dsd-dbs__capella-collab-manager METASEP

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/t4c-repo-settings/project-deletion-dialog/project-deletion-dialog.component.ts METASEP
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import {
  T4CRepoService,
  T4CRepository,
} from 'src/app/services/modelsources/t4c-repos/t4c-repo.service';

@Component({
  selector: 'app-project-deletion-dialog',
  templateUrl: './project-deletion-dialog.component.html',
  styleUrls: ['./project-deletion-dialog.component.css'],
})
export class ProjectDeletionDialogComponent implements OnInit {
  constructor(
    private projectService: T4CRepoService,
    public dialogRef: MatDialogRef<ProjectDeletionDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public project: T4CRepository
  ) {}

  ngOnInit(): void {}

  removeProject(): void {
    this.projectService
      .deleteRepositoryProject(this.project.repository_name, this.project.id)
      .subscribe(() => {
        this.dialogRef.close(true);
      });
  }
}

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/t4c-repo-settings/project-deletion-dialog/project-deletion-dialog.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ProjectDeletionDialogComponent } from './project-deletion-dialog.component';

describe('ProjectDeletionDialogComponent', () => {
  let component: ProjectDeletionDialogComponent;
  let fixture: ComponentFixture<ProjectDeletionDialogComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ProjectDeletionDialogComponent],
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(ProjectDeletionDialogComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/t4c-repo-settings/project-deletion-dialog/project-deletion-dialog.component.html METASEP
<h1 mat-dialog-title>Remove Project</h1>
<div mat-dialog-content>
  <p>
    Do you really want delete the Project {{ project.name }} with the ID
    {{ project.id }}?
  </p>
  <p>
    This will remove all related Git repository connections and will delete all
    Backup Jobs!
  </p>
  <p>The deletion cannot be undone!</p>
</div>
<div mat-dialog-actions>
  <button mat-button (click)="this.dialogRef.close(false)">No</button>
  <button mat-flat-button (click)="removeProject()">Remove the project</button>
</div>

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/t4c-repo-settings/project-deletion-dialog/project-deletion-dialog.component.css METASEP

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/git-model-settings/git-model-deletion-dialog/git-model-deletion-dialog.component.ts METASEP
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import {
  GitModel,
  GitModelService,
} from 'src/app/services/modelsources/git-model/git-model.service';

@Component({
  selector: 'app-git-model-deletion-dialog',
  templateUrl: './git-model-deletion-dialog.component.html',
  styleUrls: ['./git-model-deletion-dialog.component.css'],
})
export class GitModelDeletionDialogComponent implements OnInit {
  constructor(
    private gitModelService: GitModelService,
    public dialogRef: MatDialogRef<GitModelDeletionDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public input: GitModelDeletionDialogInput
  ) {}

  ngOnInit(): void {}

  unassignGitModel() {
    this.gitModelService
      .unassignGitRepositoriesFromRepository(
        this.input.repository,
        this.input.model.id
      )
      .subscribe(() => {
        this.dialogRef.close(true);
      });
  }
}

export interface GitModelDeletionDialogInput {
  model: GitModel;
  repository: string;
}

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/git-model-settings/git-model-deletion-dialog/git-model-deletion-dialog.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { GitModelDeletionDialogComponent } from './git-model-deletion-dialog.component';

describe('GitModelDeletionDialogComponent', () => {
  let component: GitModelDeletionDialogComponent;
  let fixture: ComponentFixture<GitModelDeletionDialogComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [GitModelDeletionDialogComponent],
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(GitModelDeletionDialogComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/git-model-settings/git-model-deletion-dialog/git-model-deletion-dialog.component.html METASEP
<h1 mat-dialog-title>Remove Git model assignment</h1>
<div mat-dialog-content>
  <p>
    Do you really want delete the Git model {{ input.model.name }} with the ID
    {{ input.model.id }}?
  </p>
  <p>
    This will remove the Git model connection. It will not affect the existing
    Git repository!
  </p>
</div>
<div mat-dialog-actions>
  <button mat-button (click)="this.dialogRef.close(false)">No</button>
  <button mat-flat-button (click)="unassignGitModel()">Unassign</button>
</div>

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/git-model-settings/git-model-deletion-dialog/git-model-deletion-dialog.component.css METASEP

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/view-logs-dialog/view-logs-dialog.component.ts METASEP
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { EASEBackupService } from 'src/app/services/backups/ease/easebackup.service';

@Component({
  selector: 'app-view-logs-dialog',
  templateUrl: './view-logs-dialog.component.html',
  styleUrls: ['./view-logs-dialog.component.css'],
})
export class ViewLogsDialogComponent implements OnInit {
  constructor(
    @Inject(MAT_DIALOG_DATA) public data: ViewLogsData,
    private easeBackupService: EASEBackupService
  ) {}

  loading = true;
  logs = '';

  ngOnInit(): void {
    this.refreshLogs();
  }

  refreshLogs(): void {
    this.easeBackupService
      .getLogs(this.data.project, this.data.backup_id, this.data.job_id)
      .subscribe(
        (res: string) => {
          this.loading = false;
          this.logs = res;
        },
        () => {
          this.loading = false;
          this.logs = "Couldn't fetch logs";
        }
      );
  }
}

export interface ViewLogsData {
  job_id: string;
  backup_id: number;
  project: string;
}

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/view-logs-dialog/view-logs-dialog.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ViewLogsDialogComponent } from './view-logs-dialog.component';

describe('ViewLogsDialogComponent', () => {
  let component: ViewLogsDialogComponent;
  let fixture: ComponentFixture<ViewLogsDialogComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ ViewLogsDialogComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(ViewLogsDialogComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/view-logs-dialog/view-logs-dialog.component.html METASEP
<div class="wrapper">
  <h1 mat-dialog-title>Logs</h1>
  <mat-spinner *ngIf="loading"></mat-spinner>
  <div [innerText]="logs"></div>
</div>
<div mat-dialog-actions class="buttons">
  <button mat-button mat-dialog-close cdkFocusInitial>Close</button>
</div>

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/view-logs-dialog/view-logs-dialog.component.css METASEP
.wrapper {
  min-width: 50vw;
  min-height: 80vh;
}

.buttons {
  display: flex;
  justify-content: right;
}

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/create-ease-backup/create-ease-backup.component.ts METASEP
import { Component, Inject, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { EASEBackupService } from 'src/app/services/backups/ease/easebackup.service';
import { GitModelService } from 'src/app/services/modelsources/git-model/git-model.service';
import { T4CRepoService } from 'src/app/services/modelsources/t4c-repos/t4c-repo.service';

@Component({
  selector: 'app-create-ease-backup',
  templateUrl: './create-ease-backup.component.html',
  styleUrls: ['./create-ease-backup.component.css'],
})
export class CreateEASEBackupComponent implements OnInit {
  constructor(
    public gitModelService: GitModelService,
    public t4cRepoService: T4CRepoService,
    private easeBackupService: EASEBackupService,
    private dialogRef: MatDialogRef<CreateEASEBackupComponent>,
    @Inject(MAT_DIALOG_DATA) public data: CreateEASEBackupData
  ) {}

  ngOnInit(): void {}

  createGitBackupForm = new FormGroup({
    gitmodel: new FormControl('', Validators.required),
    t4cmodel: new FormControl('', Validators.required),
  });

  createGitBackup() {
    if (this.createGitBackupForm.valid) {
      this.easeBackupService
        .createBackup(this.data.project, this.createGitBackupForm.value)
        .subscribe(() => {
          this.dialogRef.close(true);
        });
    }
  }
}

export interface CreateEASEBackupData {
  project: string;
}

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/create-ease-backup/create-ease-backup.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { CreateEASEBackupComponent } from './create-ease-backup.component';

describe('CreateGitBackupComponent', () => {
  let component: CreateEASEBackupComponent;
  let fixture: ComponentFixture<CreateEASEBackupComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [CreateEASEBackupComponent],
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(CreateEASEBackupComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/create-ease-backup/create-ease-backup.component.html METASEP
<h1 mat-dialog-title>Create a new EASE backup</h1>

<form [formGroup]="createGitBackupForm">
  <mat-form-field>
    <mat-label>Select source (t4c model)</mat-label>
    <mat-select formControlName="t4cmodel">
      <mat-option
        *ngFor="let t4cModel of t4cRepoService.repositories"
        [value]="t4cModel.id"
      >
        {{ t4cModel.name }}
      </mat-option>
    </mat-select>
    <mat-error>Please select a t4c model!</mat-error>
  </mat-form-field>
  <mat-icon id="arr-right">arrow_right_alt</mat-icon>
  <mat-form-field>
    <mat-label>Select target (git model)</mat-label>
    <mat-select formControlName="gitmodel">
      <mat-option
        *ngFor="let gitModel of gitModelService.models"
        [value]="gitModel.id"
      >
        {{ gitModel.name }}
      </mat-option>
    </mat-select>
    <mat-error>Please select a git model!</mat-error>
  </mat-form-field>
</form>

<div
  *ngIf="!gitModelService.models.length || !t4cRepoService.repositories.length"
></div>
<div mat-dialog-actions>
  <button mat-button [mat-dialog-close]="false">Cancel</button>
  <button mat-button (click)="createGitBackup()" cdkFocusInitial>Create</button>
</div>

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/create-ease-backup/create-ease-backup.component.css METASEP
#arr-right {
  margin-right: 10px;
}

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/t4c-repo-settings/t4c-repo-settings.component.ts METASEP
import {
  Component,
  EventEmitter,
  Input,
  OnInit,
  Output,
  ViewChild,
} from '@angular/core';
import {
  AbstractControl,
  FormControl,
  FormGroup,
  FormGroupDirective,
  ValidationErrors,
  Validators,
} from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import {
  T4CRepoService,
  T4CRepository,
} from 'src/app/services/modelsources/t4c-repos/t4c-repo.service';
import { ProjectDeletionDialogComponent } from './project-deletion-dialog/project-deletion-dialog.component';

@Component({
  selector: 'app-t4c-repo-settings',
  templateUrl: './t4c-repo-settings.component.html',
  styleUrls: ['./t4c-repo-settings.component.css'],
})
export class T4CRepoSettingsComponent implements OnInit {
  createProjectForm = new FormGroup({
    name: new FormControl('', Validators.required),
  });

  _repository: string = '';

  @ViewChild('projectsList') projectsList: any;

  @Input()
  set repository(value: string) {
    this._repository = value;
    this.refreshProjects();
  }

  get repository() {
    return this._repository;
  }

  projectNonexistenceValidator(): Validators {
    return (control: AbstractControl): ValidationErrors | null => {
      for (let project of this.projectService.repositories) {
        if (project.name == control.value) {
          return { projectExistsError: true };
        }
      }
      return null;
    };
  }

  constructor(
    public projectService: T4CRepoService,
    private dialog: MatDialog
  ) {}

  ngOnInit(): void {}

  refreshProjects(): void {
    this.projectService.getRepositoryProjects(this.repository).subscribe();
  }

  createProject(formDirective: FormGroupDirective): void {
    if (this.createProjectForm.valid) {
      this.projectService
        .createRepositoryProject(
          this.repository,
          this.createProjectForm.value.name
        )
        .subscribe(() => {
          this.refreshProjects();
          formDirective.resetForm();
          this.createProjectForm.reset();
        });
    }
  }

  removeProject(project: T4CRepository): void {
    const dialogRef = this.dialog.open(ProjectDeletionDialogComponent, {
      data: project,
    });

    dialogRef.afterClosed().subscribe((val) => {
      if (val) {
        this.refreshProjects();
      }
    });
  }

  get selectedProject(): T4CRepository {
    return this.projectsList.selectedOptions.selected[0].value;
  }
}

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/t4c-repo-settings/t4c-repo-settings.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ProjectSettingsComponent } from './project-settings.component';

describe('ProjectSettingsComponent', () => {
  let component: ProjectSettingsComponent;
  let fixture: ComponentFixture<ProjectSettingsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ ProjectSettingsComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(ProjectSettingsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/t4c-repo-settings/t4c-repo-settings.component.html METASEP
<mat-card
  ><h2>T4C Repository Settings</h2>
  Adding and deleting t4c repositories will not affect the T4C Server! <br />
  This should represent a manually updated list of the current t4c repositories.
  <br />
  This will be automated in the next version.
  <form [formGroup]="createProjectForm" #formDirective="ngForm">
    <mat-form-field>
      <mat-label>Repository name</mat-label>
      <input matInput formControlName="name" />
      <mat-error>Please enter a name!</mat-error>
    </mat-form-field>
    <button
      mat-flat-button
      color="primary"
      (click)="createProject(formDirective)"
    >
      Add T4C repository
    </button>
  </form>
  <mat-selection-list #projectsList [multiple]="false" class="user-selection">
    <mat-list-option
      *ngFor="let project of projectService.repositories"
      [value]="project"
    >
      <mat-icon mat-list-icon>laptop</mat-icon>
      <div mat-line>{{ project.name }}</div>
      <div mat-line>Project ID: {{ project.id }}</div>
    </mat-list-option>
  </mat-selection-list>

  <div *ngIf="projectsList.selectedOptions.selected.length">
    <button
      mat-flat-button
      color="primary"
      (click)="removeProject(selectedProject)"
    >
      <mat-icon>delete</mat-icon> Remove {{ selectedProject.name }} from
      {{ repository }}
    </button>
  </div>
</mat-card>

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/t4c-repo-settings/t4c-repo-settings.component.css METASEP
button {
  margin: 5px;
}

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/git-model-settings/git-model-settings.component.ts METASEP
import { Component, Input, OnInit } from '@angular/core';
import {
  AbstractControl,
  FormControl,
  FormGroup,
  FormGroupDirective,
  ValidationErrors,
  ValidatorFn,
  Validators,
} from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import {
  GitModel,
  GitModelService,
} from 'src/app/services/modelsources/git-model/git-model.service';
import { T4CRepoService } from 'src/app/services/modelsources/t4c-repos/t4c-repo.service';
import { GitModelDeletionDialogComponent } from './git-model-deletion-dialog/git-model-deletion-dialog.component';

@Component({
  selector: 'app-git-model-settings',
  templateUrl: './git-model-settings.component.html',
  styleUrls: ['./git-model-settings.component.css'],
})
export class GitModelSettingsComponent implements OnInit {
  createGitModel = new FormGroup({
    name: new FormControl('', Validators.required),
    model: new FormGroup({
      path: new FormControl('', [Validators.required, this.gitURLValidator()]),
      entrypoint: new FormControl('', [
        Validators.required,
        this.airdFileValidator(),
      ]),
      revision: new FormControl('', Validators.required),
    }),
    credentials: new FormGroup({
      username: new FormControl(''),
      password: new FormControl(''),
    }),
  });

  get model(): FormGroup {
    return this.createGitModel.get('model') as FormGroup;
  }

  get gitPath(): FormControl {
    return this.model.get('path') as FormControl;
  }

  get entrypoint(): FormControl {
    return this.model.get('entrypoint') as FormControl;
  }

  @Input()
  repository = '';

  constructor(
    public gitModelService: GitModelService,
    private dialog: MatDialog
  ) {}

  ngOnInit(): void {
    this.refreshGitModels();
  }

  refreshGitModels() {
    this.gitModelService
      .getGitRepositoriesForRepository(this.repository)
      .subscribe();
  }

  gitURLValidator(): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      const regex = /^https:\/\/\S*\.git$/;
      if (regex.test(control.value) || !control.value) {
        return null;
      }
      return { gitURLError: true };
    };
  }

  airdFileValidator(): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      const regex = /\.aird$/;
      if (regex.test(control.value) || !control.value) {
        return null;
      }
      return { airdFileIncorrect: true };
    };
  }

  assignGitModel(formDirective: FormGroupDirective) {
    if (this.createGitModel.valid) {
      this.gitModelService
        .assignGitRepositoryToRepository(
          this.repository,
          this.createGitModel.value
        )
        .subscribe(() => {
          formDirective.resetForm();
          this.createGitModel.reset();
          this.refreshGitModels();
        });
    }
  }

  unassignGitModel(model: GitModel) {
    const dialogRef = this.dialog.open(GitModelDeletionDialogComponent, {
      data: { model: model, repository: this.repository },
    });

    dialogRef.afterClosed().subscribe((val) => {
      if (val) {
        this.refreshGitModels();
      }
    });
  }

  makeItPrimary(id: number) {
    this.gitModelService
      .makeGitRepositoryPrimary(this.repository, id)
      .subscribe(() => {
        this.refreshGitModels();
      });
  }
}

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/git-model-settings/git-model-settings.component.html METASEP
<mat-card>
  <h2 class="content">Assign existing git repository</h2>
  <form [formGroup]="createGitModel" #createGitModelFormDirective="ngForm">
    <mat-form-field class="content">
      <mat-label>Name</mat-label>
      <input matInput formControlName="name" />
      <mat-error>Please enter a name!</mat-error>
    </mat-form-field>
    <br />
    <form formGroupName="model" class="content">
      <mat-form-field id="git-path">
        <mat-label>Git HTTPS-URL</mat-label>
        <input
          matInput
          formControlName="path"
          placeholder="https://github.com/repository.git"
        />
        <mat-error *ngIf="gitPath.getError('required')"
          >Please enter a Git HTTPS URL!</mat-error
        >
        <mat-error *ngIf="gitPath.getError('gitURLError')"
          >The provided Git URL does not match a valid Git HTTPS URL!</mat-error
        >
      </mat-form-field>
      <br />
      <mat-form-field>
        <mat-label>Entrypoint</mat-label>
        <input
          matInput
          formControlName="entrypoint"
          placeholder="path/to/project.aird"
        />
        <mat-error *ngIf="entrypoint.getError('required')"
          >Please enter a entrypoint!</mat-error
        >
        <mat-error *ngIf="entrypoint.getError('airdFileIncorrect')"
          >Your Entrypoint has to end with .aird!</mat-error
        >
      </mat-form-field>
      <mat-form-field>
        <mat-label>Revision</mat-label>
        <input matInput formControlName="revision" placeholder="HEAD" />
        <mat-error>Please enter a revision!</mat-error></mat-form-field
      >
    </form>
    <div id="credentials">
      Credentials are used for pushes to the repository. <br />
      In private repositories, they are also needed to pull the model.
      <form formGroupName="credentials">
        <mat-form-field>
          <mat-label>Username</mat-label>
          <input matInput formControlName="username" placeholder="techuser" />
        </mat-form-field>
        <mat-form-field>
          <mat-label>Password</mat-label>
          <input
            matInput
            formControlName="password"
            placeholder="**********"
            type="password"
          />
        </mat-form-field>
      </form>
    </div>
    <br />
    <button
      class="content"
      mat-flat-button
      color="primary"
      (click)="assignGitModel(createGitModelFormDirective)"
    >
      Assign
    </button>
  </form>
</mat-card>
<mat-card id="handle-models">
  <h2>Handle Git models</h2>
  <div *ngIf="gitModelService.models.length"></div>
  <mat-accordion>
    <mat-expansion-panel *ngFor="let model of gitModelService.models">
      <mat-expansion-panel-header class="expansion-panel">
        <mat-panel-title> {{ model.name }} </mat-panel-title>
        <mat-panel-description>
          <div *ngIf="model.primary">Primary</div>
        </mat-panel-description>
      </mat-expansion-panel-header>
      <mat-form-field id="git-path-view" appearance="fill">
        <mat-label>Git-URL</mat-label>
        <input matInput disabled [value]="model.model.path" />
      </mat-form-field>
      <br />
      <mat-form-field appearance="fill" class="show-git-model">
        <mat-label>Entrypoint</mat-label>
        <input matInput disabled [value]="model.model.entrypoint" />
      </mat-form-field>
      <mat-form-field appearance="fill" class="show-git-model">
        <mat-label>Revision</mat-label>
        <input matInput disabled [value]="model.model.revision" />
      </mat-form-field>
      <mat-form-field appearance="fill" class="show-git-model">
        <mat-label *ngIf="model.username">Username</mat-label>
        <mat-label *ngIf="!model.username"
          ><mat-icon>no_encryption</mat-icon> No credentials</mat-label
        >
        <input matInput disabled [value]="model.username" />
      </mat-form-field>
      <br />
      <button mat-flat-button color="primary" (click)="unassignGitModel(model)">
        Unassign
      </button>
      <button
        mat-flat-button
        color="primary"
        (click)="makeItPrimary(model.id)"
        *ngIf="!model.primary"
      >
        Make it primary
      </button>
    </mat-expansion-panel>
  </mat-accordion>
  <div *ngIf="!gitModelService.models.length">
    There are no linked git models.
  </div>
</mat-card>

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/git-model-settings/git-model-settings.component.css METASEP
mat-card {
  min-width: 500px;
  margin: 5px;
  height: fit-content;
}

.content {
  margin-left: 5px;
}

mat-form-field {
  margin-right: 10px;
}

h1 {
  margin: 10px;
}

.flexbox {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
}

button {
  margin: 5px 10px 0 0;
}

#git-path {
  width: 370px;
}

#git-path-view {
  width: 450px;
}

input:disabled {
  color: black;
}

.show-git-model {
  width: 143px;
}

#project-id {
  width: 70px;
}

#credentials {
  padding: 5px;
  border-radius: 5px;
  background-color: lightgreen;
  width: fit-content;
}

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/jenkins-backup-settings/jenkins-backup-settings.component.ts METASEP
import { HttpErrorResponse } from '@angular/common/http';
import { Component, Input, OnInit } from '@angular/core';
import {
  GitModel,
  GitModelService,
} from 'src/app/services/modelsources/git-model/git-model.service';
import {
  JenkinsPipeline,
  JenkinsService,
} from 'src/app/services/backups/jenkins/jenkins.service';

@Component({
  selector: 'app-jenkins-backup-settings',
  templateUrl: './jenkins-backup-settings.component.html',
  styleUrls: ['./jenkins-backup-settings.component.css'],
})
export class JenkinsBackupSettingsComponent implements OnInit {
  constructor(
    private jenkinsService: JenkinsService,
    private gitModelService: GitModelService
  ) {}

  ngOnInit(): void {}

  /* TODO: Needs rework

  loading = true;
  pipeline: JenkinsPipeline | undefined = undefined;

  _repository = '';

  @Input()
  set repository(value: string) {
    this._repository = value;
    this.refreshPipeline();
  }

  get repository() {
    return this._repository;
  }

  refreshPipeline() {
    this.loading = true;
    if (this.repository) {
      this.jenkinsService
        .getJenkinsPipelineForModel(this.repository, this.model.id)
        .subscribe(
          (res) => {
            this.pipeline = res;
            this.loading = false;
          },
          (err: HttpErrorResponse) => {
            this.loading = false;
            if (err.status === 404) {
              this.pipeline = undefined;
            }
          }
        );
    }
  }

  createPipeline() {
    if (this.model && this.repository) {
      this.loading = true;
      this.jenkinsService
        .createJenkinsPipelineForModel(this.repository, this.model.id)
        .subscribe(
          () => {
            this.refreshPipeline();
            this.loading = false;
          },
          () => {
            this.loading = false;
          }
        );
    }
  }

  runJenkinsJob() {
    if (this.model && this.pipeline && this.repository) {
      this.loading = true;
      this.jenkinsService
        .createJenkinsJobForModel(
          this.repository,
          this.model.id,
          this.pipeline.name
        )
        .subscribe(
          () => {
            this.refreshPipeline();
            this.loading = false;
          },
          () => {
            this.loading = false;
          }
        );
    }
  }

  removeJenkinsPipeline() {
    if (this.model && this.pipeline && this.repository) {
      this.loading = true;
      this.jenkinsService
        .removeJenkinsPipeline(
          this.repository,
          this.model.id,
          this.pipeline.name
        )
        .subscribe(
          () => {
            this.refreshPipeline();
            this.loading = false;
          },
          () => {
            this.loading = false;
          }
        );
    }
  } */
}

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/jenkins-backup-settings/jenkins-backup-settings.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { JenkinsBackupSettingsComponent } from './jenkins-backup-settings.component';

describe('JenkinsBackupSettingsComponent', () => {
  let component: JenkinsBackupSettingsComponent;
  let fixture: ComponentFixture<JenkinsBackupSettingsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [JenkinsBackupSettingsComponent],
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(JenkinsBackupSettingsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/jenkins-backup-settings/jenkins-backup-settings.component.html METASEP
This option is currently not available.
<!-- 
    <div class="jenkins">
  <h3>Available Backup Jobs</h3>
  <mat-spinner *ngIf="loading" class="spinner" [diameter]="25"></mat-spinner>
  <button
    id="refresh-button"
    (click)="refreshPipeline()"
    mat-icon-button
    *ngIf="!loading && pipeline"
  >
    <mat-icon>refresh</mat-icon>
  </button>
  <div>
    <div *ngIf="!loading">No backup jobs were found. <br /></div>
    <button mat-flat-button color="primary" (click)="createPipeline()">
      Create Backup Job
    </button>
  </div>
  <div *ngIf="pipeline">
    <br />
    <div class="">
      <div class="flexbox">
        <mat-form-field appearance="fill">
          <mat-label>Name of the Backup Job</mat-label>
          <input matInput disabled [value]="pipeline.name" /> </mat-form-field
        ><br />
        <div
          class="state flexbox"
          [ngClass]="pipeline.latest_run.result.toLowerCase()"
          id="state-field"
          *ngIf="pipeline.latest_run"
        >
          <div class="inner-state">
            <div class="title">
              Last Run: {{ pipeline.latest_run.start_time }}
            </div>
            <span class="text">{{ pipeline.latest_run.result }}</span
            ><br />
          </div>
          <mat-icon
            *ngIf="pipeline.latest_run.result == 'FAILURE'"
            id="error-icon"
            >error</mat-icon
          >
        </div>
      </div>
    </div>

    <button mat-flat-button (click)="runJenkinsJob()" color="primary">
      Run job
    </button>
    <button mat-flat-button (click)="removeJenkinsPipeline()" color="primary">
      Remove Backup Pipeline
    </button>
    <a
      mat-flat-button
      color="primary"
      target="_blank"
      [href]="pipeline.latest_run.logs_url"
      *ngIf="pipeline.latest_run"
    >
      View logs <mat-icon>launch</mat-icon>
    </a>
  </div>
</div>
-->

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/jenkins-backup-settings/jenkins-backup-settings.component.css METASEP
button {
  margin: 5px 10px 0 0;
}

input:disabled {
  color: black;
}

.state {
  padding: 0px;
  width: 201px;
  border-radius: 3px 3px 0 0;
}

.success {
  background-color: green;
}

.failure {
  background-color: darkred;
}

.unknown {
  background-color: darkblue;
}

.inner-state {
  padding: 10.5px 10.5px 0 10.5px;
}

.inner-state > .text {
  font-size: 14px;
  padding-top: 3.5px;
  padding-bottom: 10.5px;
  line-height: 15px;
  display: inline-block;
  color: white;
}

.inner-state > .title {
  color: lightgrey;
  font-size: 11px;
  line-height: 11.813px;
}

#state-field {
  justify-content: space-between;
  align-items: center;
}

#error-icon {
  margin-right: 10px;
  color: white;
}

.spinner {
  float: right;
}

#refresh-button {
  float: right;
  margin: -8px -8px;
}

h3 {
  display: inline;
}

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/ease-backup-settings.component.ts METASEP
import { Component, Input, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import {
  EASEBackup,
  EASEBackupJob,
  EASEBackupService,
} from 'src/app/services/backups/ease/easebackup.service';
import { BeautifyService } from 'src/app/services/beatify/beautify.service';
import { CreateEASEBackupComponent } from './create-ease-backup/create-ease-backup.component';
import { ViewLogsDialogComponent } from './view-logs-dialog/view-logs-dialog.component';

@Component({
  selector: 'app-ease-backup-settings',
  templateUrl: './ease-backup-settings.component.html',
  styleUrls: ['./ease-backup-settings.component.css'],
})
export class GitBackupSettingsComponent implements OnInit {
  constructor(
    public beautifyService: BeautifyService,
    public dialog: MatDialog,
    private easeBackupService: EASEBackupService
  ) {}

  @Input()
  project: string = '';

  loading = false;

  ngOnInit(): void {
    this.refreshBackups();
  }

  backups: Array<EASEBackup> = [];

  refreshBackups(): void {
    this.loading = true;
    this.easeBackupService
      .getBackups(this.project)
      .subscribe((res: Array<EASEBackup>) => {
        this.backups = res;
        this.loading = false;
      });
  }

  createNewBackup(): void {
    const dialogRef = this.dialog.open(CreateEASEBackupComponent, {
      data: { project: this.project },
    });

    dialogRef.afterClosed().subscribe((success) => {
      if (success) {
        this.refreshBackups();
      }
    });
  }

  runJob(backup: EASEBackup): void {
    this.easeBackupService.triggerRun(this.project, backup.id).subscribe(() => {
      this.refreshBackups();
    });
  }

  removeBackup(backup: EASEBackup): void {
    this.easeBackupService
      .removeBackup(this.project, backup.id)
      .subscribe(() => {
        this.refreshBackups();
      });
  }

  viewLogs(backup: EASEBackup): void {
    this.dialog.open(ViewLogsDialogComponent, {
      data: {
        job_id: backup.lastrun.id,
        backup_id: backup.id,
        project: this.project,
      },
    });
  }
}

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/ease-backup-settings.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { GitBackupSettingsComponent } from './ease-backup-settings.component';

describe('GitBackupSettingsComponent', () => {
  let component: GitBackupSettingsComponent;
  let fixture: ComponentFixture<GitBackupSettingsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [GitBackupSettingsComponent],
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(GitBackupSettingsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/ease-backup-settings.component.html METASEP
<div>
  <div id="description">
    One-way synchronization: T4C <mat-icon>arrow_right_alt</mat-icon> Git
  </div>
  <br />
  <div id="loading">
    <div>
      The jobs are executed every night. <br />A job can be triggered manually
      at any time.
    </div>
    <div>
      <mat-spinner
        *ngIf="loading"
        class="spinner"
        [diameter]="25"
      ></mat-spinner>
      <button
        id="refresh-button"
        (click)="refreshBackups()"
        mat-icon-button
        *ngIf="!loading"
      >
        <mat-icon>refresh</mat-icon>
      </button>
    </div>
  </div>
  <mat-card class="item" *ngFor="let item of backups">
    <div class="header">
      Backup from T4C model {{ item.t4cmodel }} to Git model {{ item.gitmodel }}
    </div>
    <div
      class="state"
      [ngClass]="beautifyService.beatifyState(item.lastrun?.state).css"
    >
      {{ beautifyService.beatifyState(item.lastrun?.state).text }}
      <div class="lastrun" *ngIf="item.lastrun.date">
        {{ beautifyService.beatifyDate(item.lastrun.date) }}
      </div>
      <div class="lastrun" *ngIf="!item.lastrun.date">Not started yet</div>
    </div>
    <div class="flexbox">
      <div class="state flexbox" id="state-field" *ngIf="item.lastrun">
        <div class="inner-state"><br /></div>
      </div>

      <button mat-flat-button (click)="runJob(item)" color="primary">
        Run job
      </button>
      <button mat-flat-button (click)="removeBackup(item)" color="primary">
        Remove Backup
      </button>
      <button
        mat-flat-button
        (click)="viewLogs(item)"
        color="primary"
        *ngIf="item.lastrun.id"
      >
        View logs
      </button>
    </div>
  </mat-card>
  <mat-card class="item" id="add-button" (click)="createNewBackup()">
    Create a new backup <mat-icon>add</mat-icon>
  </mat-card>
</div>

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/ease-backup-settings.component.css METASEP
#description {
  border-radius: 10px;
  background-color: var(--primary-color);
  color: white;
  text-align: center;
  font-size: 1.1em;
  padding: 5px;
}

.item {
  border-radius: 5px;
  margin: 10px 0;
  padding: 10px 0;
}

.error {
  background-color: var(--error-color);
  color: white;
}

.warning {
  background-color: var(--warning-color);
  color: white;
}

.success {
  background-color: var(--success-color);
  color: white;
}

.state {
  text-align: center;
  font-size: 1.25em;
  padding: 5px;
}

.lastrun {
  font-size: 0.75em;
}

.header {
  padding: 5px;
  text-align: center;
}

#add-button {
  display: flex;
  justify-content: space-between;
  padding: 10px;
}

#add-button:hover {
  cursor: pointer;
}

button {
  margin: 5px 10px 0 0;
}

.spinner {
  float: right;
}

#refresh-button {
  float: right;
  margin: -8px -8px;
}

#loading {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

frontend/src/app/settings/repository-manager-settings/repository-settings/repository-user-settings/repository-user-settings.component.ts METASEP
import { Component, Input, OnInit, ViewChild } from '@angular/core';
import {
  AbstractControl,
  FormControl,
  FormGroup,
  FormGroupDirective,
  ValidationErrors,
  ValidatorFn,
  Validators,
} from '@angular/forms';
import { RepositoryUser } from 'src/app/schemes';
import { RepositoryUserService } from 'src/app/services/repository-user/repository-user.service';
import { UserService } from 'src/app/services/user/user.service';

@Component({
  selector: 'app-repository-user-settings',
  templateUrl: './repository-user-settings.component.html',
  styleUrls: ['./repository-user-settings.component.css'],
})
export class RepositoryUserSettingsComponent implements OnInit {
  _repository: string = '';

  @Input()
  set repository(value: string) {
    this._repository = value;
    this.refreshRepoUsers();
  }

  get repository() {
    return this._repository;
  }

  repositoryUsers: Array<RepositoryUser> = [];
  search = '';

  @ViewChild('users') users: any;

  addUserToRepoForm = new FormGroup(
    {
      username: new FormControl('', [
        Validators.required,
        this.userAlreadyInRepositoryValidator(),
      ]),
      role: new FormControl('', Validators.required),
      permission: new FormControl(''),
    },
    this.permissionRequiredValidator()
  );
  constructor(
    public repoUserService: RepositoryUserService,
    public userService: UserService
  ) {}

  ngOnInit(): void {}

  get username(): FormControl {
    return this.addUserToRepoForm.get('username') as FormControl;
  }

  get selectedUser(): RepositoryUser {
    return this.users.selectedOptions.selected[0].value;
  }

  permissionRequiredValidator(): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      if (
        control.get('permission')?.value in this.repoUserService.PERMISSIONS ||
        control.get('role')?.value == 'manager'
      ) {
        control.get('permission')?.setErrors(null);
        return null;
      }
      control.get('permission')?.setErrors({ permissionInvalid: true });
      return {};
    };
  }

  userAlreadyInRepositoryValidator(): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      for (let repoUser of this.repositoryUsers) {
        if (repoUser.username == control.value) {
          return { userAlreadyInRepositoryError: true };
        }
      }
      return null;
    };
  }

  refreshRepoUsers(): void {
    this.repoUserService.getRepoUsers(this.repository).subscribe((res) => {
      this.repositoryUsers = res;
    });
  }

  addUser(formDirective: FormGroupDirective): void {
    if (this.addUserToRepoForm.valid) {
      const formValue = this.addUserToRepoForm.value;

      let permission = formValue.permission;
      if (formValue.role == 'manager') {
        permission = 'write';
      }
      this.repoUserService
        .addUserToRepo(
          this.repository,
          formValue.username,
          formValue.role,
          permission
        )
        .subscribe(() => {
          formDirective.resetForm();
          this.addUserToRepoForm.reset();
          this.refreshRepoUsers();
        });
    }
  }

  removeUserFromRepo(username: string): void {
    this.repoUserService
      .deleteUserFromRepo(this.repository, username)
      .subscribe(() => {
        this.refreshRepoUsers();
      });
  }

  upgradeUserToRepositoryManager(username: string): void {
    this.repoUserService
      .changeRoleOfRepoUser(this.repository, username, 'manager')
      .subscribe(() => {
        this.refreshRepoUsers();
      });
  }

  downgradeUserToUserRole(username: string): void {
    this.repoUserService
      .changeRoleOfRepoUser(this.repository, username, 'user')
      .subscribe(() => {
        this.refreshRepoUsers();
      });
  }

  setUserPermission(username: string, permission: 'read' | 'write'): void {
    this.repoUserService
      .changePermissionOfRepoUser(this.repository, username, permission)
      .subscribe(() => {
        this.refreshRepoUsers();
      });
  }

  getRepositoryUsersByRole(role: 'manager' | 'user'): Array<RepositoryUser> {
    return this.repositoryUsers.filter(
      (u) => u.role == role && u.username.includes(this.search.toLowerCase())
    );
  }
}

frontend/src/app/settings/repository-manager-settings/repository-settings/repository-user-settings/repository-user-settings.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { RepositoryUserSettingsComponent } from './repository-user-settings.component';

describe('RepositoryUserSettingsComponent', () => {
  let component: RepositoryUserSettingsComponent;
  let fixture: ComponentFixture<RepositoryUserSettingsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ RepositoryUserSettingsComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(RepositoryUserSettingsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/repository-manager-settings/repository-settings/repository-user-settings/repository-user-settings.component.html METASEP
<mat-card id="manage-users">
  <h2>Manage users</h2>
  <mat-form-field id="search" appearance="outline">
    <mat-label>Search</mat-label>
    <input
      [(ngModel)]="search"
      autocomplete="off"
      matInput
      placeholder="Username"
    />
    <mat-icon matSuffix>search</mat-icon> </mat-form-field
  >.
  <ngx-simplebar class="user-selection">
    <mat-selection-list #users [multiple]="false">
      <div mat-subheader>Managers</div>
      <mat-list-option
        *ngFor="let user of getRepositoryUsersByRole('manager')"
        [value]="user"
      >
        <mat-icon mat-list-icon>account_circle</mat-icon>
        <div mat-line>{{ user.username }}</div>
        <div mat-line>
          {{ repoUserService.ADVANCED_ROLES[user.role] }},
          {{ repoUserService.PERMISSIONS[user.permission] }}
        </div>
      </mat-list-option>
      <div mat-subheader>Users</div>
      <mat-list-option
        *ngFor="let user of getRepositoryUsersByRole('user')"
        [value]="user"
      >
        <mat-icon mat-list-icon>account_circle</mat-icon>
        <div mat-line>{{ user.username }}</div>
        <div mat-line>
          {{ repoUserService.ADVANCED_ROLES[user.role] }},
          {{ repoUserService.PERMISSIONS[user.permission] }}
        </div>
      </mat-list-option>
    </mat-selection-list>
  </ngx-simplebar>

  <div
    *ngIf="
      users.selectedOptions.selected.length &&
      userService.getUsernameFromLocalStorage() != selectedUser.username
    "
  >
    <button
      mat-flat-button
      color="primary"
      *ngIf="['user', 'manager'].includes(selectedUser.role)"
      (click)="removeUserFromRepo(selectedUser.username)"
    >
      <mat-icon>delete</mat-icon> Remove {{ selectedUser.username }} from
      {{ repository }}
    </button>
    <button
      mat-flat-button
      color="primary"
      *ngIf="'user' == selectedUser.role"
      (click)="upgradeUserToRepositoryManager(selectedUser.username)"
    >
      <mat-icon>arrow_upward</mat-icon>
      Upgrade
      {{ selectedUser.username }} to project manager
    </button>
    <button
      mat-flat-button
      color="primary"
      *ngIf="'manager' == selectedUser.role"
      (click)="downgradeUserToUserRole(selectedUser.username)"
    >
      <mat-icon>arrow_downward</mat-icon>
      Downgrade
      {{ selectedUser.username }} to User
    </button>
    <div *ngIf="'manager' != selectedUser.role">
      <button
        mat-flat-button
        color="primary"
        *ngIf="'read' == selectedUser.permission"
        (click)="setUserPermission(selectedUser.username, 'write')"
      >
        <mat-icon>folder_shared</mat-icon>
        Set permission of User
        {{ selectedUser.username }} to Read/Write
      </button>
      <button
        mat-flat-button
        color="primary"
        *ngIf="'write' == selectedUser.permission"
        (click)="setUserPermission(selectedUser.username, 'read')"
      >
        <mat-icon>folder_open</mat-icon>
        Set permission of User
        {{ selectedUser.username }} to Read only
      </button>
    </div>
  </div>
</mat-card>
<mat-card>
  <h2>Add user</h2>
  <form [formGroup]="addUserToRepoForm" #addUserToRepoFormDirective="ngForm">
    <mat-form-field>
      <mat-label>Username</mat-label>
      <input matInput formControlName="username" />
      <mat-error *ngIf="username.getError('required')"
        >Please enter a username!</mat-error
      >
      <mat-error *ngIf="username.getError('lowerCaseError')"
        >Usernames can only contain lowercase letters!
      </mat-error>
      <mat-error *ngIf="username.getError('userAlreadyInRepositoryError')"
        >The user is already a member of this repository!
      </mat-error>
    </mat-form-field>
    <br />
    <mat-form-field>
      <mat-label>Role</mat-label>
      <mat-select formControlName="role">
        <mat-option
          *ngFor="let role of repoUserService.ROLES | keyvalue"
          [value]="role.key"
          >{{ role.value }}</mat-option
        >
      </mat-select>
      <mat-error>You have to select a role!</mat-error> </mat-form-field
    ><br />
    <mat-form-field *ngIf="addUserToRepoForm.value.role != 'manager'">
      <mat-label>Permission</mat-label>
      <mat-select formControlName="permission">
        <mat-option
          *ngFor="let permission of repoUserService.PERMISSIONS | keyvalue"
          [value]="permission.key"
          >{{ permission.value }}</mat-option
        >
      </mat-select>
      <mat-error>You have to select a permission!</mat-error>
    </mat-form-field>
    <button
      (click)="addUser(addUserToRepoFormDirective)"
      mat-flat-button
      color="primary"
    >
      Add user <mat-icon>keyboard_arrow_right</mat-icon>
    </button>
  </form>
</mat-card>

frontend/src/app/settings/repository-manager-settings/repository-settings/repository-user-settings/repository-user-settings.component.css METASEP
#manage-users {
  min-width: 400px;
}

.user-selection {
  height: 40vh;
}

button {
  display: block;
  margin: 5px;
}

#search {
  padding-bottom: 0px;
  width: 400px;
}

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/model-source.component.ts METASEP
import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'app-model-source',
  templateUrl: './model-source.component.html',
  styleUrls: ['./model-source.component.css'],
})
export class ModelSourceComponent implements OnInit {
  constructor() {}

  @Input()
  repository = '';

  ngOnInit(): void {}
}

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/model-source.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ModelSourceComponent } from './model-source.component';

describe('ModelSourceComponent', () => {
  let component: ModelSourceComponent;
  let fixture: ComponentFixture<ModelSourceComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ ModelSourceComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(ModelSourceComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/model-source.component.html METASEP
<mat-card
  ><h2>Model sources</h2>
  <mat-tab-group animationDuration="0" mat-align-tabs="center">
    <mat-tab label="Git"
      ><div class="content">
        <app-git-model-settings
          [repository]="repository"
        ></app-git-model-settings>
      </div>
    </mat-tab>
    <mat-tab label="T4C">
      <div class="content">
        <app-t4c-repo-settings
          [repository]="repository"
        ></app-t4c-repo-settings>
      </div>
    </mat-tab> </mat-tab-group
></mat-card>

frontend/src/app/settings/repository-manager-settings/repository-settings/model-source/model-source.component.css METASEP
mat-card {
  width: 550px;
}

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/backup-settings.component.ts METASEP
import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'app-backup-settings',
  templateUrl: './backup-settings.component.html',
  styleUrls: ['./backup-settings.component.css'],
})
export class BackupSettingsComponent implements OnInit {
  constructor() {}

  ngOnInit(): void {}

  @Input()
  project: string = '';
}

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/backup-settings.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { BackupSettingsComponent } from './backup-settings.component';

describe('BackupSettingsComponent', () => {
  let component: BackupSettingsComponent;
  let fixture: ComponentFixture<BackupSettingsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ BackupSettingsComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(BackupSettingsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/backup-settings.component.html METASEP
<mat-card
  ><h2>Backups</h2>
  <mat-tab-group animationDuration="0" mat-align-tabs="center">
    <mat-tab label="EASE"
      ><div class="content">
        <app-ease-backup-settings
          [project]="project"
        ></app-ease-backup-settings>
      </div>
    </mat-tab>
    <mat-tab label="Jenkins">
      <div class="content">
        <app-jenkins-backup-settings></app-jenkins-backup-settings>
      </div>
    </mat-tab> </mat-tab-group
></mat-card>

frontend/src/app/settings/repository-manager-settings/repository-settings/backup-settings/backup-settings.component.css METASEP
.content {
  margin: 10px;
}

frontend/src/app/settings/repository-manager-settings/repository-settings/repository-settings.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-repository-settings',
  templateUrl: './repository-settings.component.html',
  styleUrls: ['./repository-settings.component.css'],
})
export class RepositorySettingsComponent implements OnInit {
  repository: string = '';

  constructor(private route: ActivatedRoute) {}

  ngOnInit(): void {
    this.route.params.subscribe((params) => {
      this.repository = params['repository'];
    });
  }
}

frontend/src/app/settings/repository-manager-settings/repository-settings/repository-settings.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { RepositorySettingsComponent } from './repository-settings.component';

describe('RepositorySettingsComponent', () => {
  let component: RepositorySettingsComponent;
  let fixture: ComponentFixture<RepositorySettingsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ RepositorySettingsComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(RepositorySettingsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/repository-manager-settings/repository-settings/repository-settings.component.html METASEP
<h1 id="title">{{ repository }} Project Options</h1>
<div class="flexbox">
  <app-repository-user-settings [repository]="repository">
  </app-repository-user-settings>
  <app-backup-settings [project]="repository"></app-backup-settings>
  <app-model-source [repository]="repository"></app-model-source>
</div>

frontend/src/app/settings/repository-manager-settings/repository-settings/repository-settings.component.css METASEP
#title {
  margin-left: 10px;
}

frontend/src/app/settings/admin-settings/repository-sync-settings/repository-sync-settings.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { RepositoryService } from 'src/app/services/repository/repository.service';
import { T4CSyncService } from 'src/app/services/t4c-sync/t4-csync.service';

@Component({
  selector: 'app-repository-sync-settings',
  templateUrl: './repository-sync-settings.component.html',
  styleUrls: ['./repository-sync-settings.component.css'],
})
export class RepositorySyncSettingsComponent implements OnInit {
  synchronizeButtonState = 'primary';

  constructor(
    private t4cSyncService: T4CSyncService,
    private repositoryService: RepositoryService
  ) {}

  ngOnInit(): void {}

  synchronizeRepositories() {
    this.t4cSyncService.syncRepositories().subscribe(() => {
      this.synchronizeButtonState = 'success';
      this.repositoryService.refreshRepositories();
      setTimeout(() => {
        this.synchronizeButtonState = 'primary';
      }, 3000);
    });
  }
}

frontend/src/app/settings/admin-settings/repository-sync-settings/repository-sync-settings.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { RepositorySyncSettingsComponent } from './repository-sync-settings.component';

describe('RepositorySyncSettingsComponent', () => {
  let component: RepositorySyncSettingsComponent;
  let fixture: ComponentFixture<RepositorySyncSettingsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ RepositorySyncSettingsComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(RepositorySyncSettingsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/admin-settings/repository-sync-settings/repository-sync-settings.component.html METASEP
<mat-card
  ><h2>Synchronize repositories from T4C Server</h2>
  Click the button to trigger a One-Way Synchronization of T4C repositories to
  this application. <br />
  Existing repositories in this application will not be modified or deleted.
  <br />
  <button
    mat-flat-button
    (click)="synchronizeRepositories()"
    [ngClass]="synchronizeButtonState"
  >
    <div *ngIf="synchronizeButtonState == 'primary'">Start Synchronization</div>
    <div *ngIf="synchronizeButtonState == 'success'">
      Synchronization successful
    </div>
  </button>
</mat-card>

frontend/src/app/settings/admin-settings/repository-sync-settings/repository-sync-settings.component.css METASEP

frontend/src/app/settings/admin-settings/create-repository/create-repository.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { RepositoryService } from 'src/app/services/repository/repository.service';

@Component({
  selector: 'app-create-repository',
  templateUrl: './create-repository.component.html',
  styleUrls: ['./create-repository.component.css'],
})
export class CreateRepositoryComponent implements OnInit {
  createRepositoryForm = new FormGroup({
    name: new FormControl('', Validators.required),
  });

  get name(): FormControl {
    return this.createRepositoryForm.get('name') as FormControl;
  }

  constructor(
    private repositoryService: RepositoryService,
    private router: Router
  ) {}

  ngOnInit(): void {}

  createRepository(): void {
    if (this.createRepositoryForm.valid) {
      this.repositoryService.createRepository(this.name.value).subscribe(() => {
        this.repositoryService.refreshRepositories();
        this.router.navigateByUrl('/settings');
      });
    }
  }
}

frontend/src/app/settings/admin-settings/create-repository/create-repository.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { CreateRepositoryComponent } from './create-repository.component';

describe('CreateRepositoryComponent', () => {
  let component: CreateRepositoryComponent;
  let fixture: ComponentFixture<CreateRepositoryComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ CreateRepositoryComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(CreateRepositoryComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/admin-settings/create-repository/create-repository.component.html METASEP
<h1>Create Project</h1>
This will create a project and a T4C repository.
<form [formGroup]="createRepositoryForm">
  <mat-form-field appearance="fill">
    <mat-label>name</mat-label>
    <input matInput formControlName="name" />
  </mat-form-field>
  <br />
  <button mat-flat-button color="primary" (click)="createRepository()">
    Create
  </button>
</form>

frontend/src/app/settings/admin-settings/create-repository/create-repository.component.css METASEP

frontend/src/app/settings/admin-settings/alert-settings/alert-settings.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import {
  AbstractControl,
  FormControl,
  FormGroup,
  ValidationErrors,
  ValidatorFn,
  Validators,
} from '@angular/forms';
import { NoticeService } from 'src/app/services/notice/notice.service';

@Component({
  selector: 'app-alert-settings',
  templateUrl: './alert-settings.component.html',
  styleUrls: ['./alert-settings.component.css'],
})
export class AlertSettingsComponent implements OnInit {
  createAlertForm = new FormGroup(
    {
      title: new FormControl(''),
      message: new FormControl(''),
      scope: new FormControl('', Validators.required),
      level: new FormControl('', Validators.required),
    },
    this.titleOrDescriptionRequired()
  );

  get message(): FormControl {
    return this.createAlertForm.get('message') as FormControl;
  }

  constructor(public noticeService: NoticeService) {}

  ngOnInit(): void {}

  titleOrDescriptionRequired(): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      if (control.get('title')?.value || control.get('message')?.value) {
        control.get('message')?.setErrors(null);
        return null;
      }
      control.get('message')?.setErrors({ titleOrDescriptionAvailable: true });
      return { titleOrDescriptionAvailable: true };
    };
  }

  createNotice(): void {
    if (this.createAlertForm.valid) {
      this.noticeService
        .createNotice(this.createAlertForm.value)
        .subscribe(() => {
          this.noticeService.refreshNotices();
        });
    }
  }

  deleteNotice(id: number): void {
    this.noticeService.deleteNotice(id).subscribe(() => {
      this.noticeService.refreshNotices();
    });
  }
}

frontend/src/app/settings/admin-settings/alert-settings/alert-settings.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { AlertSettingsComponent } from './alert-settings.component';

describe('AlertSettingsComponent', () => {
  let component: AlertSettingsComponent;
  let fixture: ComponentFixture<AlertSettingsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ AlertSettingsComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(AlertSettingsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/admin-settings/alert-settings/alert-settings.component.html METASEP
<mat-card>
  <h2>Create new alert</h2>
  <form [formGroup]="createAlertForm">
    <mat-form-field appearance="fill">
      <mat-label>Title</mat-label>
      <input matInput formControlName="title" />
    </mat-form-field>
    <mat-form-field appearance="fill">
      <mat-label>Level</mat-label>
      <mat-select formControlName="level">
        <mat-option
          *ngFor="let noticeLevel of noticeService.noticeLevels"
          [value]="noticeLevel"
        >
          {{ noticeLevel }}
        </mat-option>
      </mat-select>
      <mat-error>Please select a level!</mat-error>
    </mat-form-field>
    <mat-form-field appearance="fill">
      <mat-label>Scope</mat-label>
      <input matInput formControlName="scope" placeholder="t4c" />
      <mat-error>Please enter a scope!</mat-error>
    </mat-form-field>
    <br />
    <mat-form-field appearance="fill" id="notice-description">
      <mat-label>Description</mat-label>
      <textarea matInput formControlName="message"></textarea
      ><mat-error *ngIf="message.getError('titleOrDescriptionAvailable')"
        >Please enter a description or title!</mat-error
      ></mat-form-field
    ><br />
    <button mat-flat-button color="primary" (click)="createNotice()">
      Create
    </button>
  </form>
</mat-card>
<mat-card id="handle-alerts">
  <h2>Handle alerts</h2>
  <div *ngIf="noticeService.notices.length"></div>
  <mat-accordion>
    <mat-expansion-panel *ngFor="let notice of noticeService.notices">
      <mat-expansion-panel-header class="expansion-panel">
        <mat-panel-title> {{ notice.title }} </mat-panel-title>
        <mat-panel-description>
          {{ notice.level }}
        </mat-panel-description>
        <mat-panel-description>
          {{ notice.scope }}
        </mat-panel-description>
      </mat-expansion-panel-header>
      <p>{{ notice.message }}</p>
      <button mat-flat-button color="primary" (click)="deleteNotice(notice.id)">
        Delete!
      </button>
    </mat-expansion-panel>
  </mat-accordion>
  <div *ngIf="!noticeService.notices.length">There are no existing alerts.</div>
</mat-card>

frontend/src/app/settings/admin-settings/alert-settings/alert-settings.component.css METASEP
mat-card {
  width: fit-content;
  margin: 10px;
  height: fit-content;
}

mat-form-field {
  margin-right: 10px;
}

h1 {
  margin: 10px;
}

.flexbox {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
}

button {
  margin-top: 5px;
  display: block;
}

#handle-alerts {
  max-width: 633px;
}

#notice-description {
  width: 623px;
}

frontend/src/app/settings/admin-settings/admin-user-settings/admin-user-settings.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { User } from 'src/app/schemes';
import { RepositoryUserService } from 'src/app/services/repository-user/repository-user.service';
import { UserService } from 'src/app/services/user/user.service';
import { lowerCaseValidator } from 'src/app/validators/validators';

@Component({
  selector: 'app-admin-user-settings',
  templateUrl: './admin-user-settings.component.html',
  styleUrls: ['./admin-user-settings.component.css'],
})
export class AdminUserSettingsComponent implements OnInit {
  createAdministratorFormGroup = new FormGroup({
    username: new FormControl('', [Validators.required]),
  });

  users: Array<User> = [];
  search = '';

  constructor(
    public userService: UserService,
    public repoUserService: RepositoryUserService
  ) {}

  ngOnInit(): void {
    this.getUsers();
  }

  get username(): FormControl {
    return this.createAdministratorFormGroup.get('username') as FormControl;
  }

  createAdministrator() {
    if (this.createAdministratorFormGroup.valid) {
      this.userService
        .updateRoleOfUser(
          this.createAdministratorFormGroup.value.username,
          'administrator'
        )
        .subscribe(() => {
          this.getUsers();
        });
    }
  }

  createAdministratorWithUsername(username: string) {
    this.userService
      .updateRoleOfUser(username, 'administrator')
      .subscribe(() => {
        this.getUsers();
      });
  }

  getUsers() {
    this.userService.getUsers().subscribe((res: Array<User>) => {
      this.users = res;
    });
  }

  removeAdministrator(username: string) {
    this.userService.updateRoleOfUser(username, 'user').subscribe(() => {
      this.getUsers();
    });
  }

  deleteUser(username: string) {
    this.userService.deleteUser(username).subscribe(() => {
      this.getUsers();
    });
  }

  getUsersByRole(role: 'administrator' | 'user'): Array<User> {
    return this.users.filter(
      (u) => u.role == role && u.name.includes(this.search.toLowerCase())
    );
  }
}

frontend/src/app/settings/admin-settings/admin-user-settings/admin-user-settings.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { AdminUserSettingsComponent } from './admin-user-settings.component';

describe('AdminUserSettingsComponent', () => {
  let component: AdminUserSettingsComponent;
  let fixture: ComponentFixture<AdminUserSettingsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ AdminUserSettingsComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(AdminUserSettingsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/admin-settings/admin-user-settings/admin-user-settings.component.html METASEP
<div class="flexbox">
  <mat-card id="manage-users">
    <h2>Manage users</h2>
    <mat-form-field id="search" appearance="outline">
      <mat-label>Search</mat-label>
      <input
        [(ngModel)]="search"
        autocomplete="off"
        matInput
        placeholder="Username"
      />
      <mat-icon matSuffix>search</mat-icon>
    </mat-form-field>
    <ngx-simplebar class="user-selection">
      <mat-selection-list #adminusers [multiple]="false">
        <div mat-subheader>Administrators</div>
        <mat-list-option
          *ngFor="let user of getUsersByRole('administrator')"
          [value]="user"
        >
          <mat-icon mat-list-icon>account_circle</mat-icon>
          <div mat-line>{{ user.name }}</div>
          <div mat-line>{{ repoUserService.ADVANCED_ROLES[user.role] }}</div>
        </mat-list-option>
        <div mat-subheader>Users</div>
        <mat-list-option
          *ngFor="let user of getUsersByRole('user')"
          [value]="user"
        >
          <mat-icon mat-list-icon>account_circle</mat-icon>
          <div mat-line>{{ user.name }}</div>
          <div mat-line>{{ repoUserService.ADVANCED_ROLES[user.role] }}</div>
        </mat-list-option>
      </mat-selection-list>
    </ngx-simplebar>

    <div *ngIf="adminusers.selectedOptions.selected.length">
      <button
        mat-flat-button
        color="primary"
        *ngIf="
          adminusers.selectedOptions.selected[0]?.value.role ==
            'administrator' &&
          adminusers.selectedOptions.selected[0]?.value.name !=
            userService.getUsernameFromLocalStorage()
        "
        (click)="
          this.removeAdministrator(
            adminusers.selectedOptions.selected[0]?.value.name
          )
        "
      >
        <mat-icon>arrow_downward</mat-icon>
        Downgrade
        {{ adminusers.selectedOptions.selected[0]?.value.name }} to User
      </button>
      <button
        mat-flat-button
        color="primary"
        (click)="
          createAdministratorWithUsername(
            adminusers.selectedOptions.selected[0]?.value.name
          )
        "
        *ngIf="adminusers.selectedOptions.selected[0]?.value.role === 'user'"
      >
        <mat-icon>arrow_upward</mat-icon>
        Upgrade
        {{ adminusers.selectedOptions.selected[0]?.value.name }} to
        Administrator
      </button>
      <button
        mat-flat-button
        color="primary"
        (click)="deleteUser(adminusers.selectedOptions.selected[0]?.value.name)"
        *ngIf="adminusers.selectedOptions.selected[0]?.value.role === 'user'"
      >
        <mat-icon>delete</mat-icon>
        Delete
        {{ adminusers.selectedOptions.selected[0]?.value.name }}
      </button>
    </div>
  </mat-card>
  <mat-card>
    <h2>Create Administrator</h2>
    Be careful with this option: <br />
    Administrators can control all sessions <br />
    and can modify all repositories! <br />
    <form [formGroup]="createAdministratorFormGroup">
      <mat-form-field>
        <mat-label>Username</mat-label>
        <input matInput formControlName="username" />
        <mat-error *ngIf="username.getError('required')"
          >Please enter a username!</mat-error
        >
        <mat-error *ngIf="username.getError('lowerCaseError')"
          >Usernames can only contain lowercase letters!
        </mat-error>
      </mat-form-field>
      <button mat-flat-button (click)="createAdministrator()" color="primary">
        Create Administrator <mat-icon>keyboard_arrow_right</mat-icon>
      </button>
    </form>
  </mat-card>
</div>

frontend/src/app/settings/admin-settings/admin-user-settings/admin-user-settings.component.css METASEP
mat-card {
  width: fit-content;
  margin: 10px;
  height: fit-content;
}

mat-form-field {
  margin-right: 10px;
}

h1 {
  margin: 10px;
}

.flexbox {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
}

#manage-users {
  min-width: 400px;
}

button {
  margin-top: 5px;
  display: block;
}

.user-selection {
  max-height: 40vh;
}

#search {
  padding-bottom: 0px;
  width: 400px;
}

frontend/src/app/services/modelsources/t4c-repos/t4c-repo.service.ts METASEP
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { environment } from 'src/environments/environment';

@Injectable({
  providedIn: 'root',
})
export class T4CRepoService {
  constructor(private http: HttpClient) {}
  repositories: Array<T4CRepository> = [];

  getRepositoryProjects(repository: string): Observable<Array<T4CRepository>> {
    return this.http
      .get<Array<T4CRepository>>(
        `${environment.backend_url}/projects/${repository}/extensions/modelsources/t4c`
      )
      .pipe(
        tap((res: Array<T4CRepository>) => {
          this.repositories = res;
        })
      );
  }

  createRepositoryProject(
    repository: string,
    project_name: string
  ): Observable<T4CRepository> {
    return this.http.post<T4CRepository>(
      `${environment.backend_url}/projects/${repository}/extensions/modelsources/t4c`,
      { name: project_name }
    );
  }

  deleteRepositoryProject(
    repository: string,
    project_id: number
  ): Observable<T4CRepository> {
    return this.http.delete<T4CRepository>(
      `${environment.backend_url}/projects/${repository}/extensions/modelsources/t4c/${project_id}`
    );
  }
}

export interface T4CRepository {
  id: number;
  name: string;
  repository_name: string;
}

frontend/src/app/services/modelsources/t4c-repos/t4c-repo.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { T4CRepoService } from './t4c-repo.service';

describe('T4CRepoService', () => {
  let service: T4CRepoService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(T4CRepoService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/services/modelsources/git-model/git-model.service.ts METASEP
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { environment } from 'src/environments/environment';

@Injectable({
  providedIn: 'root',
})
export class GitModelService {
  constructor(private http: HttpClient) {}
  models: Array<GitModel> = [];

  getGitRepositoriesForRepository(
    repository_name: string
  ): Observable<Array<GitModel>> {
    return this.http
      .get<Array<GitModel>>(
        environment.backend_url +
          '/projects/' +
          repository_name +
          '/extensions/modelsources/git'
      )
      .pipe(
        tap((res: Array<GitModel>) => {
          this.models = res;
        })
      );
  }

  unassignGitRepositoriesFromRepository(
    repository_name: string,
    model_id: number
  ): Observable<void> {
    return this.http.delete<void>(
      environment.backend_url +
        '/projects/' +
        repository_name +
        '/extensions/modelsources/git/' +
        model_id
    );
  }

  assignGitRepositoryToRepository(
    repository_name: string,
    body: CreateGitModel
  ): Observable<GitModel> {
    const reqBody = JSON.parse(JSON.stringify(body));
    // Base64 encoding is needed because some application gateways block urls in the requests
    reqBody.model.path = btoa(reqBody.model.path);
    return this.http.post<GitModel>(
      environment.backend_url +
        '/projects/' +
        repository_name +
        '/extensions/modelsources/git',
      reqBody
    );
  }

  makeGitRepositoryPrimary(
    repository_name: string,
    model_id: number
  ): Observable<GitModel> {
    return this.http.patch<GitModel>(
      environment.backend_url +
        '/projects/' +
        repository_name +
        '/extensions/modelsources/git/' +
        model_id,
      { primary: true }
    );
  }
}

export interface GitModel extends BasicGitModel {
  id: number;
  primary: boolean;
  username: string;
}

export interface BasicGitModel {
  name: string;
  model: {
    path: string;
    entrypoint: string;
    revision: string;
  };
}

export interface CreateGitModel extends BasicGitModel {
  credentials: {
    username: string;
    password: string;
  };
}

frontend/src/app/services/backups/jenkins/jenkins.service.ts METASEP
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';

@Injectable({
  providedIn: 'root',
})
export class JenkinsService {
  constructor(private http: HttpClient) {}

  getJenkinsPipelineForModel(
    repository: string,
    model_id: number
  ): Observable<JenkinsPipeline> {
    return this.http.get<JenkinsPipeline>(
      `${environment.backend_url}/projects/${repository}/extensions/backups/jenkins`
    );
  }

  createJenkinsPipelineForModel(
    repository: string,
    model_id: number
  ): Observable<JenkinsPipeline> {
    return this.http.post<JenkinsPipeline>(
      `${environment.backend_url}/projects/${repository}/extensions/backups/jenkins`,
      null
    );
  }

  createJenkinsJobForModel(
    repository: string,
    model_id: number,
    pipeline_name: string
  ): Observable<void> {
    return this.http.post<void>(
      `${environment.backend_url}/projects/${repository}/extensions/backups/jenkins/${pipeline_name}/jobs`,
      null
    );
  }

  removeJenkinsPipeline(
    repository: string,
    model_id: number,
    pipeline_name: string
  ): Observable<void> {
    return this.http.delete<void>(
      `${environment.backend_url}/projects/${repository}/extensions/backups/jenkins/${pipeline_name}`
    );
  }
}

export interface JenkinsPipeline {
  id: number;
  name: string;
  latest_run: JenkinsPipelineRun;
}
export interface JenkinsPipelineRun {
  id: number;
  result: string;
  start_time: string;
  logs_url: string;
}

frontend/src/app/services/backups/jenkins/jenkins.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { JenkinsService } from './jenkins.service';

describe('JenkinsService', () => {
  let service: JenkinsService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(JenkinsService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/services/backups/ease/easebackup.service.ts METASEP
import { ObserversModule } from '@angular/cdk/observers';
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';

@Injectable({
  providedIn: 'root',
})
export class EASEBackupService {
  constructor(private http: HttpClient) {}

  getBackups(project: string): Observable<Array<EASEBackup>> {
    return this.http.get<Array<EASEBackup>>(
      `${environment.backend_url}/projects/${project}/extensions/backups/ease`
    );
  }

  createBackup(project: string, body: PostEASEBackup): Observable<EASEBackup> {
    return this.http.post<EASEBackup>(
      `${environment.backend_url}/projects/${project}/extensions/backups/ease`,
      body
    );
  }

  removeBackup(project: string, backup_id: number): Observable<void> {
    return this.http.delete<void>(
      `${environment.backend_url}/projects/${project}/extensions/backups/ease/${backup_id}`
    );
  }

  triggerRun(project: string, backup_id: number): Observable<EASEBackupJob> {
    return this.http.post<EASEBackupJob>(
      `${environment.backend_url}/projects/${project}/extensions/backups/ease/${backup_id}/jobs`,
      null
    );
  }

  getLogs(
    project: string,
    backup_id: number,
    job_id: string
  ): Observable<string> {
    return this.http.get<string>(
      `${environment.backend_url}/projects/${project}/extensions/backups/ease/${backup_id}/jobs/${job_id}/logs`
    );
  }
}

export interface EASEBackupJob {
  id: string;
  date: string;
  state: string;
}

export interface EASEBackup extends PostEASEBackup {
  id: number;
  lastrun: EASEBackupJob;
}

export interface PostEASEBackup {
  t4cmodel: string;
  gitmodel: string;
}

frontend/src/app/services/backups/ease/easebackup.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { EASEBackupService } from './easebackup.service';

describe('EASEBackupService', () => {
  let service: EASEBackupService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(EASEBackupService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/home/request-session/warning/warning.component.ts METASEP
import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'app-warning',
  templateUrl: './warning.component.html',
  styleUrls: ['./warning.component.css'],
})
export class WarningComponent implements OnInit {
  constructor() {}

  ngOnInit(): void {}

  @Input()
  persistent = true;

  @Input()
  warning = '';
}

frontend/src/app/home/request-session/warning/warning.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { WarningComponent } from './warning.component';

describe('WarningComponent', () => {
  let component: WarningComponent;
  let fixture: ComponentFixture<WarningComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ WarningComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(WarningComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/home/request-session/warning/warning.component.html METASEP
<!-- <div *ngIf="persistent">
  <mat-card class="danger" *ngIf="warning == 'LICENCE_LIMIT'">
    All licences are in use! This will result in the "Invalid License" error
    being displayed when connecting. <br />Please use the "Read-only" connection
    type or wait for a free slot.
  </mat-card>
  <mat-card class="warning" *ngIf="warning == 'LICENCE_LIMIT'">
    There are less then 5 licences left! <br />This could result in the "Invalid
    License" error being displayed when connecting (if all licences are in use).
    <br />Please consider a Read-only workspace.
  </mat-card>
</div>
<div *ngIf="!persistent">
  <mat-card class="danger" *ngIf="warning == 'NO_GIT_MODEL_DEFINED'">
    The repository is not configured correctly. There is no Git repository
    linked.
    <br />
    Please contact a project manager.
  </mat-card>
</div> -->

frontend/src/app/home/request-session/warning/warning.component.css METASEP
.warning {
  background-color: #fff3cd;
  color: black;
}

mat-card {
  width: fit-content;
  margin: auto;
  margin-bottom: 10px;
}

.danger {
  background-color: #721c24;
  color: white;
}

frontend/src/app/auth/logout/logout/logout.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-logout',
  templateUrl: './logout.component.html',
  styleUrls: ['./logout.component.css'],
})
export class LogoutComponent implements OnInit {
  reason = '';
  autoLogin = false;

  constructor(private route: ActivatedRoute) {}

  ngOnInit(): void {
    this.route.queryParams.subscribe((params) => {
      this.reason = params['reason'];
      if (this.reason === 'session-expired') {
        this.autoLogin = true;
      }
    });
  }
}

frontend/src/app/auth/logout/logout/logout.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { LogoutComponent } from './logout.component';

describe('LogoutComponent', () => {
  let component: LogoutComponent;
  let fixture: ComponentFixture<LogoutComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ LogoutComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(LogoutComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/auth/logout/logout/logout.component.html METASEP
<div class="message">
  <div *ngIf="reason == 'logout'">The Logout was successful.</div>
  <div *ngIf="reason == 'session-expired'">Your session has expired.</div>
  <div *ngIf="reason == 'unauthorized'">
    An unknown error occurred during the authorization.
  </div>
  <app-auth [autoLogin]="autoLogin"></app-auth>
</div>

frontend/src/app/auth/logout/logout/logout.component.css METASEP
.message {
  margin-top: 30px;
  text-align: center;
}

frontend/src/app/auth/logout/logout-redirect/logout-redirect.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AuthService } from 'src/app/services/auth/auth.service';

@Component({
  selector: 'app-logout-redirect',
  templateUrl: './logout-redirect.component.html',
  styleUrls: ['./logout-redirect.component.css'],
})
export class LogoutRedirectComponent implements OnInit {
  constructor(private authService: AuthService, private router: Router) {}

  ngOnInit(): void {
    this.authService.logOut();
    this.router.navigate(['/logout'], { queryParamsHandling: 'merge' });
  }
}

frontend/src/app/auth/logout/logout-redirect/logout-redirect.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { LogoutRedirectComponent } from './logout-redirect.component';

describe('LogoutRedirectComponent', () => {
  let component: LogoutRedirectComponent;
  let fixture: ComponentFixture<LogoutRedirectComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ LogoutRedirectComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(LogoutRedirectComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/auth/logout/logout-redirect/logout-redirect.component.html METASEP
Redirecting...

frontend/src/app/auth/logout/logout-redirect/logout-redirect.component.css METASEP

frontend/src/app/settings/user-settings/user-settings.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { RepositoryUserService } from 'src/app/services/repository-user/repository-user.service';
import {
  RepositoryService,
  Repository,
} from 'src/app/services/repository/repository.service';
import { UserService } from 'src/app/services/user/user.service';

@Component({
  selector: 'app-user-settings',
  templateUrl: './user-settings.component.html',
  styleUrls: ['./user-settings.component.css'],
})
export class UserSettingsComponent implements OnInit {
  constructor(
    private repositoryService: RepositoryService,
    private repositoryUserService: RepositoryUserService,
    private userService: UserService
  ) {}
  repositories: Array<Repository> = [];
  updatePasswordSuccess = false;

  updatePasswordForm = new FormGroup({
    repository: new FormControl('', Validators.required),
    password: new FormControl('', [
      Validators.required,
      Validators.minLength(8),
    ]),
  });

  get repository(): FormControl {
    return this.updatePasswordForm.get('repository') as FormControl;
  }

  get password(): FormControl {
    return this.updatePasswordForm.get('password') as FormControl;
  }

  ngOnInit(): void {
    this.repositoryService
      .getRepositories()
      .subscribe((res: Array<Repository>) => {
        this.repositories = res.filter((repo) => {
          return repo.permissions.includes('write');
        });
      });
  }

  updatePassword(): void {
    if (this.updatePasswordForm.valid) {
      const value = this.updatePasswordForm.value;
      this.repositoryUserService
        .updatePasswordOfUser(
          value.repository,
          this.userService.getUsernameFromLocalStorage(),
          value.password
        )
        .subscribe(() => {
          this.updatePasswordSuccess = true;
          setTimeout(() => {
            this.updatePasswordSuccess = false;
          }, 3000);
        });
    }
  }
}

frontend/src/app/settings/user-settings/user-settings.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { UserSettingsComponent } from './user-settings.component';

describe('UserSettingsComponent', () => {
  let component: UserSettingsComponent;
  let fixture: ComponentFixture<UserSettingsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ UserSettingsComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(UserSettingsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/user-settings/user-settings.component.html METASEP
<h1>User Options</h1>
<div *ngIf="!repositories.length">
  <mat-card> You don't have any repositories. </mat-card>
</div>
<mat-card *ngIf="repositories.length"
  ><form [formGroup]="updatePasswordForm">
    <mat-form-field>
      <mat-label>Repository</mat-label>
      <mat-select formControlName="repository">
        <mat-option
          *ngFor="let repository of repositories"
          [value]="repository.repository_name"
          >{{ repository.repository_name }}</mat-option
        >
      </mat-select>
      <mat-error *ngIf="repository.getError('required')"
        >Please select a repository!</mat-error
      >
    </mat-form-field>
    <mat-form-field>
      <mat-label>Password</mat-label>
      <input type="password" formControlName="password" matInput />
      <mat-error *ngIf="password.getError('required')"
        >Please enter a password!</mat-error
      >
      <mat-error *ngIf="password.getError('minlength')"
        >The password must be at least 8 characters long!</mat-error
      >
    </mat-form-field>
    <button
      mat-flat-button
      [ngClass]="updatePasswordSuccess ? 'success' : 'primary'"
      type="submit"
      (click)="updatePassword()"
      id="update-password-button"
    >
      <span *ngIf="updatePasswordSuccess">
        <mat-icon>check_circle_outline</mat-icon>
      </span>
      <div *ngIf="!updatePasswordSuccess">Update Password</div>
    </button>
  </form>
</mat-card>

frontend/src/app/settings/user-settings/user-settings.component.css METASEP
mat-form-field {
  margin: 10px;
}

h1 {
  margin: 20px 0 0 10px;
}

mat-card {
  width: fit-content;
  margin: 10px;
}

#update-password-button {
  min-width: 110px;
}

frontend/src/app/settings/repository-manager-settings/repository-manager-settings.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { RepositoryUser } from 'src/app/schemes';
import { RepositoryService } from 'src/app/services/repository/repository.service';
import { UserService } from 'src/app/services/user/user.service';

@Component({
  selector: 'app-repository-manager-settings',
  templateUrl: './repository-manager-settings.component.html',
  styleUrls: ['./repository-manager-settings.component.css'],
})
export class RepositoryManagerSettingsComponent implements OnInit {
  constructor(
    public repositoryService: RepositoryService,
    public userService: UserService
  ) {}

  ngOnInit(): void {
    this.repositoryService.refreshRepositories();
  }
}

frontend/src/app/settings/repository-manager-settings/repository-manager-settings.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { RepositoryManagerSettingsComponent } from './repository-manager-settings.component';

describe('RepositoryManagerSettingsComponent', () => {
  let component: RepositoryManagerSettingsComponent;
  let fixture: ComponentFixture<RepositoryManagerSettingsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ RepositoryManagerSettingsComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(RepositoryManagerSettingsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/repository-manager-settings/repository-manager-settings.component.html METASEP
<h1>Project manager options</h1>
<mat-card>
  <h2>Manage projects</h2>
  You are Manager of these projects. Please select a project to see all
  settings. <br />
  <button
    *ngFor="let repo of repositoryService.repositories"
    color="primary"
    mat-flat-button
    [routerLink]="'/settings/projects/' + repo.repository_name"
  >
    {{ repo.repository_name }}
  </button>
  <button
    *ngIf="userService.user?.role === 'administrator'"
    color="primary"
    mat-flat-button
    [routerLink]="'/settings/projects/create'"
  >
    <mat-icon>add</mat-icon>
  </button></mat-card
>

frontend/src/app/settings/repository-manager-settings/repository-manager-settings.component.css METASEP
button {
  margin: 5px;
}

mat-card {
  width: fit-content;
  margin: 10px;
}

h1 {
  margin: 10px;
}

.flexbox {
  display: flex;
  flex-direction: row;
}

frontend/src/app/settings/admin-settings/admin-settings.component.ts METASEP
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-admin-settings',
  templateUrl: './admin-settings.component.html',
  styleUrls: ['./admin-settings.component.css'],
})
export class AdminSettingsComponent implements OnInit {
  constructor() {}

  ngOnInit(): void {}
}

frontend/src/app/settings/admin-settings/admin-settings.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { AdminSettingsComponent } from './admin-settings.component';

describe('AdminSettingsComponent', () => {
  let component: AdminSettingsComponent;
  let fixture: ComponentFixture<AdminSettingsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ AdminSettingsComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(AdminSettingsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/admin-settings/admin-settings.component.html METASEP
<h1>Administrator Options</h1>
<div class="flexbox">
  <app-admin-user-settings></app-admin-user-settings>
  <app-alert-settings></app-alert-settings>
  <app-repository-sync-settings></app-repository-sync-settings>
</div>

frontend/src/app/settings/admin-settings/admin-settings.component.css METASEP
h1 {
  margin: 10px;
}

.flexbox {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
}

frontend/src/app/session-overview/licences/licences.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { SessionsUsage } from 'src/app/schemes';
import { SessionService } from 'src/app/services/session/session.service';

@Component({
  selector: 'app-licences',
  templateUrl: './licences.component.html',
  styleUrls: ['./licences.component.css'],
})
export class LicencesComponent implements OnInit {
  constructor(private sessionService: SessionService) {}

  ngOnInit(): void {
    this.sessionService.getSessionsUsage().subscribe((res) => {
      this.sessionsUsage = res;
    });
  }

  sessionsUsage: SessionsUsage | undefined = undefined;

  getErrorMessage(error: string): string {
    switch (error) {
      case 'T4C_ERROR':
        return 'Internal server error in the license server.';
      case 'TIMEOUT':
        return 'The connection to the license server timed out.';
      case 'CONNECTION_ERROR':
        return 'The connection to the license server failed.';
      case 'NO_STATUS':
        return 'No status is available. This can happen during and after license server restarts.';
      case 'NO_STATUS_JSON':
        return 'No status in response from license server.';
      case 'UNKNOWN_ERROR':
        return 'An unknown error occured when communicating with the license server.';
      case 'DECODE_ERROR':
        return 'License server response could not be decoded.';
      default:
        return 'Unknown error. Please contact your system administrator.';
    }
  }
}

frontend/src/app/session-overview/licences/licences.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { LicencesComponent } from './licences.component';

describe('LicencesComponent', () => {
  let component: LicencesComponent;
  let fixture: ComponentFixture<LicencesComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ LicencesComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(LicencesComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/session-overview/licences/licences.component.html METASEP
<div id="licences" *ngIf="sessionsUsage">
  <div *ngIf="!sessionsUsage.errors.length">
    Used licences: {{ sessionsUsage.total - sessionsUsage.free }}/{{
      sessionsUsage.total
    }}
  </div>
  <div class="error" *ngFor="let error of sessionsUsage.errors">
    {{ getErrorMessage(error) }}
  </div>
</div>

frontend/src/app/session-overview/licences/licences.component.css METASEP
#licences {
  margin: 20px 0 0 20px;
}

.error {
  color: var(--error-color);
}

frontend/src/app/session-creation-progress/session-progress-icon/session-progress-icon.component.ts METASEP
import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'app-session-progress-icon',
  templateUrl: './session-progress-icon.component.html',
  styleUrls: ['./session-progress-icon.component.css'],
})
export class SessionProgressIconComponent implements OnInit {
  @Input()
  state = 'pending';

  constructor() {}

  ngOnInit(): void {}
}

frontend/src/app/session-creation-progress/session-progress-icon/session-progress-icon.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { SessionProgressIconComponent } from './session-progress-icon.component';

describe('SessionProgressIconComponent', () => {
  let component: SessionProgressIconComponent;
  let fixture: ComponentFixture<SessionProgressIconComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ SessionProgressIconComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(SessionProgressIconComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/session-creation-progress/session-progress-icon/session-progress-icon.component.html METASEP
<span *ngIf="state === 'success'" class="circle"
  ><mat-icon style="color: green">check_circle</mat-icon></span
>
<span *ngIf="state === 'running'" class="circle"
  ><mat-spinner [diameter]="35"></mat-spinner
></span>
<span *ngIf="state === 'pending'" class="circle" style="color: grey"
  ><mat-icon>access_time</mat-icon></span
>
<span *ngIf="state === 'error'" class="circle" style="color: darkred"
  ><mat-icon>error</mat-icon></span
>

frontend/src/app/session-creation-progress/session-progress-icon/session-progress-icon.component.css METASEP
:host ::ng-deep .mat-progress-spinner circle,
.mat-spinner circle {
  stroke: black;
  width: 10px !important;
  height: 10px !important;
}

mat-icon {
  font-size: 2.5em;
  background-color: white;
  margin-bottom: 5px;
}

.error {
  background-color: var(--error-color);
}

.warning {
  background-color: var(--warning-color);
}

.success {
  background-color: var(--success-color);
}

frontend/src/app/session-created/rdp/rdp.component.ts METASEP
import { Component, Input, OnInit } from '@angular/core';
import { Session } from 'src/app/schemes';
import { SessionService } from 'src/app/services/session/session.service';

@Component({
  selector: 'app-rdp',
  templateUrl: './rdp.component.html',
  styleUrls: ['./rdp.component.css'],
})
export class RDPComponent implements OnInit {
  @Input()
  session: Session | undefined = undefined;

  constructor() {}

  ngOnInit(): void {}
}

frontend/src/app/session-created/rdp/rdp.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { RDPComponent } from './rdp.component';

describe('RDPComponent', () => {
  let component: RDPComponent;
  let fixture: ComponentFixture<RDPComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ RDPComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(RDPComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/session-created/rdp/rdp.component.html METASEP
<div *ngIf="session">
  <div class="title-2">Connect via RDP</div>
  <mat-card>Temporary not available</mat-card>
  <!-- 
  <mat-card class="inner-mat-card">
    <div class="title">Step 1: How do I connect to the server?</div>
    The Server is reachable over RDP: <br />
    <table>
      <tr>
        <th>Host:</th>
        <th>Port:</th>
      </tr>
      <tr>
        <td>
          <button mat-button cdkCopyToClipboard="localhost">
            localhost &nbsp;<mat-icon>content_copy</mat-icon>
          </button>
        </td>
        <td>
          <button mat-button [cdkCopyToClipboard]="session.ports[0]">
            {{ session.ports[0] }}
            &nbsp;<mat-icon>content_copy</mat-icon>
          </button>
        </td>
      </tr>
    </table>
  </mat-card>
  <mat-card class="inner-mat-card">
    <div class="title">Step 2: Authentication</div>
    When you connect to the server, you have to use the following credentials to
    log in: <br />
    <table>
      <tr>
        <th>Username:</th>
        <th>Password:</th>
      </tr>
      <tr>
        <td>
          <button mat-button [cdkCopyToClipboard]="session.rdp_username">
            {{ session.rdp_username }}
            &nbsp;<mat-icon>content_copy</mat-icon>
          </button>
        </td>
        <td>
          <button mat-button [cdkCopyToClipboard]="session.rdp_password">
            ****** &nbsp;<mat-icon>content_copy</mat-icon>
          </button>
        </td>
      </tr>
    </table>
  </mat-card>
  <mat-card class="inner-mat-card">
    <div class="title">Step 3: Wait for Capella</div>
    After logging in, Capella starts automatically. This can up to one minute.
  </mat-card>-->
</div>

frontend/src/app/session-created/rdp/rdp.component.css METASEP
mat-card {
  margin-top: 10px;
  width: fit-content;
  margin-left: auto;
  margin-right: auto;
}

table td {
  border: 0;
}

table {
  margin-left: auto;
  margin-right: auto;
}

.title {
  font-size: 1.2em;
  font-weight: bold;
  margin-bottom: 2px;
}

.title-2 {
  font-size: 1.3em;
  font-weight: bold;
  margin-bottom: 2px;
  color: #ec0016;
}

.inner-mat-card {
  width: 90%;
}

frontend/src/app/session-created/guacamole/guacamole.component.ts METASEP
import { Component, Input, OnInit } from '@angular/core';
import { LocalStorageService } from 'src/app/auth/local-storage/local-storage.service';
import { Session } from 'src/app/schemes';
import { GuacamoleService } from 'src/app/services/guacamole/guacamole.service';
import { SessionService } from 'src/app/services/session/session.service';
import { UserService } from 'src/app/services/user/user.service';
import { environment } from 'src/environments/environment';

@Component({
  selector: 'app-guacamole',
  templateUrl: './guacamole.component.html',
  styleUrls: ['./guacamole.component.css'],
})
export class GuacamoleComponent implements OnInit {
  @Input()
  session: Session | undefined = undefined;

  constructor(
    public userService: UserService,
    private localStorageService: LocalStorageService,
    private guacamoleService: GuacamoleService
  ) {}

  ngOnInit(): void {}

  redirectToGuacamole(): void {
    this.guacamoleService
      .getGucamoleToken(this.session?.id || '')
      .subscribe((res) => {
        this.localStorageService.setValue('GUAC_AUTH', res.token);
        window.open(res.url);
      });
  }
}

frontend/src/app/session-created/guacamole/guacamole.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { GuacamoleComponent } from './guacamole.component';

describe('GuacamoleComponent', () => {
  let component: GuacamoleComponent;
  let fixture: ComponentFixture<GuacamoleComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ GuacamoleComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(GuacamoleComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/session-created/guacamole/guacamole.component.html METASEP
<div *ngIf="session">
  <div class="title-2">Connect directly via Browser</div>
  <mat-card class="inner-mat-card">
    <div class="title">Step 1: How do I connect to the server?</div>
    Please click on this button to connect to the server: <br />
    <button mat-flat-button color="primary" (click)="redirectToGuacamole()">
      Connect to Session
    </button>
  </mat-card>
  <mat-card class="inner-mat-card">
    <div class="title">Step 2: Wait for Capella</div>
    After opening the session, Capella starts automatically. This can up to one
    minute.
  </mat-card>
  <mat-card class="inner-mat-card" *ngIf="session.type == 'persistent'">
    <div class="title">Step 3: T4C Login</div>
    Please enter "{{ userService.getUsernameFromLocalStorage() }}" as username
    and your password. <br />
    If you don't know your password, you can change it in the
    <a routerLink="/settings">settings</a>. <br />
  </mat-card>
</div>

frontend/src/app/session-created/guacamole/guacamole.component.css METASEP
mat-card {
  margin-top: 10px;
  width: fit-content;
  margin-left: auto;
  margin-right: auto;
}

table td {
  border: 0;
}

table {
  margin-left: auto;
  margin-right: auto;
}

.title {
  font-size: 1.2em;
  font-weight: bold;
  margin-bottom: 2px;
}

.title-2 {
  font-size: 1.3em;
  font-weight: bold;
  margin-bottom: 2px;
  color: var(--primary-color);
}

.inner-mat-card {
  width: 90%;
}
a {
  text-decoration: none;
  color: var(--primary-color);
}

frontend/src/app/services/user/user.service.ts METASEP
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { LocalStorageService } from 'src/app/auth/local-storage/local-storage.service';
import { Session, User } from 'src/app/schemes';
import { environment } from 'src/environments/environment';
import { AuthService } from '../auth/auth.service';

@Injectable({
  providedIn: 'root',
})
export class UserService {
  user: User | undefined = undefined;

  BACKEND_URL_PREFIX = environment.backend_url + '/users/';
  constructor(
    private http: HttpClient,
    private localStorageService: LocalStorageService,
    private authService: AuthService
  ) {
    if (this.authService.isLoggedIn()) {
      this.getAndSaveOwnUser();
    }
  }

  getAndSaveOwnUser(): void {
    this.getUser(this.getUsernameFromLocalStorage()).subscribe((res) => {
      this.user = res;
    });
  }

  getUser(username: string): Observable<User> {
    return this.http.get<User>(this.BACKEND_URL_PREFIX + username);
  }

  deleteUser(username: string): Observable<any> {
    return this.http.delete<any>(this.BACKEND_URL_PREFIX + username);
  }

  getUsers(): Observable<Array<User>> {
    return this.http.get<Array<User>>(this.BACKEND_URL_PREFIX);
  }

  getUsernameFromLocalStorage(): string {
    return JSON.parse(
      atob(this.localStorageService.getValue('access_token').split('.')[1])
    )['preferred_username'];
  }

  getOwnActiveSessions(): Observable<Array<Session>> {
    return this.http.get<Array<Session>>(
      this.BACKEND_URL_PREFIX +
        this.getUsernameFromLocalStorage() +
        '/sessions/'
    );
  }

  updateRoleOfUser(
    username: string,
    role: 'user' | 'administrator'
  ): Observable<User> {
    return this.http.patch<User>(
      this.BACKEND_URL_PREFIX + username + '/roles',
      {
        role,
      }
    );
  }
}

frontend/src/app/services/user/user.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { UserService } from './user.service';

describe('UserService', () => {
  let service: UserService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(UserService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/services/t4c-sync/t4-csync.service.ts METASEP
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';

@Injectable({
  providedIn: 'root',
})
export class T4CSyncService {
  constructor(private http: HttpClient) {}

  syncRepositories(): Observable<void> {
    return this.http.post<void>(
      environment.backend_url + '/sync/repositories',
      null
    );
  }
}

frontend/src/app/services/t4c-sync/t4-csync.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { T4CSyncService } from './t4-csync.service';

describe('T4CSyncService', () => {
  let service: T4CSyncService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(T4CSyncService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/services/session/session.service.ts METASEP
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';
import { Session, SessionsUsage } from '../../schemes';

@Injectable({
  providedIn: 'root',
})
export class SessionService {
  constructor(private http: HttpClient) {}
  BACKEND_URL_PREFIX = environment.backend_url + '/sessions/';

  getCurrentSessions(): Observable<Array<Session>> {
    return this.http.get<Array<Session>>(this.BACKEND_URL_PREFIX);
  }

  createNewSession(
    type: 'readonly' | 'persistent',
    repository: string | undefined
  ): Observable<Session> {
    return this.http.post<Session>(this.BACKEND_URL_PREFIX, {
      type,
      repository,
    });
  }

  deleteSession(id: string): Observable<any> {
    return this.http.delete<any>(this.BACKEND_URL_PREFIX + id);
  }

  getSessionsUsage(): Observable<SessionsUsage> {
    return this.http.get<SessionsUsage>(this.BACKEND_URL_PREFIX + 'usage');
  }
}

frontend/src/app/services/session/session.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { SessionService } from './session.service';

describe('SessionService', () => {
  let service: SessionService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(SessionService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/services/repository/repository.service.ts METASEP
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';
import { AuthService } from '../auth/auth.service';

@Injectable({
  providedIn: 'root',
})
export class RepositoryService {
  constructor(private http: HttpClient, private authService: AuthService) {
    if (this.authService.isLoggedIn()) {
      this.getAndSaveManagerRole();
    }
  }
  BACKEND_URL_PREFIX = environment.backend_url + '/projects/';
  isManager: boolean = false;
  repositories: Array<Repository> = [];

  getAndSaveManagerRole(): void {
    this.getRepositories().subscribe((res: Array<Repository>) => {
      let tmpIsManager = false;
      for (let s of res) {
        if (s.role === 'administrator' || s.role === 'manager') {
          tmpIsManager = true;
        }
      }
      this.isManager = tmpIsManager;
    });
  }

  getRepositories(): Observable<Array<Repository>> {
    return this.http.get<Array<Repository>>(this.BACKEND_URL_PREFIX);
  }

  refreshRepositories(): void {
    this.getRepositories().subscribe((res) => {
      this.repositories = res;
    });
  }

  createRepository(name: string): Observable<Repository> {
    return this.http.post<Repository>(this.BACKEND_URL_PREFIX, {
      name,
    });
  }
}

export type Warnings = 'LICENCE_LIMIT' | 'NO_GIT_MODEL_DEFINED';

export interface Repository {
  repository_name: string;
  username: string;
  permissions: Array<'read' | 'write'>;
  warnings: Array<Warnings>;
  role: 'user' | 'manager' | 'administrator';
}

frontend/src/app/services/repository/repository.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { RepositoryService } from './repository.service';

describe('RepositoryService', () => {
  let service: RepositoryService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(RepositoryService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/services/repository-user/repository-user.service.ts METASEP
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { RepositoryUser } from 'src/app/schemes';
import { environment } from 'src/environments/environment';
import { AuthService } from '../auth/auth.service';

@Injectable({
  providedIn: 'root',
})
export class RepositoryUserService {
  constructor(private http: HttpClient) {}
  BACKEND_URL_PREFIX = environment.backend_url + '/projects/';

  PERMISSIONS = { read: 'Read only', write: 'Read/Write' };
  ROLES = { user: 'User', manager: 'Manager' };
  ADVANCED_ROLES = { administrator: 'Administrator', ...this.ROLES };

  getRepoUsers(repository: string): Observable<Array<RepositoryUser>> {
    return this.http.get<Array<RepositoryUser>>(
      this.BACKEND_URL_PREFIX + repository + '/users'
    );
  }

  addUserToRepo(
    repository: string,
    username: string,
    role: 'user' | 'manager',
    permission: string
  ): Observable<RepositoryUser> {
    return this.http.post<RepositoryUser>(
      this.BACKEND_URL_PREFIX + repository + '/users',
      { username, role, permission }
    );
  }

  changeRoleOfRepoUser(
    repository: string,
    username: string,
    role: 'user' | 'manager'
  ): Observable<any> {
    return this.http.patch<any>(
      this.BACKEND_URL_PREFIX + repository + '/users/' + username,
      { role }
    );
  }

  updatePasswordOfUser(
    repository: string,
    username: string,
    password: string
  ): Observable<void> {
    return this.http.patch<any>(
      this.BACKEND_URL_PREFIX + repository + '/users/' + username,
      { password }
    );
  }

  changePermissionOfRepoUser(
    repository: string,
    username: string,
    permission: 'read' | 'write'
  ): Observable<any> {
    return this.http.patch<any>(
      this.BACKEND_URL_PREFIX + repository + '/users/' + username,
      { permission }
    );
  }

  deleteUserFromRepo(repository: string, username: string): Observable<any> {
    return this.http.delete<any>(
      this.BACKEND_URL_PREFIX + repository + '/users/' + username
    );
  }
}

frontend/src/app/services/repository-user/repository-user.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { RepositoryUserService } from './repository-user.service';

describe('RepositoryUserService', () => {
  let service: RepositoryUserService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(RepositoryUserService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/services/own-session/own-session.service.ts METASEP
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Session } from 'src/app/schemes';
import { UserService } from '../user/user.service';

@Injectable({
  providedIn: 'root',
})
export class OwnSessionService {
  sessions: Array<Session> = [];

  constructor(private userService: UserService) {}

  refreshSessions(): Observable<Array<Session>> {
    return this.userService.getOwnActiveSessions().pipe(
      tap((res: Array<Session>) => {
        this.sessions = res;
      })
    );
  }
}

frontend/src/app/services/own-session/own-session.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { OwnSessionService } from './own-session.service';

describe('OwnSessionService', () => {
  let service: OwnSessionService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(OwnSessionService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/services/notice/notice.service.ts METASEP
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';

@Injectable({
  providedIn: 'root',
})
export class NoticeService {
  notices: Array<Notice> = [];
  noticeLevels = [
    'primary',
    'secondary',
    'success',
    'danger',
    'warning',
    'info',
    'alert',
  ];
  constructor(private http: HttpClient) {
    this.refreshNotices();
  }

  refreshNotices(): void {
    this.getNotices().subscribe((res) => {
      this.notices = res;
    });
  }

  getNotices(): Observable<Array<Notice>> {
    return this.http.get<Array<Notice>>(environment.backend_url + '/notices');
  }

  deleteNotice(id: number): Observable<void> {
    return this.http.delete<void>(environment.backend_url + '/notices/' + id);
  }

  createNotice(body: CreateNotice): Observable<Notice> {
    return this.http.post<Notice>(environment.backend_url + '/notices', body);
  }
}

export interface Notice extends CreateNotice {
  id: number;
}

interface CreateNotice {
  level: NoticeLevel;
  title: string;
  message: string;
  scope: string;
}

export type NoticeLevel =
  | 'primary'
  | 'secondary'
  | 'success'
  | 'danger'
  | 'warning'
  | 'info'
  | 'alert';

frontend/src/app/services/notice/notice.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { NoticeService } from './notice.service';

describe('NoticeService', () => {
  let service: NoticeService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(NoticeService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/services/guacamole/guacamole.service.ts METASEP
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';

@Injectable({
  providedIn: 'root',
})
export class GuacamoleService {
  constructor(private http: HttpClient) {}

  getGucamoleToken(session_id: string): Observable<GuacamoleAuthentication> {
    return this.http.post<GuacamoleAuthentication>(
      environment.backend_url + '/sessions/' + session_id + '/guacamole-tokens',
      null
    );
  }
}

export interface GuacamoleAuthentication {
  url: string;
  token: string;
}

frontend/src/app/services/guacamole/guacamole.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { GuacamoleService } from './guacamole.service';

describe('GuacamoleService', () => {
  let service: GuacamoleService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(GuacamoleService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/services/encoder/encoder.interceptor.ts METASEP
import { Injectable } from '@angular/core';
import { DefaultUrlSerializer, UrlSerializer, UrlTree } from '@angular/router';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpParameterCodec,
  HttpParams,
} from '@angular/common/http';
import { Observable } from 'rxjs';

// The HTTPClient removes trailing whitespaces in usernames by default, but they exist.
@Injectable()
export class WhitespaceUrlInterceptor implements HttpInterceptor {
  constructor() {}

  intercept(
    request: HttpRequest<unknown>,
    next: HttpHandler
  ): Observable<HttpEvent<unknown>> {
    const url = request.url.replace(' ', '%20');
    return next.handle(request.clone({ url }));
  }
}

frontend/src/app/services/beatify/beautify.service.ts METASEP
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class BeautifyService {
  constructor() {}

  beatifyState(state: string | undefined): SessionState {
    let text = state;
    let css = 'warning';
    switch (state) {
      case '404':
        text = 'Error: Session not found';
        css = 'error';
        break;
      case 'pending':
        text = 'Waiting for resources';
        css = 'warning';
        break;
      case 'ImagePullBackOff':
      case 'ErrImagePull':
        text = 'Failed to pull image';
        css = 'error';
        break;
      case 'ContainerCreating':
        text = 'Creating session';
        css = 'warning';
        break;
      case 'Running':
        text = 'Running';
        css = 'success';
        break;
      case 'START_LOAD_MODEL':
        text = 'Modelloading started';
        css = 'warning';
        break;
      case 'FINISH_LOAD_MODEL':
        text = 'Modelloading finished';
        css = 'warning';
        break;
      case 'FAILURE_LOAD_MODEL':
        text = 'Error during loading of the model';
        css = 'error';
        break;
      case 'START_PREPARE_WORKSPACE':
        text = 'Started workspace preparation';
        css = 'warning';
        break;
      case 'FINISH_PREPARE_WORKSPACE':
        text = 'Workspace preparation finished';
        css = 'warning';
        break;
      case 'FAILURE_PREPARE_WORKSPACE':
        text = 'Error during workspace preparation';
        css = 'error';
        break;
      case 'START_SESSION':
        text = 'Session started';
        css = 'success';
        break;
      case 'unknown':
        text = 'Unknown State';
        css = 'primary';
        break;
      case 'Unschedulable':
        text = 'Unschedulable';
        css = 'error';
        break;
      case 'NOT_FOUND':
        text = 'Not found';
        css = 'error';
        break;
    }

    return {
      text: text || '',
      css: css,
    };
  }

  beatifyDate(date: string): string {
    const newDate = new Date(date);
    const now = new Date();
    let newDateString = '';
    if (
      newDate.getFullYear() == now.getFullYear() &&
      newDate.getMonth() == now.getMonth() &&
      newDate.getDate() == now.getDate()
    ) {
      newDateString = 'today';
    } else {
      newDateString =
        'on ' +
        newDate.toLocaleDateString(undefined, {
          year: 'numeric',
          month: 'numeric',
          day: 'numeric',
        });
    }

    return (
      newDateString +
      ' at ' +
      newDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
    );
  }
}

export interface SessionState {
  text: string;
  css: string;
}

frontend/src/app/services/beatify/beautify.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { BeautifyService } from './beautify.service';

describe('BeautifyService', () => {
  let service: BeautifyService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(BeautifyService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/services/auth/auth.service.ts METASEP
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { LocalStorageService } from 'src/app/auth/local-storage/local-storage.service';
import { environment } from 'src/environments/environment';

@Injectable({
  providedIn: 'root',
})
export class AuthService {
  constructor(
    private http: HttpClient,
    private localStorageService: LocalStorageService
  ) {}

  getRedirectURL(): Observable<GetRedirectURLResponse> {
    return this.http.get<GetRedirectURLResponse>(
      environment.backend_url + '/auth/oauth'
    );
  }

  getAccessToken(code: string, state: string): Observable<PostTokenResponse> {
    return this.http.post<PostTokenResponse>(
      environment.backend_url + '/auth/oauth/tokens',
      {
        code,
        state,
      }
    );
  }

  refreshToken(refresh_token: string): Observable<RefreshTokenResponse> {
    return this.http.put<PostTokenResponse>(
      environment.backend_url + '/auth/oauth/tokens',
      { refresh_token }
    );
  }

  isLoggedIn(): boolean {
    return !!this.localStorageService.getValue('access_token');
  }

  logOut() {
    return this.http
      .get(environment.backend_url + '/auth/oauth/logout')
      .toPromise()
      .then(() => {
        this.localStorageService.setValue('access_token', '');
        this.localStorageService.setValue('refresh_token', '');
        this.localStorageService.setValue('GUAC_AUTH', '');
      });
  }
}

export interface GetRedirectURLResponse {
  auth_url: string;
  state: string;
}

export interface PostTokenResponse {
  access_token: string;
  token_type: string;
  refresh_token: string;
}

export interface RefreshTokenResponse {
  access_token: string;
  token_type: string;
  refresh_token: string;
}

frontend/src/app/services/auth/auth.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { AuthService } from './auth.service';

describe('AuthService', () => {
  let service: AuthService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(AuthService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/home/request-session/request-session.component.ts METASEP
import { Component, EventEmitter, Input, OnInit } from '@angular/core';
import {
  AbstractControl,
  FormControl,
  FormGroup,
  ValidationErrors,
  ValidatorFn,
  Validators,
} from '@angular/forms';
import { MatSelectChange } from '@angular/material/select';
import { Session } from 'src/app/schemes';
import { RepositoryUserService } from 'src/app/services/repository-user/repository-user.service';
import {
  Repository,
  Warnings,
} from 'src/app/services/repository/repository.service';
import { SessionService } from 'src/app/services/session/session.service';

@Component({
  selector: 'app-request-session',
  templateUrl: './request-session.component.html',
  styleUrls: ['./request-session.component.css'],
})
export class RequestSessionComponent implements OnInit {
  showSpinner = false;
  creationSuccessful = false;
  repositoryFormGroup = new FormGroup(
    {
      workspaceSwitch: new FormControl(true),
      repository: new FormControl(''),
    },
    this.validateForm()
  );

  get repository(): FormControl {
    return this.repositoryFormGroup.get('repository') as FormControl;
  }

  get workspaceSwitch(): FormControl {
    return this.repositoryFormGroup.get('workspaceSwitch') as FormControl;
  }

  @Input()
  repositories: Array<Repository> = [];

  warnings: Array<Warnings> = [];

  permissions: any = {};

  session: Session | undefined = undefined;
  connectionTypeHelpIsOpen = false;
  persistentWorkspaceHelpIsOpen = false;
  cleanWorkspaceHelpIsOpen = false;

  constructor(
    public sessionService: SessionService,
    private repoUserService: RepositoryUserService
  ) {}

  ngOnInit(): void {}

  validateForm(): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      if (
        control.get('workspaceSwitch')?.value &&
        !control.get('repository')?.value
      ) {
        control.get('repository')?.setErrors({ repositoryRequired: true });
        return { repositoryRequired: true };
      }
      control.get('repository')?.setErrors(null);
      return null;
    };
  }

  requestSession() {
    if (this.repositoryFormGroup.valid) {
      this.showSpinner = true;
      this.creationSuccessful = false;
      let type: 'readonly' | 'persistent' = 'readonly';
      if (this.workspaceSwitch.value) {
        type = 'readonly';
      } else {
        type = 'persistent';
      }
      this.sessionService
        .createNewSession(type, this.repository.value)
        .subscribe(
          (res) => {
            this.session = res;
            this.showSpinner = false;
            this.creationSuccessful = true;
          },
          () => {
            this.showSpinner = false;
          }
        );
    }
  }

  setPermissionsAndWarningsByName(event: MatSelectChange): void {
    this.permissions = {};
    this.warnings = [];
    for (let repo of this.repositories) {
      if (repo.repository_name == event.value) {
        for (let permission of repo.permissions) {
          this.permissions[permission] =
            this.repoUserService.PERMISSIONS[permission];
        }
        this.warnings = repo.warnings;
        return;
      }
    }
    this.permissions = {};
  }
}

frontend/src/app/home/request-session/request-session.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { RequestSessionComponent } from './request-session.component';

describe('RequestSessionComponent', () => {
  let component: RequestSessionComponent;
  let fixture: ComponentFixture<RequestSessionComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ RequestSessionComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(RequestSessionComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/home/request-session/request-session.component.html METASEP
<div class="repository-selection">
  <form [formGroup]="repositoryFormGroup">
    <div class="workspace-toggle">
      <a
        (click)="persistentWorkspaceHelpIsOpen = !persistentWorkspaceHelpIsOpen"
        mat-icon-button
        cdkOverlayOrigin
        #overlayOriginPersistentWorkspace="cdkOverlayOrigin"
        class="help-button-workspace"
        ><mat-icon>help</mat-icon></a
      >
      <ng-template
        cdkConnectedOverlay
        [cdkConnectedOverlayOrigin]="overlayOriginPersistentWorkspace"
        [cdkConnectedOverlayOpen]="persistentWorkspaceHelpIsOpen"
      >
        <div class="help">
          Persistent Workspaces will store all the changes you make on models.
          Additionally, newly created projects will be stored in your personal
          workspace. <br />
          <b
            >If you don't plan on making changes to the models, please use the
            "Read-only Workspace" option.</b
          >
          <br />
          Please note that you have only access to T4C models if a Repository
          Manager gave you access and you have set the password for the
          repository in your settings.
        </div>
      </ng-template>
      Persistent Workspace &nbsp;
      <mat-slide-toggle formControlName="workspaceSwitch"></mat-slide-toggle>
      &nbsp; Read-only Workspace
      <a
        (click)="cleanWorkspaceHelpIsOpen = !cleanWorkspaceHelpIsOpen"
        mat-icon-button
        cdkOverlayOrigin
        #overlayOriginCleanWorkspace="cdkOverlayOrigin"
        class="help-button-workspace"
        ><mat-icon>help</mat-icon></a
      >
      <ng-template
        cdkConnectedOverlay
        [cdkConnectedOverlayOrigin]="overlayOriginCleanWorkspace"
        [cdkConnectedOverlayOpen]="cleanWorkspaceHelpIsOpen"
      >
        <div class="help">
          Due to the limitation of licences, we decided to offer a new "Read
          only" option.<br />
          <b>Any changes made in this session will NOT be saved.</b>
          <br />
          This will give more users the opportunity to work on the models since
          "Read only" users do not need a license.
          <br />
          A model with this option always has the state from last night (3 a.m.)
        </div>
      </ng-template>
    </div>
    <br />
    <div class="clean-workspace" *ngIf="workspaceSwitch.value">
      <mat-form-field appearance="fill">
        <mat-label>Repository</mat-label>
        <mat-select
          formControlName="repository"
          (selectionChange)="setPermissionsAndWarningsByName($event)"
        >
          <mat-option
            *ngFor="let repository of repositories"
            [value]="repository.repository_name"
            >{{ repository.repository_name }}</mat-option
          >
        </mat-select>
        <mat-error>Please select a repository!</mat-error></mat-form-field
      ><br />
    </div>
    <div class="center" *ngFor="let warning of warnings">
      <app-warning
        [warning]="warning"
        [persistent]="!workspaceSwitch.value"
      ></app-warning>
    </div>
    <button
      mat-flat-button
      color="primary"
      (click)="requestSession()"
      [disabled]="showSpinner || !repositoryFormGroup.valid"
    >
      Request Session <mat-icon>keyboard_arrow_right</mat-icon>
    </button>
  </form>
</div>

<mat-spinner *ngIf="showSpinner"></mat-spinner>
<app-session-creation-progress
  *ngIf="creationSuccessful"
  [session]="session"
></app-session-creation-progress>

frontend/src/app/home/request-session/request-session.component.css METASEP
mat-spinner {
  margin-top: 70px;
  margin-left: auto;
  margin-right: auto;
}

.center {
  margin-left: auto;
  margin-right: auto;
}

mat-card {
  width: fit-content;
  margin: auto;
  margin-bottom: 10px;
}

.help-button {
  top: -8px;
  left: -7px;
}

.help-button-workspace {
  top: -1px;
}

.help {
  width: 300px;
  border: solid 1px #ccc;
  border-radius: 5px;
  background: #fff;
  text-align: center;
  padding: 10px;
  margin: 0;
}

#field-connection-type {
  margin-left: 40px;
}

.workspace-toggle {
  margin: 20px 0 10px 0;
}

.repository-selection {
  margin-bottom: 20px;
}

frontend/src/app/home/no-repository/no-repository.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { UserService } from 'src/app/services/user/user.service';

@Component({
  selector: 'app-no-repository',
  templateUrl: './no-repository.component.html',
  styleUrls: ['./no-repository.component.css'],
})
export class NoRepositoryComponent implements OnInit {
  constructor(public userService: UserService) {}

  ngOnInit(): void {}
}

frontend/src/app/home/no-repository/no-repository.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { NoRepositoryComponent } from './no-repository.component';

describe('NoRepositoryComponent', () => {
  let component: NoRepositoryComponent;
  let fixture: ComponentFixture<NoRepositoryComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ NoRepositoryComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(NoRepositoryComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/home/no-repository/no-repository.component.html METASEP
<div class="no-repository">
  <mat-card>
    Unfortunately no repository was found in our system. <br />
    Please ask an administrator or an project manager to add you to the required
    repository.
    <div *ngIf="userService.user">
      <br /><br />
      Please give the administrator or project manager your username: <br />
      <button
        id="username"
        mat-button
        [cdkCopyToClipboard]="userService.user.name"
      >
        {{ userService.user.name }}
        &nbsp;<mat-icon>content_copy</mat-icon>
      </button>
    </div>
  </mat-card>
</div>

frontend/src/app/home/no-repository/no-repository.component.css METASEP
.no-repository {
  font-size: 1.2em;
}

mat-card {
  width: fit-content;
  margin-left: auto;
  margin-right: auto;
  color: white;
  background-color: #dc3545;
}

#username {
  font-size: 1.2em !important;
}

frontend/src/app/footer/terms-conditions/terms-conditions.component.ts METASEP
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-terms-conditions',
  templateUrl: './terms-conditions.component.html',
  styleUrls: ['./terms-conditions.component.css']
})
export class TermsConditionsComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

}

frontend/src/app/footer/terms-conditions/terms-conditions.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { TermsConditionsComponent } from './terms-conditions.component';

describe('TermsConditionsComponent', () => {
  let component: TermsConditionsComponent;
  let fixture: ComponentFixture<TermsConditionsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ TermsConditionsComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(TermsConditionsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/footer/terms-conditions/terms-conditions.component.html METASEP
<h2 mat-dialog-title>Terms and Conditions</h2>
This is proof-of-concept, terms and conditions will appear here later
<mat-dialog-actions align="end">
  <button mat-button mat-dialog-close>Close</button>
</mat-dialog-actions>

frontend/src/app/footer/terms-conditions/terms-conditions.component.css METASEP

frontend/src/app/footer/legal/legal.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { environment } from 'src/environments/environment';

@Component({
  selector: 'app-legal',
  templateUrl: './legal.component.html',
  styleUrls: ['./legal.component.css'],
})
export class LegalComponent implements OnInit {
  imprint = environment.imprint;
  privacy = environment.privacy;

  constructor() {}

  ngOnInit(): void {}
}

frontend/src/app/footer/legal/legal.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { LegalComponent } from './legal.component';

describe('LegalComponent', () => {
  let component: LegalComponent;
  let fixture: ComponentFixture<LegalComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ LegalComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(LegalComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/footer/legal/legal.component.html METASEP
<div class="wrapper">
  <a id="tc" target="_blank" [href]="imprint">Imprint</a> &nbsp;
  <a id="tc" target="_blank" [href]="privacy">Privacy statement</a>
</div>

frontend/src/app/footer/legal/legal.component.css METASEP
.wrapper {
  text-align: center;
  margin-bottom: 10px;
}

.wrapper > a {
  text-decoration: none;
  color: var(--primary-color);
}

frontend/src/app/auth/local-storage/local-storage.service.ts METASEP
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class LocalStorageService {
  constructor() {}

  getValue(key: string): string {
    return localStorage.getItem(key) || '';
  }

  setValue(key: string, value: any) {
    localStorage.setItem(key, value);
  }
}

frontend/src/app/auth/local-storage/local-storage.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { LocalStorageService } from './local-storage.service';

describe('LocalStorageService', () => {
  let service: LocalStorageService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(LocalStorageService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/auth/http-response-interceptor/http-response.interceptor.ts METASEP
import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class HttpResponseInterceptor implements HttpInterceptor {

  constructor() {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    return next.handle(request);
  }
}

frontend/src/app/auth/http-response-interceptor/http-response.interceptor.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { HttpResponseInterceptor } from './http-response.interceptor';

describe('HttpResponseInterceptor', () => {
  beforeEach(() => TestBed.configureTestingModule({
    providers: [
      HttpResponseInterceptor
      ]
  }));

  it('should be created', () => {
    const interceptor: HttpResponseInterceptor = TestBed.inject(HttpResponseInterceptor);
    expect(interceptor).toBeTruthy();
  });
});

frontend/src/app/auth/http-interceptor/auth.interceptor.ts METASEP
import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpHeaders,
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { LocalStorageService } from '../local-storage/local-storage.service';
import { catchError, first, map, tap, switchMap } from 'rxjs/operators';
import { Router } from '@angular/router';
import {
  AuthService,
  RefreshTokenResponse,
} from 'src/app/services/auth/auth.service';
import { MatSnackBar } from '@angular/material/snack-bar';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor(
    private localStorageService: LocalStorageService,
    private router: Router,
    private authService: AuthService,
    private snackBar: MatSnackBar
  ) {}

  intercept(
    request: HttpRequest<unknown>,
    next: HttpHandler
  ): Observable<HttpEvent<unknown>> {
    const req = this.injectAccessToken(request);
    return next.handle(req).pipe(
      catchError((err) => {
        if (err.status === 401) {
          if (err.error.detail.err_code == 'token_exp') {
            return this.refreshToken().pipe(
              switchMap(() => {
                const req = this.injectAccessToken(request);
                return next.handle(req);
              }),
              catchError(() => {
                this.router.navigateByUrl('/logout?reason=session-expired');
                return throwError(err);
              })
            );
          } else {
            this.router.navigateByUrl('/logout?reason=unauthorized');
          }
        } else if (
          typeof err.error.detail !== 'undefined' &&
          err.error.detail.reason
        ) {
          this.snackBar.open(err.error.detail.reason, 'Ok!');
        } else if (err.status !== 404) {
          this.snackBar.open(
            'An unknown error occurred! If you encounter the problem again, please open an issue on Github!',
            'Ok!'
          );
        }

        return throwError(err);
      })
    );
  }

  injectAccessToken(request: HttpRequest<unknown>): HttpRequest<unknown> {
    let access_token = this.localStorageService.getValue('access_token');
    return request.clone({
      headers: new HttpHeaders({
        'Content-Type': 'application/json',
        Authorization: `Bearer ${access_token}`,
      }),
    });
  }

  refreshToken(): Observable<RefreshTokenResponse> {
    console.log('Token is expired. Refreshing token...');
    const refresh_token = this.localStorageService.getValue('refresh_token');

    return this.authService.refreshToken(refresh_token).pipe(
      map((res) => {
        this.localStorageService.setValue('access_token', res.access_token);
        this.localStorageService.setValue('refresh_token', res.refresh_token);
        return res;
      }, first())
    );
  }
}

frontend/src/app/auth/http-interceptor/auth.interceptor.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { AuthInterceptor } from './auth.interceptor';

describe('AuthInterceptor', () => {
  beforeEach(() =>
    TestBed.configureTestingModule({
      providers: [AuthInterceptor],
    })
  );

  it('should be created', () => {
    const interceptor: AuthInterceptor = TestBed.inject(AuthInterceptor);
    expect(interceptor).toBeTruthy();
  });
});

frontend/src/app/auth/auth/auth.component.ts METASEP
import {
  Component,
  Input,
  OnChanges,
  OnInit,
  SimpleChanges,
} from '@angular/core';
import { AuthService } from 'src/app/services/auth/auth.service';

@Component({
  selector: 'app-auth',
  templateUrl: './auth.component.html',
  styleUrls: ['./auth.component.css'],
})
export class AuthComponent implements OnInit {
  @Input()
  set autoLogin(value: boolean) {
    if (value) {
      this.webSSO();
    }
  }

  constructor(private authService: AuthService) {}

  ngOnInit(): void {}

  webSSO() {
    this.authService.getRedirectURL().subscribe((res) => {
      window.location.href = res.auth_url;
    });
  }
}

frontend/src/app/auth/auth/auth.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { AuthComponent } from './auth.component';

describe('AuthComponent', () => {
  let component: AuthComponent;
  let fixture: ComponentFixture<AuthComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ AuthComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(AuthComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/auth/auth/auth.component.html METASEP
<div class="center">
  <span id="welcome">Welcome to the</span>
  <h1>Capella Collaboration Manager</h1>
  <div id="description">
    This service enables co-working on Capella MBSE projects. <br />
    To continue to the service you need an invite from an existing user. <br />
    The service is currently operated in a proof-of-concept mode and does not
    allow for production work.
  </div>
  <div id="oauth-login">
    <button mat-flat-button color="primary" (click)="webSSO()">
      Login via OAuth2
    </button>
    <br />
  </div>
</div>

frontend/src/app/auth/auth/auth.component.css METASEP
.center {
  margin-top: 50px;
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}

button {
  margin-top: 10px;
}

.repository-selection {
  margin-top: 10px;
}

#description {
  margin: auto;
  text-align: left;
  max-width: 400px;
  margin-bottom: 20px;
}

frontend/src/app/auth/auth-redirect/auth-redirect.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AuthService } from 'src/app/services/auth/auth.service';
import { RepositoryService } from 'src/app/services/repository/repository.service';
import { UserService } from 'src/app/services/user/user.service';
import { LocalStorageService } from '../local-storage/local-storage.service';

@Component({
  selector: 'app-auth-redirect',
  templateUrl: './auth-redirect.component.html',
  styleUrls: ['./auth-redirect.component.css'],
})
export class AuthRedirectComponent implements OnInit {
  constructor(
    private route: ActivatedRoute,
    private authService: AuthService,
    private userService: UserService,
    private localStorageService: LocalStorageService,
    private router: Router,
    private repositoryService: RepositoryService
  ) {}

  ngOnInit(): void {
    this.route.queryParams.subscribe((params) => {
      this.authService
        .getAccessToken(params['code'], params['state'])
        .subscribe((res) => {
          this.localStorageService.setValue('access_token', res.access_token);
          this.localStorageService.setValue('refresh_token', res.refresh_token);

          this.userService.getAndSaveOwnUser();
          this.repositoryService.getAndSaveManagerRole();

          this.router.navigateByUrl('/');
        });
    });
  }
}

frontend/src/app/auth/auth-redirect/auth-redirect.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { AuthRedirectComponent } from './auth-redirect.component';

describe('AuthRedirectComponent', () => {
  let component: AuthRedirectComponent;
  let fixture: ComponentFixture<AuthRedirectComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [AuthRedirectComponent],
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(AuthRedirectComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/auth/auth-redirect/auth-redirect.component.html METASEP
Redirecting... This can take a few seconds.

frontend/src/app/auth/auth-redirect/auth-redirect.component.css METASEP

frontend/src/app/auth/auth-guard/auth-guard.service.ts METASEP
import { Injectable } from '@angular/core';
import {
  ActivatedRouteSnapshot,
  CanActivate,
  Router,
  RouterStateSnapshot,
  UrlTree,
} from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from 'src/app/services/auth/auth.service';
import { LocalStorageService } from '../local-storage/local-storage.service';

@Injectable({
  providedIn: 'root',
})
export class AuthGuardService implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    if (this.authService.isLoggedIn()) {
      return true;
    } else {
      this.router.navigateByUrl('/auth');
      return false;
    }
  }
}

frontend/src/app/auth/auth-guard/auth-guard.service.spec.ts METASEP
import { TestBed } from '@angular/core/testing';

import { AuthGuardService } from './auth-guard.service';

describe('AuthGuardService', () => {
  let service: AuthGuardService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(AuthGuardService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

frontend/src/app/active-sessions/reconnect-dialog/reconnect-dialog.component.ts METASEP
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Session } from 'src/app/schemes';

@Component({
  selector: 'app-reconnect-dialog',
  templateUrl: './reconnect-dialog.component.html',
  styleUrls: ['./reconnect-dialog.component.css'],
})
export class ReconnectDialogComponent implements OnInit {
  constructor(
    public dialogRef: MatDialogRef<ReconnectDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public session: Session
  ) {}

  ngOnInit(): void {}
}

frontend/src/app/active-sessions/reconnect-dialog/reconnect-dialog.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ReconnectDialogComponent } from './reconnect-dialog.component';

describe('ReconnectDialogComponent', () => {
  let component: ReconnectDialogComponent;
  let fixture: ComponentFixture<ReconnectDialogComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ ReconnectDialogComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(ReconnectDialogComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/active-sessions/reconnect-dialog/reconnect-dialog.component.html METASEP
<h1 mat-dialog-title>Reconnect to existing session</h1>
<div mat-dialog-content>
  <app-session-created [session]="session"></app-session-created>
</div>
<div mat-dialog-actions>
  <button mat-button (click)="this.dialogRef.close()">Close</button>
</div>

frontend/src/app/active-sessions/reconnect-dialog/reconnect-dialog.component.css METASEP

backend/t4cclient/extensions/backups/jenkins/config.xml METASEP
<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="workflow-job@2.40">
  <actions>
    <org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobAction plugin="pipeline-model-definition@1.7.2"/>
    <org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobPropertyTrackerAction plugin="pipeline-model-definition@1.7.2">
      <jobProperties/>
      <triggers/>
      <parameters/>
      <options/>
    </org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobPropertyTrackerAction>
  </actions>
  <description>&lt;p&gt;A pipeline to backup __T4C_PROJECT_NAME__ from the repository __T4C_REPO_NAME__.&lt;/p&gt;</description>
  <keepDependencies>false</keepDependencies>
  <properties>
    <jenkins.model.BuildDiscarderProperty>
      <strategy class="hudson.tasks.LogRotator">
        <daysToKeep>-1</daysToKeep>
        <numToKeep>10</numToKeep>
        <artifactDaysToKeep>-1</artifactDaysToKeep>
        <artifactNumToKeep>-1</artifactNumToKeep>
      </strategy>
    </jenkins.model.BuildDiscarderProperty>
    <org.jenkinsci.plugins.workflow.job.properties.DisableConcurrentBuildsJobProperty/>
    <com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty plugin="gitlab-plugin@1.5.13">
      <gitLabConnection>GitLab API</gitLabConnection>
    </com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty>
    <hudson.plugins.jira.JiraProjectProperty plugin="jira@3.1.3"/>
    <org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
      <triggers>
        <hudson.triggers.TimerTrigger>
          <spec>H 03 * * 1-5</spec>
        </hudson.triggers.TimerTrigger>
      </triggers>
    </org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty>
  </properties>
  <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@2.85">
    <script>import java.time.*

pipeline {
    agent any
    environment {
        // T4C
        def repoName = &quot;__T4C_REPO_NAME__&quot;
        def projectName = &quot;__T4C_PROJECT_NAME__&quot;
        def importCommitHistory = true
        // PROJECT
        def space = &quot;$env.WORKSPACE&quot;
        def importer = &quot;$space\\importer-workspace&quot;
        def database = &quot;$space\\database&quot;
        def logs = &quot;$space\\logs&quot;
        def wkp = &quot;$space\\wkp&quot;
        def lib = &quot;$space\\lib&quot;
        def rsynch = &quot;$lib\\rsync\\lib&quot;
        def smcpy = &quot;$lib\\smc\\lib&quot;
        def eclipse = &quot;$lib\\capella\\eclipse&quot;
        def aird = &quot;$wkp\\__MODEL_ENTRYPOINT__&quot;
        def history = &quot;$wkp\\CommitHistory.json&quot;
        // GIT
        def branch = &quot;__GIT_BRANCH__&quot;
        def credentialsId = &quot;__GIT_CREDENTIAL_ID__&quot;
        def email = &quot;__GIT_EMAIL__&quot;
        def username = &quot;__GIT_USERNAME__&quot;
        // BUILD STATUS
        def bstatus = 0
    }
    stages {
        stage(&quot;Initialization&quot;) {
            steps {
                bat &quot;if not exist \&quot;$importer\\\&quot; mkdir \&quot;$importer\&quot;&quot;
                bat &quot;if not exist \&quot;$logs\\\&quot; mkdir \&quot;$logs\&quot;&quot;
                bat &quot;if not exist \&quot;$wkp\\\&quot; mkdir \&quot;$wkp\&quot;&quot;
                bat &quot;if not exist \&quot;$database\\\&quot; mkdir \&quot;$database\&quot;&quot;
                bat &quot;if not exist \&quot;$lib\\\&quot; mkdir \&quot;$lib\&quot;&quot;
            }
        }
        stage(&quot;Checkout&quot;) {
            steps {
                dir(&quot;wkp&quot;) {
                    git branch: &quot;__GIT_BRANCH__&quot;, credentialsId: credentialsId, url: &quot;__GIT_MODEL_URL__&quot;
                }
                dir(&quot;lib&quot;) {
                    git branch: &quot;master&quot;, credentialsId: credentialsId, url: &quot;__JENKINS_SCRIPT_REPO_URL__&quot;
                }
            }
        }
        stage(&quot;T4C Import&quot;) {
            steps {
                dir(&quot;${env.TEAMFORCAPELLA_APP_HOME}/tools&quot;) {
                    bat &quot;call importer.bat &quot; +
                        &quot;-data \&quot;$importer\&quot; &quot; +
                        &quot;-outputFolder \&quot;$wkp\&quot; &quot; +
                        &quot;-logFolder \&quot;$logs\&quot; &quot; +
                        &quot;-archiveProject false &quot; +
                        &quot;-overrideExistingProject true &quot; +
                        &quot;-addTimestampToResultFiles false &quot; +
                        &quot;-closeserveronfailure false &quot; +
                        &quot;-checksize -1 &quot; +
                        &quot;-checksession false &quot; +
                        &quot;-importCommitHistoryAsJson $importCommitHistory &quot; +
                        &quot;-projectName $projectName &quot; +
                        &quot;-repoName $repoName&quot;
                }
                dir(&quot;$wkp&quot;) {
                    bat &quot;del CommitHistory.activitymetadata /s/q&quot;
                    bat &quot;xcopy \&quot;__T4C_PROJECT_NAME__\\.project\&quot; . /s/h/e/k/f/c/y&quot;
                    bat &quot;xcopy \&quot;__T4C_PROJECT_NAME__\\__T4C_PROJECT_NAME__.afm\&quot; . /s/h/e/k/f/c/y&quot;
                    bat &quot;xcopy \&quot;__T4C_PROJECT_NAME__\\__T4C_PROJECT_NAME__.aird\&quot; . /s/h/e/k/f/c/y&quot;
                    bat &quot;xcopy \&quot;__T4C_PROJECT_NAME__\\__T4C_PROJECT_NAME__.capella\&quot; . /s/h/e/k/f/c/y&quot;
                    bat &quot;rd \&quot;$wkp\\__T4C_PROJECT_NAME__\&quot; /s/q&quot;
                }
            }
        }
        stage(&quot;Git Backup&quot;) {
            steps {
                dir(&quot;$wkp&quot;) {
                    bat &quot;git config  --replace-all user.email $email&quot;
                    bat &quot;git config  --replace-all user.name $username&quot;
                    bat &quot;git add .&quot;
                    bat &quot;git reset -- script.sql&quot;
                }
                bat &quot;C:\\python\\venvs\\jupyter\\Scripts\\python.exe \&quot;$smcpy\\smc.py\&quot; &quot; +
                    &quot;--history \&quot;$history\&quot; &quot; +
                    &quot;--repo \&quot;$wkp\&quot; &quot; +
                    &quot;--branch \&quot;$branch\&quot;&quot;
                dir(&quot;$wkp&quot;) {
                    withCredentials([usernamePassword(credentialsId: &quot;af231c4f-57af-4b0b-97e7-95498af9c0cf&quot;, usernameVariable: &quot;USER&quot;, passwordVariable: &quot;PASS&quot;)]) {
                        bat &quot;git push __GIT_URL_WITH_CREDENTIALS_ENV__&quot;
                    }
                }
            }
        }
        stage(&quot;T4C Export&quot;) {
            steps {
                bat &quot;echo skip&quot;
            }
        }
    }
}
</script>
    <sandbox>true</sandbox>
  </definition>
  <triggers/>
  <disabled>false</disabled>
</flow-definition>

backend/t4cclient/extensions/modelsources/t4c/routes.py METASEP
import typing as t

import t4cclient.core.database as database
import t4cclient.extensions.modelsources.t4c.crud as database_projects
import t4cclient.schemas.repositories.projects as schema_projects
from fastapi import APIRouter, Depends
from requests import Session
from t4cclient.core.oauth.database import verify_admin, verify_repository_role
from t4cclient.core.oauth.jwt_bearer import JWTBearer
from t4cclient.routes.open_api_configuration import AUTHENTICATION_RESPONSES

router = APIRouter()


@router.get(
    "/",
    response_model=t.List[schema_projects.RepositoryProject],
    responses=AUTHENTICATION_RESPONSES,
)
def get_projects_for_repository(
    project: str,
    db: Session = Depends(database.get_db),
    token=Depends(JWTBearer()),
):
    verify_repository_role(
        project, allowed_roles=["manager", "administrator"], token=token, db=db
    )
    db_models = database_projects.get_all_projects(db, project)
    return db_models


@router.post(
    "/",
    response_model=schema_projects.RepositoryProject,
    responses=AUTHENTICATION_RESPONSES,
)
def create_project_in_repository(
    project: str,
    body: schema_projects.RepositoryProjectBase,
    db: Session = Depends(database.get_db),
    token=Depends(JWTBearer()),
):
    verify_repository_role(
        project, allowed_roles=["manager", "administrator"], token=token, db=db
    )
    return database_projects.create_project(db, project, body.name)


@router.delete(
    "/{project_id}",
    status_code=204,
    responses=AUTHENTICATION_RESPONSES,
)
def delete_project_from_repository(
    project: str,
    project_id: int,
    db: Session = Depends(database.get_db),
    token=Depends(JWTBearer()),
):
    verify_admin(token, db)
    return database_projects.delete_project(
        db,
        id=project_id,
        repo_name=project,
    )

backend/t4cclient/extensions/modelsources/t4c/models.py METASEP
from sqlalchemy import Boolean, Column, Enum, ForeignKey, Integer, String, Table
from sqlalchemy.orm import relationship
from t4cclient.core.database import Base


class DatabaseProject(Base):
    __tablename__ = "projects"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)
    repository_name = Column(
        String, ForeignKey("repositories.name", ondelete="CASCADE")
    )
    repository = relationship("DatabaseRepository", back_populates="projects")

backend/t4cclient/extensions/modelsources/t4c/crud.py METASEP
from sqlalchemy.orm import Session
from t4cclient.extensions.modelsources.t4c.models import DatabaseProject


def get_project(db: Session, name: str, repo_name: str):
    return (
        db.query(DatabaseProject)
        .filter(DatabaseProject.name == name)
        .filter(DatabaseProject.repository_name == repo_name)
        .first()
    )


def get_project_by_id(db: Session, id: int, repo_name: str):
    return (
        db.query(DatabaseProject)
        .filter(DatabaseProject.id == id)
        .filter(DatabaseProject.repository_name == repo_name)
        .first()
    )


def get_all_projects(db: Session, repo_name: str):
    return (
        db.query(DatabaseProject)
        .filter(DatabaseProject.repository_name == repo_name)
        .all()
    )


def create_project(db: Session, repo_name: str, project_name: str):
    project = DatabaseProject(repository_name=repo_name, name=project_name)
    db.add(project)
    db.commit()
    db.refresh(project)
    return project


def delete_project(db: Session, id: int, repo_name: str):
    db.query(DatabaseProject).filter(DatabaseProject.id == id).filter(
        DatabaseProject.repository_name == repo_name
    ).delete()
    db.commit()

backend/t4cclient/extensions/modelsources/t4c/connection.py METASEP
import json
import logging
import typing as t
from socket import timeout

import requests
from requests.auth import HTTPBasicAuth
from t4cclient import config
from t4cclient.core.credentials import generate_password

log = logging.getLogger(__name__)

T4C_BACKEND_AUTHENTICATION = HTTPBasicAuth(
    config.T4C_SERVER_USERNAME, config.T4C_SERVER_PASSWORD
)


def get_t4c_status():
    try:
        log.debug("Fetch T4C status")
        r = requests.get(
            config.T4C_USAGE_API + "/status/json",
            auth=T4C_BACKEND_AUTHENTICATION,
            timeout=config.REQUESTS_TIMEOUT,
        )
    except requests.exceptions.Timeout:
        log.info("License server timeout", exc_info=True)
        return {"free": -1, "total": -1, "used": [], "errors": ["TIMEOUT"]}
    except requests.exceptions.ConnectionError:
        log.info("License server timeout", exc_info=True)
        return {"free": -1, "total": -1, "used": [], "errors": ["CONNECTION_ERROR"]}

    # This API endpoints returns 404 on success -> We have to handle the errors here manually
    if r.status_code != 404 and not r.ok:
        log.error(
            "Licence server returned status code %s: %s",
            r.status_code,
            r.content.decode("ascii"),
        )
        return {"free": -1, "total": -1, "used": [], "errors": ["T4C_ERROR"]}

    try:
        status = r.json()["status"]

        if status.get("message", "") == "No last status available.":
            return {"free": -1, "total": -1, "used": [], "errors": ["NO_STATUS"]}

        if "used" in status:
            return status
    except KeyError:
        log.exception("No status available")
        log.info("Response from T4C is %s", r.content.decode("ascii"))
        return {"free": -1, "total": -1, "used": [], "errors": ["NO_STATUS_JSON"]}
    except json.JSONDecodeError:
        log.exception("Cannot decode T4C status")
        log.info("Response from T4C is %s", r.content.decode("ascii"))
        return {"free": -1, "total": -1, "used": [], "errors": ["DECODE_ERROR"]}

    return {"free": -1, "total": -1, "used": [], "errors": ["UNKNOWN_ERROR"]}


def fetch_last_seen(mac_addr: str):
    try:
        status = get_t4c_status()
        if "errors" in status:
            return str(status["errors"][0])
        list_with_mac = [
            user["lastSeen"]
            for user in get_t4c_status()["used"]
            if user["user"] == mac_addr.upper().replace(":", "-")
        ]
        if list_with_mac:
            return list_with_mac[0]
        return "No T4C Session found"
    except Exception:
        log.exception("Unexpected exception")
        return "UNKNOWN_ERROR"


def add_user_to_repository(
    repository: str, username: str, password: str = generate_password()
):
    r = requests.post(
        config.T4C_REST_API + "/users",
        params={"repositoryName": repository},
        json={
            "id": username,
            "isAdmin": False,
            "password": password,
        },
        auth=T4C_BACKEND_AUTHENTICATION,
        timeout=config.REQUESTS_TIMEOUT,
    )

    # No exception if user does already exist (status_code 400)
    if not r.ok and r.status_code != 400:
        raise requests.HTTPError(r)
    return r.json()


def remove_user_from_repository(repository: str, username: str):
    r = requests.delete(
        config.T4C_REST_API + "/users/" + username,
        params={"repositoryName": repository},
        auth=T4C_BACKEND_AUTHENTICATION,
        timeout=config.REQUESTS_TIMEOUT,
    )
    # No exception if user does not exist (status_code 404)
    if not r.ok and r.status_code != 404:
        raise requests.HTTPError(r)


def update_password_of_user(repository: str, username: str, password: str):
    r = requests.put(
        config.T4C_REST_API + "/users/" + username,
        params={"repositoryName": repository},
        json={
            "id": username,
            "isAdmin": False,
            "password": password,
        },
        auth=T4C_BACKEND_AUTHENTICATION,
        timeout=config.REQUESTS_TIMEOUT,
    )
    r.raise_for_status()
    return r.json()


def get_repositories() -> t.List[str]:
    r = requests.get(
        config.T4C_REST_API + "/repositories",
        auth=T4C_BACKEND_AUTHENTICATION,
        timeout=config.REQUESTS_TIMEOUT,
    )
    r.raise_for_status()

    return [repo["name"] for repo in r.json()["repositories"]]


def create_repository(name: str) -> None:
    r = requests.post(
        config.T4C_REST_API + "/repositories",
        json={
            "repositoryName": name,
            "authenticationType": "FILE",
            "authenticationData": {
                "users": [{"login": "admin", "password": generate_password()}]
            },
            "datasourceType": "H2_EMBEDDED",
        },
        auth=T4C_BACKEND_AUTHENTICATION,
        timeout=config.REQUESTS_TIMEOUT,
    )
    r.raise_for_status()

backend/t4cclient/extensions/modelsources/t4c/__init__.py METASEP
from . import connection, crud, models, routes

backend/t4cclient/extensions/modelsources/git/routes.py METASEP
import base64
import typing as t

from fastapi import APIRouter, Depends
from requests import Session
from t4cclient.core.database import get_db
from t4cclient.core.oauth.database import verify_repository_role
from t4cclient.core.oauth.database.git_models import verify_gitmodel_permission
from t4cclient.core.oauth.jwt_bearer import JWTBearer
from t4cclient.extensions.modelsources import git
from t4cclient.extensions.modelsources.git.models import (
    GetRepositoryGitModel,
    PatchRepositoryGitModel,
    PostGitModel,
    RepositoryGitInnerModel,
    RepositoryGitModel,
)
from t4cclient.routes.open_api_configuration import AUTHENTICATION_RESPONSES

router = APIRouter()


@router.get(
    "/",
    response_model=t.List[GetRepositoryGitModel],
    responses=AUTHENTICATION_RESPONSES,
)
def get_models_for_repository(
    project: str, db: Session = Depends(get_db), token=Depends(JWTBearer())
):
    verify_repository_role(project, token=token, db=db)
    db_models = git.crud.get_models_of_repository(db, project)
    return_models: t.List[GetRepositoryGitModel] = []
    for db_model in db_models:
        return_models.append(
            GetRepositoryGitModel(
                **db_model.__dict__,
                model=RepositoryGitInnerModel(**db_model.__dict__),
            )
        )
    return return_models


@router.post(
    "/", response_model=GetRepositoryGitModel, responses=AUTHENTICATION_RESPONSES
)
def assign_model_to_repository(
    project: str,
    body: PostGitModel,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    verify_repository_role(
        project, allowed_roles=["manager", "administrator"], token=token, db=db
    )
    body.model.path = base64.b64decode(body.model.path).decode("utf-8")
    db_model = git.crud.add_model_to_repository(db, project, body)
    return GetRepositoryGitModel(
        **db_model.__dict__,
        model=RepositoryGitInnerModel(**db_model.__dict__),
    )


@router.delete(
    "/{model_id}",
    status_code=204,
    responses=AUTHENTICATION_RESPONSES,
)
def unassign_model_from_repository(
    project: str,
    model_id: int,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    verify_repository_role(
        project, allowed_roles=["manager", "administrator"], token=token, db=db
    )
    verify_gitmodel_permission(project, model_id, db)
    return git.crud.delete_model_from_repository(db, project, model_id)


@router.patch(
    "/{model_id}",
    response_model=GetRepositoryGitModel,
    responses=AUTHENTICATION_RESPONSES,
)
def patch_model(
    project: str,
    body: PatchRepositoryGitModel,
    model_id: int,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    verify_repository_role(project, token=token, db=db)
    verify_gitmodel_permission(project, model_id, db)
    if body.primary is not None:
        db_model = git.crud.make_model_primary(db, project, model_id)
        return GetRepositoryGitModel(
            **db_model.__dict__,
            model=RepositoryGitInnerModel(**db_model.__dict__),
        )
    return None

backend/t4cclient/extensions/modelsources/git/models.py METASEP
import typing as t

from pydantic import BaseModel
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import relationship
from sqlalchemy.sql.schema import ForeignKey
from sqlalchemy.sql.sqltypes import Boolean
from t4cclient.core.database import Base


class RepositoryGitInnerModel(BaseModel):
    path: str
    entrypoint: str
    revision: str

    class Config:
        orm_mode = True


class RepositoryGitModel(BaseModel):
    name: str
    model: RepositoryGitInnerModel

    class Config:
        orm_mode = True


class PatchRepositoryGitModel(BaseModel):
    primary: t.Optional[bool]


class GetRepositoryGitModel(RepositoryGitModel):
    id: int
    primary: bool
    username: str | None


class GitCredentials(BaseModel):
    username: str | None
    password: str | None


class PostGitModel(RepositoryGitModel):
    credentials: GitCredentials


class DB_GitModel(Base):
    __tablename__ = "git_models"
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    name = Column(String)
    path = Column(String)
    entrypoint = Column(String)
    revision = Column(String)
    primary = Column(Boolean)
    repository_name = Column(
        String, ForeignKey("repositories.name", ondelete="CASCADE")
    )
    repository = relationship("DatabaseRepository", back_populates="git_models")
    username = Column(String)
    password = Column(String)

backend/t4cclient/extensions/modelsources/git/crud.py METASEP
import typing as t

from sqlalchemy.orm import Session
from t4cclient.extensions.modelsources.git.models import (
    DB_GitModel,
    PostGitModel,
    RepositoryGitModel,
)


def get_models_of_repository(db: Session, repository_name: str) -> t.List[DB_GitModel]:
    return (
        db.query(DB_GitModel)
        .filter(DB_GitModel.repository_name == repository_name)
        .all()
    )


def get_primary_model_of_repository(db: Session, repository_name: str):
    return (
        db.query(DB_GitModel)
        .filter(DB_GitModel.repository_name == repository_name)
        .filter(DB_GitModel.primary == True)
        .first()
    )


def get_model_by_id(db: Session, repository_name: str, model_id: int) -> DB_GitModel:
    return (
        db.query(DB_GitModel)
        .filter(DB_GitModel.repository_name == repository_name)
        .filter(DB_GitModel.id == model_id)
        .first()
    )


def make_model_primary(db: Session, repository_name: str, model_id: int) -> DB_GitModel:
    primary_model = get_primary_model_of_repository(db, repository_name)
    if primary_model:
        primary_model.primary = False
        db.add(primary_model)

    new_primary_model = get_model_by_id(db, repository_name, model_id)
    new_primary_model.primary = True

    db.add(new_primary_model)
    db.commit()
    db.refresh(new_primary_model)
    return new_primary_model


def add_model_to_repository(db: Session, repository_name: str, model: PostGitModel):
    if len(get_models_of_repository(db, repository_name)):
        primary = False
    else:
        primary = True

    model = DB_GitModel(
        repository_name=repository_name,
        **model.model.dict(),
        name=model.name,
        primary=primary,
        username=model.credentials.username,
        password=model.credentials.password
    )
    db.add(model)
    db.commit()
    db.refresh(model)
    return model


def delete_model_from_repository(db: Session, repository_name: str, model_id: int):
    db.query(DB_GitModel).filter(DB_GitModel.id == model_id).filter(
        DB_GitModel.repository_name == repository_name
    ).delete()
    db.commit()

backend/t4cclient/extensions/modelsources/git/__init__.py METASEP
from . import crud, models, routes

backend/t4cclient/extensions/backups/jenkins/routes.py METASEP
import typing as t
from os import path

import fastapi
import t4cclient.extensions.backups.jenkins.models as jenkins_schema
from fastapi import APIRouter, Depends
from requests import Session
from t4cclient.core.database import get_db
from t4cclient.core.oauth.database import verify_repository_role
from t4cclient.core.oauth.database.git_models import verify_gitmodel_permission
from t4cclient.core.oauth.database.jenkins import verify_jenkins_permission
from t4cclient.core.oauth.jwt_bearer import JWTBearer
from t4cclient.extensions.backups import jenkins
from t4cclient.routes.open_api_configuration import AUTHENTICATION_RESPONSES

from . import crud as jenkins_database

router = APIRouter()


@router.get(
    "/",
    response_model=jenkins_schema.JenkinsPipeline,
    responses=AUTHENTICATION_RESPONSES,
)
def get_jenkins_pipeline(
    repository_name: str,
    model_id: int,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    verify_repository_role(
        repository_name, token=token, db=db, allowed_roles=["manager", "administrator"]
    )
    verify_gitmodel_permission(repository_name, model_id, db)
    db_pipeline = jenkins_database.get_pipeline_of_model(db, model_id)
    if not db_pipeline:
        raise fastapi.HTTPException(
            status_code=404,
            detail="This Git Model has no linked Jenkins Pipeline.",
        )

    latest_run = jenkins.get_pipeline(db, db_pipeline.name)
    pipeline = jenkins_schema.JenkinsPipeline(
        **db_pipeline.__dict__, latest_run=latest_run
    )
    return pipeline


@router.post(
    "/",
    response_model=jenkins_schema.JenkinsPipeline,
    responses=AUTHENTICATION_RESPONSES,
)
def create_jenkins_pipeline(
    repository_name: str,
    model_id: int,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    verify_repository_role(
        repository_name, allowed_roles=["manager", "administrator"], token=token, db=db
    )
    verify_gitmodel_permission(repository_name, model_id, db)
    jenkins.create_pipeline(db, repository_name, model_id)
    pipeline = jenkins_database.add_pipeline(
        db, git_model_id=model_id, name="backup-job-" + str(model_id)
    )
    return pipeline


@router.delete(
    "/{pipeline_name}",
    status_code=204,
    responses=AUTHENTICATION_RESPONSES,
)
def delete_pipeline(
    repository_name: str,
    pipeline_name: str,
    model_id: int,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    verify_repository_role(
        repository_name, allowed_roles=["manager", "administrator"], token=token, db=db
    )
    verify_jenkins_permission(
        repository=repository_name,
        pipeline_name=pipeline_name,
        git_model_id=model_id,
        db=db,
    )
    jenkins.remove_pipeline(pipeline_name)
    return jenkins_database.remove_pipeline_by_name(db, pipeline_name)


@router.post(
    "/{pipeline_name}/jobs",
    status_code=204,
    responses=AUTHENTICATION_RESPONSES,
)
def create_jenkins_job(
    repository_name: str,
    model_id: int,
    pipeline_name: str,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    verify_repository_role(
        repository_name, allowed_roles=["manager", "administrator"], token=token, db=db
    )
    verify_jenkins_permission(
        repository=repository_name,
        pipeline_name=pipeline_name,
        git_model_id=model_id,
        db=db,
    )
    jenkins.trigger_job_run(pipeline_name)

backend/t4cclient/extensions/backups/jenkins/models.py METASEP
import typing as t

from pydantic import BaseModel
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import relationship
from sqlalchemy.sql.schema import ForeignKey
from sqlalchemy.sql.sqltypes import Boolean
from t4cclient.core.database import Base


class CreateJenkinsJob(BaseModel):
    name: str

    class Config:
        orm_mode = True


class JenkinsRun(BaseModel):
    id: int
    result: str
    start_time: str
    logs_url: str

    class Config:
        orm_mode = True


class JenkinsPipeline(CreateJenkinsJob):
    id: int
    latest_run: t.Optional[JenkinsRun]


class DatabaseJenkinsPipeline(Base):
    __tablename__ = "jenkins"
    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    name = Column(String)
    git_model_id = Column(
        Integer, ForeignKey("git_models.id", ondelete="CASCADE"), primary_key=True
    )
    git_model = relationship(
        "DB_GitModel",
    )

backend/t4cclient/extensions/backups/jenkins/crud.py METASEP
import t4cclient.extensions.backups.jenkins.models as jenkins_schema
from sqlalchemy.orm import Session


def get_pipeline_of_model(
    db: Session, git_model_id: int
) -> jenkins_schema.DatabaseJenkinsPipeline:
    return (
        db.query(jenkins_schema.DatabaseJenkinsPipeline)
        .filter(jenkins_schema.DatabaseJenkinsPipeline.git_model_id == git_model_id)
        .first()
    )


def add_pipeline(
    db: Session, git_model_id: int, name: str
) -> jenkins_schema.DatabaseJenkinsPipeline:
    pipeline = jenkins_schema.DatabaseJenkinsPipeline(
        name=name, git_model_id=git_model_id
    )
    db.add(pipeline)
    db.commit()
    db.refresh(pipeline)
    return pipeline


def remove_pipeline(db: Session, id: int):
    db.query(jenkins_schema.DatabaseJenkinsPipeline).filter(
        jenkins_schema.DatabaseJenkinsPipeline.id == id
    ).delete()
    db.commit()


def remove_pipeline_by_name(db: Session, name: str):
    db.query(jenkins_schema.DatabaseJenkinsPipeline).filter(
        jenkins_schema.DatabaseJenkinsPipeline.name == name
    ).delete()
    db.commit()


def remove_pipeline_by_model_id(db: Session, model_id: str):
    db.query(jenkins_schema.DatabaseJenkinsPipeline).filter(
        jenkins_schema.DatabaseJenkinsPipeline.git_model_id == model_id
    ).delete()
    db.commit()

backend/t4cclient/extensions/backups/jenkins/__init__.py METASEP
import pathlib
import re

import dateutil.parser
import fastapi
import requests
import sqlalchemy.orm
import t4cclient.extensions.backups.jenkins as crud_jenkins
import t4cclient.extensions.modelsources.git.crud as crud_git_models
import t4cclient.extensions.modelsources.git.models as database_git_models
from t4cclient import config

from . import crud, models, routes

JENKINS_AUTH = (config.JENKINS_USERNAME, config.JENKINS_PASSWORD)


def load_pipeline_config(git_model: database_git_models.DB_GitModel):
    MAP_CONFIG_ENV_TO_CONFIG = {
        "T4C_PROJECT_NAME": git_model.project.name,
        "T4C_REPO_NAME": git_model.repository_name,
        "MODEL_ENTRYPOINT": git_model.entrypoint,
        "GIT_BRANCH": git_model.revision,
        "GIT_CREDENTIAL_ID": config.JENKINS_GIT_CREDENTIAL_ID,
        "GIT_USERNAME": config.JENKINS_GIT_USERNAME,
        "GIT_EMAIL": config.JENKINS_GIT_EMAIL,
        "GIT_MODEL_URL": git_model.path,
        "JENKINS_SCRIPT_REPO_URL": config.JENKINS_GIT_SCRIPT_REPO_URL,
        "GIT_URL_WITH_CREDENTIALS_ENV": git_model.path.replace("//", "//$USER:$PASS@"),
    }
    filecontent = (pathlib.Path(__file__).parent / "config.xml").read_text()
    pattern = r"__([A-Z0-9]*(?:_[A-Z0-9]+)*)__"
    for match in re.findall(pattern, filecontent):
        filecontent = filecontent.replace(
            f"__{match}__", MAP_CONFIG_ENV_TO_CONFIG[match]
        )
    return filecontent


def post_pipelines_to_jenkins(filecontent: str, pipeline_name: str):
    res = requests.post(
        config.JENKINS_BASE_URL + "/createItem?name=" + pipeline_name,
        data=filecontent,
        auth=JENKINS_AUTH,
        headers={
            "Content-Type": "text/xml",
        },
        timeout=config.REQUESTS_TIMEOUT,
    )
    res.raise_for_status()


def create_pipeline(
    db: sqlalchemy.orm.Session, repository_name: str, git_model_id: int
):
    git_model = crud_git_models.get_model_by_id(db, repository_name, git_model_id)

    filecontent = load_pipeline_config(git_model)
    post_pipelines_to_jenkins(filecontent, "backup-job-" + str(git_model_id))


def get_pipeline(db: sqlalchemy.orm.Session, pipeline_name: str):
    res = requests.get(
        config.JENKINS_BASE_URL
        + "/blue/rest/organizations/jenkins/pipelines/"
        + pipeline_name
        + "/runs",
        auth=JENKINS_AUTH,
        timeout=config.REQUESTS_TIMEOUT,
    )
    if res.status_code == 404:
        crud_jenkins.remove_pipeline_by_name(db, pipeline_name)
        raise fastapi.HTTPException(
            status_code=401,
            detail="The pipeline existed in our system, but not at the Jenkins instance. "
            + "This can happen if Jenkins Pipelines are deleted manually. "
            + "Our database has been updated.",
        )
    res.raise_for_status()

    try:
        latest_pipeline = res.json()[0]
        return {
            "id": latest_pipeline["id"],
            "start_time": dateutil.parser.isoparse(
                latest_pipeline["startTime"]
            ).strftime("%Y-%m-%d %H:%M"),
            "result": latest_pipeline["result"],
            "logs_url": config.JENKINS_BASE_URL
            + "/job/"
            + pipeline_name
            + "/"
            + latest_pipeline["id"]
            + "/console",
        }
    except IndexError:
        return None


def trigger_job_run(pipeline_name: str):
    requests.post(
        config.JENKINS_BASE_URL + "/job/" + pipeline_name + "/build?delay=0sec",
        auth=JENKINS_AUTH,
        timeout=config.REQUESTS_TIMEOUT,
    ).raise_for_status()


def remove_pipeline(pipeline_name: str):
    requests.post(
        config.JENKINS_BASE_URL + "/job/" + pipeline_name + "/doDelete",
        auth=JENKINS_AUTH,
        timeout=config.REQUESTS_TIMEOUT,
    ).raise_for_status()

backend/t4cclient/extensions/backups/ease/routes.py METASEP
import typing as t
import uuid

import t4cclient.core.oauth.database as auth
from fastapi import APIRouter, Depends
from requests import Session
from t4cclient import config, extensions
from t4cclient.core import credentials
from t4cclient.core.database import get_db
from t4cclient.core.oauth.jwt_bearer import JWTBearer
from t4cclient.core.operators import OPERATOR
from t4cclient.extensions.modelsources import git, t4c
from t4cclient.routes.open_api_configuration import AUTHENTICATION_RESPONSES

from . import crud, helper, models

router = APIRouter()


@router.get(
    "/",
    response_model=t.List[models.EASEBackupResponse],
    responses=AUTHENTICATION_RESPONSES,
)
def get_ease_backups(
    project: str,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    auth.verify_repository_role(
        project, allowed_roles=["manager", "administrator"], token=token, db=db
    )
    return [
        helper._inject_last_run(backup)
        for backup in crud.get_backups(db=db, project=project)
    ]


@router.post(
    "/", response_model=models.EASEBackupResponse, responses=AUTHENTICATION_RESPONSES
)
def create_backup(
    project: str,
    body: models.EASEBackupRequest,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    auth.verify_repository_role(
        project, allowed_roles=["manager", "administrator"], token=token, db=db
    )

    gitmodel = git.crud.get_model_by_id(
        db=db, repository_name=project, model_id=body.gitmodel
    )

    t4cmodel = t4c.crud.get_project_by_id(db=db, id=body.t4cmodel, repo_name=project)

    username = "techuser-" + str(uuid.uuid4())
    password = credentials.generate_password()
    # t4c.connection.add_user_to_repository(project, username, password)

    reference = OPERATOR.create_cronjob(
        image=config.EASE_IMAGE,
        environment={
            "EASE_LOG_LOCATION": "/proc/1/fd/1",
            "GIT_REPO_URL": gitmodel.path,
            "GIT_REPO_BRANCH": gitmodel.revision,
            "T4C_REPO_HOST": config.T4C_SERVER_HOST,
            "T4C_REPO_PORT": config.T4C_SERVER_PORT,
            "T4C_REPO_NAME": t4cmodel.name,
            "T4C_USERNAME": username,
            "T4C_PASSWORD": password,
            "GIT_USERNAME": gitmodel.username,
            "GIT_PASSWORD": gitmodel.password,
        },
        schedule="0 3 * * *"
    )

    return helper._inject_last_run(
        crud.create_backup(
            db=db,
            backup=models.DB_EASEBackup(
                project=project, **body.dict(), reference=reference, username=username
            ),
        )
    )


@router.delete(
    "/{id}",
    status_code=204,
    responses=AUTHENTICATION_RESPONSES,
)
def delete_backup(
    project: str, id: int, db: Session = Depends(get_db), token=Depends(JWTBearer())
):
    auth.verify_repository_role(
        project, allowed_roles=["manager", "administrator"], token=token, db=db
    )

    backup = crud.get_backup(db, project, id)
    t4cmodel = t4c.crud.get_project_by_id(db=db, id=backup.t4cmodel, repo_name=project)
    # t4c.connection.remove_user_from_repository(t4cmodel.name, backup.username)

    OPERATOR.delete_cronjob(backup.reference)

    crud.delete_backup(db, project, id)


@router.post(
    "/{id}/jobs",
    response_model=models.EASEBackupResponse,
    responses=AUTHENTICATION_RESPONSES,
)
def create_backup(
    project: str,
    id: int,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    auth.verify_repository_role(
        project, allowed_roles=["manager", "administrator"], token=token, db=db
    )

    backup = crud.get_backup(db=db, project=project, id=id)

    OPERATOR.trigger_cronjob(name=backup.reference)


@router.get(
    "/{bid}/jobs/{jid}/logs",
    response_model=str,
    responses=AUTHENTICATION_RESPONSES,
)
def create_backup(
    project: str,
    bid: int,
    jid: str,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    auth.verify_repository_role(
        project, allowed_roles=["manager", "administrator"], token=token, db=db
    )
    # TODO: Check if jid is part of bid

    return OPERATOR.get_job_logs(id=jid)

backend/t4cclient/extensions/backups/ease/models.py METASEP
from datetime import datetime

from pydantic import BaseModel
from sqlalchemy import Column, ForeignKey, Integer, String
from t4cclient.core.database import Base


class EASEBackupRequest(BaseModel):
    gitmodel: int
    t4cmodel: int

    class Config:
        orm_mode = True


class EASEBackupJob(BaseModel):
    id: str | None
    date: datetime | None
    state: str


class EASEBackupResponse(EASEBackupRequest):
    id: int
    lastrun: EASEBackupJob

    class Config:
        orm_mode = True


class DB_EASEBackup(Base):
    __tablename__ = "EASEBackup"

    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    reference = Column(String)
    gitmodel = Column(Integer, ForeignKey("git_models.id"))
    t4cmodel = Column(Integer, ForeignKey("projects.id"))
    username = Column(String)
    project = Column(
        String,
        ForeignKey("repositories.name"),
        primary_key=True,
    )

backend/t4cclient/extensions/backups/ease/helper.py METASEP
from t4cclient.core.operators import OPERATOR

from . import models


def _inject_last_run(model: models.DB_EASEBackup) -> models.EASEBackupResponse:
    backup_job = models.EASEBackupJob(
        id=OPERATOR.get_cronjob_last_run(model.reference),
        date=OPERATOR.get_cronjob_last_starting_date(model.reference),
        state=OPERATOR.get_cronjob_last_state(model.reference),
    )
    return models.EASEBackupResponse(
        gitmodel=model.gitmodel,
        t4cmodel=model.t4cmodel,
        id=model.id,
        lastrun=backup_job,
    )

backend/t4cclient/extensions/backups/ease/crud.py METASEP
import typing as t

from sqlalchemy.orm import Session

from . import models


def get_backup(db: Session, project: str, id: int):
    return (
        db.query(models.DB_EASEBackup)
        .filter(models.DB_EASEBackup.id == id)
        .filter(models.DB_EASEBackup.project == project)
        .first()
    )


def get_backups(db: Session, project: str) -> t.List[models.DB_EASEBackup]:
    return (
        db.query(models.DB_EASEBackup)
        .filter(models.DB_EASEBackup.project == project)
        .all()
    )


def create_backup(db: Session, backup: models.DB_EASEBackup):
    db.add(backup)
    db.commit()
    db.refresh(backup)
    return backup


def delete_backup(db: Session, project: str, id: int):
    db.query(models.DB_EASEBackup).filter(models.DB_EASEBackup.id == id).filter(
        models.DB_EASEBackup.project == project
    ).delete()
    db.commit()

backend/t4cclient/extensions/backups/ease/__init__.py METASEP
from . import crud, models, routes

backend/t4cclient/core/oauth/database/jenkins.py METASEP
from fastapi import Depends, HTTPException
from t4cclient.core.database import get_db
from t4cclient.extensions.backups import jenkins

from . import git_models as git_models_auth


def verify_jenkins_permission(
    repository: str, pipeline_name: str, git_model_id: int, db
):
    git_models_auth.verify_gitmodel_permission(repository, git_model_id, db)
    if jenkins.crud.get_pipeline_of_model(db, git_model_id).name != pipeline_name:
        raise HTTPException(
            status_code=403,
            detail="The Pipeline Name does not match with the connected Git Model!",
        )

backend/t4cclient/core/oauth/database/git_models.py METASEP
import t4cclient.extensions.modelsources.git.crud as crud_git_models
from fastapi import Depends, HTTPException
from t4cclient.core.database import get_db


def verify_gitmodel_permission(repository: str, git_model_id: int, db):
    if (
        crud_git_models.get_model_by_id(db, repository, git_model_id).repository_name
        != repository
    ):
        raise HTTPException(
            status_code=403,
            detail="The Git Model is not part of the specified repository!",
        )

backend/t4cclient/core/oauth/database/__init__.py METASEP
from fastapi import Depends, HTTPException
from sqlalchemy import true
from t4cclient.config import USERNAME_CLAIM
from t4cclient.core.database import get_db, repository_users
from t4cclient.core.database.users import get_user
from t4cclient.core.oauth.jwt_bearer import JWTBearer
from t4cclient.schemas.repositories import RepositoryUserPermission, RepositoryUserRole
from t4cclient.schemas.repositories.users import Role


def verify_admin(token=Depends(JWTBearer()), db=Depends(get_db)):
    if not is_admin(token, db):
        raise HTTPException(
            status_code=403,
            detail="The role administrator is required for this transaction.",
        )


def is_admin(token=Depends(JWTBearer()), db=Depends(get_db)) -> bool:
    return get_user(db=db, username=token[USERNAME_CLAIM]).role == Role.ADMIN


def verify_repository_role(
    repository: str,
    allowed_roles=["user", "manager", "administrator"],
    token=Depends(JWTBearer()),
    db=Depends(get_db),
):
    if not check_repository_role(repository, allowed_roles, token, db):
        raise HTTPException(
            status_code=403,
            detail=f"One of the roles '{allowed_roles}' in the repository '{repository}' is required.",
        )


def check_repository_role(
    repository: str,
    allowed_roles=["user", "manager", "administrator"],
    token=Depends(JWTBearer()),
    db=Depends(get_db),
) -> bool:

    user = get_user(db=db, username=token[USERNAME_CLAIM])
    return any(
        (
            "user" in allowed_roles
            and any(repo.repository_name == repository for repo in user.repositories),
            "manager" in allowed_roles
            and any(
                r.repository_name == repository and r.role == RepositoryUserRole.MANAGER
                for r in user.repositories
            ),
            "administrator" in allowed_roles and user.role == Role.ADMIN,
        )
    )


def check_username_not_admin(username: str, db):
    if get_user(db=db, username=username).role == Role.ADMIN:
        raise HTTPException(
            status_code=403,
            detail="You are not allowed to edit this user.",
        )


def verify_write_permission(
    repository: str,
    token=Depends(JWTBearer()),
    db=Depends(get_db),
):
    if not check_write_permission(repository, token, db):
        raise HTTPException(
            status_code=403,
            detail=f"You need to have 'Write'-Access in the repository!",
        )


def check_write_permission(
    repository: str,
    token=Depends(JWTBearer()),
    db=Depends(get_db),
) -> bool:

    user = repository_users.get_user_of_repository(db, repository, token[USERNAME_CLAIM])
    if not user:
        return get_user(db=db, username=token[USERNAME_CLAIM]).role == Role.ADMIN
    return RepositoryUserPermission.WRITE == user.permission

frontend/src/app/workspace/workspace.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import {
  Repository,
  RepositoryService,
} from '../services/repository/repository.service';
import { SessionService } from '../services/session/session.service';

@Component({
  selector: 'app-workspace',
  templateUrl: './workspace.component.html',
  styleUrls: ['./workspace.component.css'],
})
export class WorkspaceComponent implements OnInit {
  repositories: Array<Repository> = [];
  showSpinner = true;

  constructor(
    public sessionService: SessionService,
    private repositoryService: RepositoryService
  ) {}

  ngOnInit() {
    this.showSpinner = true;
    this.repositoryService.getRepositories().subscribe(
      (res: Array<Repository>) => {
        this.repositories = res;
        this.showSpinner = false;
      },
      (err) => {
        this.showSpinner = false;
      }
    );
  }
}

frontend/src/app/workspace/workspace.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { WorkspaceComponent } from './workspace.component';

describe('WorkspaceComponent', () => {
  let component: WorkspaceComponent;
  let fixture: ComponentFixture<WorkspaceComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ WorkspaceComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(WorkspaceComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/workspace/workspace.component.html METASEP
<div class="center">
  <h1><b>Request Session</b></h1>
  <mat-spinner *ngIf="showSpinner"></mat-spinner>
  <app-no-repository
    *ngIf="!repositories.length && !showSpinner"
  ></app-no-repository>
  <app-request-session
    *ngIf="repositories.length"
    [repositories]="repositories"
  ></app-request-session>
</div>

frontend/src/app/workspace/workspace.component.css METASEP
.center {
  margin-top: 50px;
  text-align: center;
  margin-left: auto;
  margin-right: auto;
  display: inline;
}

button {
  margin-top: 10px;
}

.repository-selection {
  margin-top: 10px;
}

mat-spinner {
  margin-top: 70px;
  margin-left: auto;
  margin-right: auto;
}

frontend/src/app/validators/validators.ts METASEP
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';

export function lowerCaseValidator(): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    if (control.value != control.value.toLowerCase() && control.value) {
      return { lowerCaseError: true };
    }
    return null;
  };
}

frontend/src/app/settings/settings.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { RepositoryService } from '../services/repository/repository.service';
import { UserService } from '../services/user/user.service';

@Component({
  selector: 'app-settings',
  templateUrl: './settings.component.html',
  styleUrls: ['./settings.component.css'],
})
export class SettingsComponent implements OnInit {
  constructor(
    public userService: UserService,
    public repositoryService: RepositoryService
  ) {}

  ngOnInit(): void {
    this.userService
      .getUser(this.userService.getUsernameFromLocalStorage())
      .subscribe((res) => {
        this.userService.user = res;
      });
  }
}

frontend/src/app/settings/settings.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { SettingsComponent } from './settings.component';

describe('SettingsComponent', () => {
  let component: SettingsComponent;
  let fixture: ComponentFixture<SettingsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ SettingsComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(SettingsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/settings/settings.component.html METASEP
<app-admin-settings
  *ngIf="userService.user?.role === 'administrator'"
></app-admin-settings>
<app-repository-manager-settings
  *ngIf="
    repositoryService.isManager || userService.user?.role === 'administrator'
  "
></app-repository-manager-settings>
<app-user-settings></app-user-settings>

frontend/src/app/settings/settings.component.css METASEP

frontend/src/app/session-overview/session-overview.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { forkJoin } from 'rxjs';
import { DeleteSessionDialogComponent } from '../delete-session-dialog/delete-session-dialog.component';
import { Session, SessionsUsage } from '../schemes';
import { SessionService } from '../services/session/session.service';

@Component({
  selector: 'app-session-overview',
  templateUrl: './session-overview.component.html',
  styleUrls: ['./session-overview.component.css'],
})
export class SessionOverviewComponent implements OnInit {
  constructor(
    private sessionService: SessionService,
    private dialog: MatDialog
  ) {}

  sessions: Array<Session> = [];
  displayedColumns = [
    'id',
    'user',
    'repository',
    'ports',
    'created_at',
    'docker_state',
    'guacamole_user',
    'last_seen',
    'mac',
    'actions',
  ];

  ngOnInit(): void {
    this.refreshSessions();
  }

  refreshSessions() {
    this.sessionService
      .getCurrentSessions()
      .subscribe((res: Array<Session>) => {
        this.sessions = res;
      });
  }

  openDeletionDialog(sessions: Array<Session>): void {
    const dialogRef = this.dialog.open(DeleteSessionDialogComponent, {
      data: sessions,
    });

    dialogRef.afterClosed().subscribe((_) => {
      this.refreshSessions();
    });
  }
}

frontend/src/app/session-overview/session-overview.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { SessionOverviewComponent } from './session-overview.component';

describe('SessionOverviewComponent', () => {
  let component: SessionOverviewComponent;
  let fixture: ComponentFixture<SessionOverviewComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ SessionOverviewComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(SessionOverviewComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/session-overview/session-overview.component.html METASEP
<app-licences></app-licences>
<table mat-table [dataSource]="sessions" class="mat-elevation-z8">
  <ng-container matColumnDef="id">
    <th mat-header-cell *matHeaderCellDef>ID</th>
    <td mat-cell *matCellDef="let element">{{ element.id }}</td>
  </ng-container>

  <ng-container matColumnDef="user">
    <th mat-header-cell *matHeaderCellDef>Username</th>
    <td mat-cell *matCellDef="let element">{{ element.owner }}</td>
  </ng-container>

  <ng-container matColumnDef="repository">
    <th mat-header-cell *matHeaderCellDef>Repository</th>
    <td mat-cell *matCellDef="let element">{{ element.repository }}</td>
  </ng-container>

  <ng-container matColumnDef="ports">
    <th mat-header-cell *matHeaderCellDef>Ports</th>
    <td mat-cell *matCellDef="let element">{{ element.ports }}</td>
  </ng-container>

  <ng-container matColumnDef="created_at">
    <th mat-header-cell *matHeaderCellDef>Creation date</th>
    <td mat-cell *matCellDef="let element">{{ element.created_at }}</td>
  </ng-container>

  <ng-container matColumnDef="guacamole_user">
    <th mat-header-cell *matHeaderCellDef>Guacamole User</th>
    <td mat-cell *matCellDef="let element">{{ element.guacamole_username }}</td>
  </ng-container>

  <ng-container matColumnDef="docker_state">
    <th mat-header-cell *matHeaderCellDef>State of Container</th>
    <td mat-cell *matCellDef="let element">{{ element.state }}</td>
  </ng-container>

  <ng-container matColumnDef="last_seen">
    <th mat-header-cell *matHeaderCellDef>Last seen</th>
    <td mat-cell *matCellDef="let element">{{ element.last_seen }}</td>
  </ng-container>

  <ng-container matColumnDef="mac">
    <th mat-header-cell *matHeaderCellDef>MAC Address</th>
    <td mat-cell *matCellDef="let element">{{ element.mac }}</td>
  </ng-container>

  <ng-container matColumnDef="actions">
    <th mat-header-cell *matHeaderCellDef>Actions</th>
    <td mat-cell *matCellDef="let element">
      <button
        mat-flat-button
        color="primary"
        (click)="openDeletionDialog([element])"
      >
        <mat-icon>delete</mat-icon>
      </button>
    </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>

<button
  id="close-all-sessions"
  mat-flat-button
  color="primary"
  (click)="openDeletionDialog(sessions)"
>
  Close ALL Sessions
</button>

frontend/src/app/session-overview/session-overview.component.css METASEP
.mat-cell {
  padding: 8px 10px 8px 10px;
}

.mat-header-cell {
  padding: 8px 10px 8px 10px;
}

table {
  margin: 20px;
}

#close-all-sessions {
  margin-left: 20px;
}

frontend/src/app/session-creation-progress/session-creation-progress.component.ts METASEP
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { Subscription, timer } from 'rxjs';
import { map } from 'rxjs/operators';
import { Session } from '../schemes';
import { BeautifyService } from '../services/beatify/beautify.service';
import { OwnSessionService } from '../services/own-session/own-session.service';

@Component({
  selector: 'app-session-creation-progress',
  templateUrl: './session-creation-progress.component.html',
  styleUrls: ['./session-creation-progress.component.css'],
})
export class SessionCreationProgressComponent implements OnInit, OnDestroy {
  @Input()
  sessionType = '';

  @Input()
  session: Session | undefined = undefined;

  failure = false;

  refreshSessionsSubscription: Subscription;

  containerReady = false;

  constructor(
    private ownSessionService: OwnSessionService,
    public beautifyService: BeautifyService
  ) {
    this.refreshSessionsSubscription = timer(0, 2000)
      .pipe(
        map(() => {
          if (this.session !== undefined) {
            this.ownSessionService.refreshSessions().subscribe(
              (res: Array<Session>) => {
                const session = res.find(
                  (session: Session) => session.id === this.session?.id
                );

                if (session !== undefined) {
                  this.session = JSON.parse(JSON.stringify(session));
                }

                if (
                  this.session?.state === 'Running' ||
                  this.session?.state === 'START_SESSION'
                ) {
                  this.containerReady = true;
                  this.refreshSessionsSubscription.unsubscribe();
                }
              },
              (err) => {
                this.refreshSessionsSubscription.unsubscribe();
                this.failure = true;
              }
            );
          }
        })
      )
      .subscribe();
  }

  evaluateStep(step: string): string {
    const splittedState = this.session?.state.split('_');
    if (splittedState && splittedState.length >= 2) {
      const type = splittedState[0];
      const detectedStep = splittedState.slice(1).join('_');
      const stepOrder = [
        'INITIAL',
        'LOAD_MODEL',
        'PREPARE_WORKSPACE',
        'SESSION',
      ];
      if (stepOrder.indexOf(step) < stepOrder.indexOf(detectedStep)) {
        return 'success';
      } else if (step === detectedStep) {
        switch (type) {
          case 'START':
            return 'running';
          case 'FAILURE':
            this.refreshSessionsSubscription.unsubscribe();
            return 'error';
          case 'FINISH':
            return 'success';
          default:
            return 'error';
        }
      } else {
        return 'pending';
      }
    } else {
      if (step == 'INITIAL') {
        return 'running';
      } else {
        return 'pending';
      }
    }
  }

  ngOnInit(): void {}

  ngOnDestroy(): void {
    this.refreshSessionsSubscription.unsubscribe();
  }
}

frontend/src/app/session-creation-progress/session-creation-progress.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { SessionCreationProgressComponent } from './session-creation-progress.component';

describe('SessionCreationProgressComponent', () => {
  let component: SessionCreationProgressComponent;
  let fixture: ComponentFixture<SessionCreationProgressComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ SessionCreationProgressComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(SessionCreationProgressComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/session-creation-progress/session-creation-progress.component.html METASEP
<mat-card *ngIf="!containerReady">
  Thanks for requesting a session! Our scheduler will take of the request.
  <br />
  Depending on the demand, the creation can take a few minutes. <br />In most of
  the cases the session should be available within 30 seconds. <br />
  <b>You will be automatically redirected once the creation is successful!</b>
</mat-card>

<mat-card *ngIf="failure">
  An unknown error occured in our backend. <br />Please check the session state
  under "Active Sessions". <br />You may need to request a new session.
</mat-card>

<div *ngIf="session?.type == 'persistent' && !containerReady && !failure">
  The current state of your request is: <br />
  <mat-card
    class="session-state"
    [ngClass]="beautifyService.beatifyState(session?.state).css"
  >
    {{ beautifyService.beatifyState(session?.state).text }}
  </mat-card>
</div>

<div *ngIf="session?.type == 'readonly' && !containerReady && !failure">
  <ul>
    <li>
      <mat-card class="step">
        <app-session-progress-icon
          [state]="evaluateStep('INITIAL')"
        ></app-session-progress-icon>
        <span class="description">Allocation of Resources</span>
      </mat-card>
    </li>
    <li>
      <mat-card class="step">
        <app-session-progress-icon
          [state]="evaluateStep('LOAD_MODEL')"
        ></app-session-progress-icon>
        <span class="description">Pulling latest version of the model</span>
      </mat-card>
    </li>
    <li>
      <mat-card class="step">
        <app-session-progress-icon
          [state]="evaluateStep('PREPARE_WORKSPACE')"
        ></app-session-progress-icon>
        <span class="description">Preparing workspace</span>
      </mat-card>
    </li>
    <li>
      <mat-card class="step">
        <app-session-progress-icon
          [state]="evaluateStep('SESSION')"
        ></app-session-progress-icon>
        <span class="description">Start session</span>
      </mat-card>
    </li>
  </ul>
</div>
<app-session-created
  [session]="session"
  *ngIf="containerReady"
></app-session-created>

frontend/src/app/session-creation-progress/session-creation-progress.component.css METASEP
:host ::ng-deep .mat-progress-spinner circle,
.mat-spinner circle {
  stroke: black;
  width: 10px !important;
  height: 10px !important;
}

mat-icon {
  font-size: 2.5em;
  background-color: white;
  margin-bottom: 5px;
}

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
}

.step {
  display: flex;

  align-items: center;
}

.description {
  position: absolute;
  margin-top: 5px;
  margin-left: 60px;
}

.error {
  background-color: var(--error-color);
}

.warning {
  background-color: var(--warning-color);
}

.success {
  background-color: var(--success-color);
}

.session-state {
  font-size: 16px;
  color: white;
  margin: 10px;
}

frontend/src/app/session-created/session-created.component.ts METASEP
import { Component, Input, OnInit } from '@angular/core';
import { Session } from '../schemes';
import { OwnSessionService } from '../services/own-session/own-session.service';
import { SessionService } from '../services/session/session.service';

@Component({
  selector: 'app-session-created',
  templateUrl: './session-created.component.html',
  styleUrls: ['./session-created.component.css'],
})
export class SessionCreatedComponent implements OnInit {
  @Input()
  session: Session | undefined = undefined;
  constructor(private ownSessionService: OwnSessionService) {}

  ngOnInit(): void {
    this.ownSessionService.refreshSessions().subscribe();
  }
}

frontend/src/app/session-created/session-created.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { SessionCreatedComponent } from './session-created.component';

describe('SessionCreatedComponent', () => {
  let component: SessionCreatedComponent;
  let fixture: ComponentFixture<SessionCreatedComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ SessionCreatedComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(SessionCreatedComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/session-created/session-created.component.html METASEP
<mat-card *ngIf="session" id="mat-card-session-created">
  <h2>The creation was successful and the server started.</h2>
  <div class="flexbox">
    <app-guacamole [session]="session"></app-guacamole>
  </div>
</mat-card>

frontend/src/app/session-created/session-created.component.css METASEP
#mat-card-session-created {
  margin-top: 40px;
}

.flexbox {
  display: flex;
}

mat-card {
  margin-top: 10px;
  width: fit-content;
  margin-left: auto;
  margin-right: auto;
}

frontend/src/app/notice/notice.component.ts METASEP
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { NoticeService } from '../services/notice/notice.service';

@Component({
  selector: 'app-notice',
  templateUrl: './notice.component.html',
  styleUrls: ['./notice.component.css'],
  encapsulation: ViewEncapsulation.None,
})
export class NoticeComponent implements OnInit {
  constructor(public noticeService: NoticeService) {}

  ngOnInit(): void {}
}

frontend/src/app/notice/notice.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { NoticeComponent } from './notice.component';

describe('NoticeComponent', () => {
  let component: NoticeComponent;
  let fixture: ComponentFixture<NoticeComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ NoticeComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(NoticeComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/notice/notice.component.html METASEP
<div *ngFor="let notice of noticeService.notices">
  <mat-card *ngIf="notice.scope === 't4c'" [class]="notice.level">
    <h3 [innerHTML]="notice.title"></h3>
    <p [innerHTML]="notice.message"></p>
  </mat-card>
</div>

frontend/src/app/notice/notice.component.css METASEP
mat-card {
  margin: 10px;
  width: inherit;
}

p {
  margin: 0px;
  padding: 0px;
}

h3 {
  margin: 0px !important;
}

.url {
  color: white;
}

.primary {
  background-color: #004085;
  color: white;
}

.secondary {
  background-color: #383d41;
  color: white;
}

.success {
  background-color: #155724;
  color: white;
}

.danger {
  background-color: #721c24;
  color: white;
}

.warning {
  background-color: #fff3cd;
  color: black;
}

.info {
  background-color: #d1ecf1;
  color: black;
}

frontend/src/app/home/home.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import {
  Repository,
  RepositoryService,
} from '../services/repository/repository.service';
import { SessionService } from '../services/session/session.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css'],
})
export class HomeComponent implements OnInit {
  constructor() {}

  ngOnInit(): void {}
}

frontend/src/app/home/home.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { HomeComponent } from './home.component';

describe('HomeComponent', () => {
  let component: HomeComponent;
  let fixture: ComponentFixture<HomeComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ HomeComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(HomeComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/home/home.component.html METASEP
<mat-card id="welcome-card">
  <span id="welcome">Welcome to the</span>
  <h1>Capella Collaboration Manager</h1>
</mat-card>

<div class="flexbox">
  <app-workspace></app-workspace>
  <app-active-sessions></app-active-sessions>
</div>

frontend/src/app/home/home.component.css METASEP
.flexbox {
  display: flex;
  align-items: top;
  justify-content: space-around;
}

#welcome-card {
  margin-top: 10px;
  text-align: center;
  margin-left: auto;
  margin-right: auto;
  color: white;
  background-color: #010035;
  margin-bottom: 50px;
}

frontend/src/app/header/header.component.ts METASEP
import { Component, Input, OnInit, Renderer2 } from '@angular/core';
import { Router } from '@angular/router';
import { LocalStorageService } from '../auth/local-storage/local-storage.service';
import { AuthService } from '../services/auth/auth.service';
import { RepositoryService } from '../services/repository/repository.service';
import { UserService } from '../services/user/user.service';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css'],
})
export class HeaderComponent implements OnInit {
  @Input()
  title = 'Capella Collaboration Plattform';

  constructor(
    public localStorageService: LocalStorageService,
    public authService: AuthService,
    public userService: UserService,
    public repositoryService: RepositoryService
  ) {}

  ngOnInit(): void {
    this.createGithubButton();
  }

  createGithubButton(): void {
    let githubButtonScript = document.createElement('script');
    githubButtonScript.type = 'text/javascript';
    githubButtonScript.src = 'https://buttons.github.io/buttons.js';
    document.head.appendChild(githubButtonScript);
  }
}

frontend/src/app/header/header.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { HeaderComponent } from './header.component';

describe('HeaderComponent', () => {
  let component: HeaderComponent;
  let fixture: ComponentFixture<HeaderComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ HeaderComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(HeaderComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/header/header.component.html METASEP
<div id="toolbar">
  <div class="flexbox primaryText" id="title">{{ title }}</div>
  <div class="flexbox">
    <button mat-raised-button color="primary" routerLink="">Workspaces</button>
    <button
      color="primary"
      id="overview"
      mat-raised-button
      *ngIf="
        repositoryService.isManager ||
        userService.user?.role === 'administrator'
      "
      routerLink="overview"
    >
      Overview
    </button>
  </div>
  <div class="right-aligned">
    <div>
      <div class="margin"></div>
      <span id="github">
        <a
          class="github-button"
          href="https://github.com/DSD-DBS/capella-collab-manager/issues"
          data-color-scheme="no-preference: light; light: light; dark: dark;"
          data-size="large"
          aria-label="Issue DSD-DBS/capella-collab-manager on GitHub"
          >Open Issue on Github</a
        >
      </span>
    </div>
    <mat-menu #profileMenu="matMenu">
      <button class="profileMenuButton" mat-menu-item routerLink="settings">
        Settings <mat-icon>settings</mat-icon>
      </button>
      <button
        class="profileMenuButton"
        mat-menu-item
        routerLink="logout"
        [queryParams]="{ reason: 'logout' }"
        *ngIf="localStorageService.getValue('access_token')"
      >
        Log out <mat-icon>logout</mat-icon>
      </button>
    </mat-menu>
    <button
      color="primary"
      id="profile"
      mat-raised-button
      [matMenuTriggerFor]="profileMenu"
    >
      Profile <mat-icon>account_circle</mat-icon>
    </button>
  </div>
</div>

frontend/src/app/header/header.component.css METASEP
#toolbar {
  display: flex;
  background-color: #f5f5f5;
  justify-content: space-between;
  align-items: center;
}

#title {
  margin-left: 20px;
  font-size: 1.5em;
}

.flexbox {
  display: flex;
  align-items: center;
}

#profile {
  margin-left: 20px;
  margin-right: 10px;
}

.margin {
  padding-top: 10px;
}

.right-aligned {
  display: flex;
}
::ng-deep.mat-menu-panel {
  overflow: hidden !important;
}

.profileMenuButton {
  margin: 0;
  padding: 0 0 0 15px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

button {
  margin: 5px;
}

frontend/src/app/footer/footer.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { TermsConditionsComponent } from './terms-conditions/terms-conditions.component';

@Component({
  selector: 'app-footer',
  templateUrl: './footer.component.html',
  styleUrls: ['./footer.component.css'],
})
export class FooterComponent implements OnInit {
  constructor(public dialog: MatDialog) {}

  ngOnInit(): void {}

  openTC(): void {
    this.dialog.open(TermsConditionsComponent);
  }
}

frontend/src/app/footer/footer.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { FooterComponent } from './footer.component';

describe('FooterComponent', () => {
  let component: FooterComponent;
  let fixture: ComponentFixture<FooterComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ FooterComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(FooterComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/footer/footer.component.html METASEP
<div class="footer">
  Platform for co-working on architectural projects using ARCADIA / Capella
  <br />
  Provided by ERTMS,
  <span id="tc" (click)="openTC()">Terms & conditions</span>
</div>

frontend/src/app/footer/footer.component.css METASEP
.footer {
  text-align: center;
  margin: auto;
  width: 100%;
  margin-top: 20px;
  margin-bottom: 10px;
  color: grey;
}

#tc {
  color: var(--primary-color);
  cursor: pointer;
}

frontend/src/app/delete-session-dialog/delete-session-dialog.component.ts METASEP
import { Component, Inject, OnInit } from '@angular/core';
import {
  MatDialog,
  MatDialogRef,
  MAT_DIALOG_DATA,
} from '@angular/material/dialog';
import { forkJoin } from 'rxjs';
import { Session } from '../schemes';
import { SessionService } from '../services/session/session.service';

@Component({
  templateUrl: './delete-session-dialog.component.html',
  styleUrls: ['./delete-session-dialog.component.css'],
})
export class DeleteSessionDialogComponent implements OnInit {
  constructor(
    private sessionService: SessionService,
    public dialogRef: MatDialogRef<DeleteSessionDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public sessions: Array<Session>
  ) {}

  ngOnInit(): void {}
  deleteButton = {
    disabled: false,
    text: 'Terminate',
  };

  deleteAllSessions() {
    this.deleteButton.disabled = true;
    this.deleteButton.text = 'Please wait...';
    let requests = [];
    for (let session of this.sessions) {
      requests.push(this.sessionService.deleteSession(session.id));
    }

    forkJoin(requests).subscribe(
      () => {
        this.dialogRef.close();
      },
      (err) => {
        this.deleteButton.disabled = false;
        this.deleteButton.text = 'Failure. Try again.';
      }
    );
  }
}

frontend/src/app/delete-session-dialog/delete-session-dialog.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { DeleteSessionDialogComponent } from './delete-session-dialog.component';

describe('DeleteSessionDialogComponent', () => {
  let component: DeleteSessionDialogComponent;
  let fixture: ComponentFixture<DeleteSessionDialogComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ DeleteSessionDialogComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(DeleteSessionDialogComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/delete-session-dialog/delete-session-dialog.component.html METASEP
<h1 mat-dialog-title>Termine Workspace</h1>
<div mat-dialog-content>
  <p>Do you want terminate the following sessions?</p>
  <ul>
    <li *ngFor="let session of sessions">
      ID: {{ session.id }} <br />
      Owner: {{ session.owner }} <br />
      {{ session.repository }}
    </li>
  </ul>
  <p>This will force close the sessions and all unsaved work will be lost!</p>
</div>
<div mat-dialog-actions>
  <button mat-button (click)="this.dialogRef.close()">No</button>
  <button
    mat-flat-button
    [disabled]="deleteButton.disabled"
    (click)="deleteAllSessions()"
  >
    {{ deleteButton.text }}
  </button>
</div>

frontend/src/app/delete-session-dialog/delete-session-dialog.component.css METASEP

frontend/src/app/active-sessions/active-sessions.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { DeleteSessionDialogComponent } from '../delete-session-dialog/delete-session-dialog.component';
import { Session } from '../schemes';
import { BeautifyService } from '../services/beatify/beautify.service';
import { OwnSessionService } from '../services/own-session/own-session.service';
import { UserService } from '../services/user/user.service';
import { ReconnectDialogComponent } from './reconnect-dialog/reconnect-dialog.component';

@Component({
  selector: 'app-active-sessions',
  templateUrl: './active-sessions.component.html',
  styleUrls: ['./active-sessions.component.css'],
})
export class ActiveSessionsComponent implements OnInit {
  showSpinner = false;

  constructor(
    public ownSessionService: OwnSessionService,
    private dialog: MatDialog,
    public beautifyService: BeautifyService
  ) {}

  ngOnInit(): void {
    this.refreshSessions();
  }

  refreshSessions() {
    this.showSpinner = true;
    this.ownSessionService.refreshSessions().subscribe(() => {
      this.showSpinner = false;
    });
  }

  openDeletionDialog(sessions: Array<Session>): void {
    const dialogRef = this.dialog.open(DeleteSessionDialogComponent, {
      data: sessions,
    });

    dialogRef.afterClosed().subscribe((_) => {
      this.refreshSessions();
    });
  }

  openReconnectDialog(session: Session): void {
    this.dialog.open(ReconnectDialogComponent, {
      data: session,
    });
  }
}

frontend/src/app/active-sessions/active-sessions.component.spec.ts METASEP
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ActiveSessionsComponent } from './active-sessions.component';

describe('ActiveSessionsComponent', () => {
  let component: ActiveSessionsComponent;
  let fixture: ComponentFixture<ActiveSessionsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ ActiveSessionsComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(ActiveSessionsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

frontend/src/app/active-sessions/active-sessions.component.html METASEP
<div class="wrapper">
  <span id="title"><b>Active Sessions</b></span>
  <button mat-icon-button (click)="refreshSessions()">
    <mat-icon>refresh </mat-icon>
  </button>

  <mat-spinner *ngIf="showSpinner"></mat-spinner>

  <mat-card *ngIf="!ownSessionService.sessions.length && !showSpinner">
    <h2>No active sessions</h2>
    <div class="content">
      No active sessions for your user are found in our system. <br />
    </div>
  </mat-card>

  <div class="flexbox">
    <mat-card *ngFor="let session of ownSessionService.sessions; let i = index">
      <div class="header">
        <div class="type">
          <h2 *ngIf="session.type == 'persistent'">
            Persistent workspace session
          </h2>
          <h2 *ngIf="session.type == 'readonly'">
            {{ session.repository }} (read-only session)
          </h2>
        </div>
        <div
          class="state"
          [ngClass]="beautifyService.beatifyState(session.state).css"
        >
          <h3>{{ beautifyService.beatifyState(session.state).text }}</h3>
        </div>
      </div>
      <div class="content">
        <div class="text">
          The session was created
          {{ beautifyService.beatifyDate(session.created_at) }}
          <br />
        </div>
        <button
          mat-flat-button
          color="primary"
          (click)="openDeletionDialog([session])"
        >
          Terminate
        </button>
        <button
          mat-flat-button
          color="primary"
          (click)="openReconnectDialog(session)"
        >
          Reconnect
        </button>
      </div>
    </mat-card>
  </div>
</div>

frontend/src/app/active-sessions/active-sessions.component.css METASEP
mat-card {
  width: fit-content;
  margin: 10px;
}

button {
  margin: 10px 5px 0;
}

.flexbox {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.wrapper {
  display: flex;
  flex-direction: column;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  align-items: center;
}
.header {
  display: flex;
  flex-direction: column;
  margin-bottom: 10px;
}

#title {
  font-size: 24px;
  text-align: center;
}

h2 {
  margin: 5px 10px;
}

.header > .type {
  background-color: var(--primary-color);
  color: white;
  border-radius: 5px 5px 0 0;
}

.header > .state {
  color: white;
  border-radius: 0 0 10px 10px;
}

.error {
  background-color: var(--error-color);
}

.warning {
  background-color: var(--warning-color);
}

.success {
  background-color: var(--success-color);
}

.primary {
  background-color: var(--primary-color);
}

.content {
  padding: 0 10px 10px;
}

.content > .text {
  text-align: left;
}

.mat-card {
  padding: 0 !important;
}

.mat-card-content {
  padding: 5px !important;
}

backend/t4cclient/schemas/repositories/users.py METASEP
from enum import Enum

from pydantic import BaseModel


class Role(Enum):
    USER = "user"
    ADMIN = "administrator"


class PatchUserRoleRequest(BaseModel):
    role: Role


class GetUserResponse(BaseModel):
    id: str
    name: str
    role: Role

    class Config:
        orm_mode = True

backend/t4cclient/schemas/repositories/projects.py METASEP
from lib2to3.pytree import Base

from pydantic import BaseModel


class RepositoryProjectBase(BaseModel):
    name: str

    class Config:
        orm_mode = True


class RepositoryProject(RepositoryProjectBase):
    id: int
    repository_name: str

backend/t4cclient/schemas/repositories/__init__.py METASEP
from __future__ import annotations

import enum
import typing as t

from pydantic import BaseModel


class RepositoryUserRole(enum.Enum):
    USER = "user"
    MANAGER = "manager"
    ADMIN = "administrator"


class RepositoryUserPermission(enum.Enum):
    READ = "read"
    WRITE = "write"


class Warning(enum.Enum):
    LICENCE_LIMIT = "LICENCE_LIMIT"
    NO_GIT_MODEL_DEFINED = "NO_GIT_MODEL_DEFINED"


class GetRepositoryUserResponse(BaseModel):
    repository_name: str
    role: RepositoryUserRole
    permissions: t.List[RepositoryUserPermission]
    warnings: t.List[Warning]

    class Config:
        orm_mode = True


class PostRepositoryRequest(BaseModel):
    name: str


class PostRepositoryUser(BaseModel):
    username: str
    role: RepositoryUserRole
    permission: RepositoryUserPermission

    class Config:
        orm_mode = True


class RepositoryUser(PostRepositoryUser):
    repository_name: str


class PatchRepositoryUser(BaseModel):
    role: t.Optional[RepositoryUserRole]
    password: t.Optional[str]
    permission: t.Optional[RepositoryUserPermission]

backend/t4cclient/routes/repositories/users.py METASEP
import typing as t

import t4cclient.extensions.modelsources.t4c.connection as t4c_manager
import t4cclient.schemas.repositories as schema_repositories
from fastapi import APIRouter, Depends, HTTPException
from requests import HTTPError, Session
from t4cclient.config import USERNAME_CLAIM
from t4cclient.core.database import get_db, repository_users, users
from t4cclient.core.oauth.database import (
    check_username_not_admin,
    is_admin,
    verify_repository_role,
    verify_write_permission,
)
from t4cclient.core.oauth.jwt_bearer import JWTBearer
from t4cclient.routes.open_api_configuration import AUTHENTICATION_RESPONSES

router = APIRouter()


@router.get(
    "/",
    response_model=t.List[schema_repositories.RepositoryUser],
    responses=AUTHENTICATION_RESPONSES,
)
def get_users_for_repository(
    project: str, db: Session = Depends(get_db), token=Depends(JWTBearer())
):
    verify_repository_role(
        project, allowed_roles=["manager", "administrator"], token=token, db=db
    )
    return repository_users.get_users_of_repository(db, project)


@router.post(
    "/",
    response_model=schema_repositories.RepositoryUser,
    responses=AUTHENTICATION_RESPONSES,
)
def add_user_to_repository(
    project: str,
    body: schema_repositories.PostRepositoryUser,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    verify_repository_role(
        project, allowed_roles=["manager", "administrator"], token=token, db=db
    )
    users.find_or_create_user(db, body.username)
    check_username_not_admin(body.username, db)
    if body.role == schema_repositories.RepositoryUserRole.MANAGER:
        body.permission == schema_repositories.RepositoryUserPermission.WRITE
    if body.permission == schema_repositories.RepositoryUserPermission.WRITE:
        t4c_manager.add_user_to_repository(project, body.username)
    return repository_users.add_user_to_repository(
        db, project, body.role, body.username, body.permission
    )


@router.patch(
    "/{username}",
    status_code=204,
    responses=AUTHENTICATION_RESPONSES,
)
def patch_repository_user(
    project: str,
    username: str,
    body: schema_repositories.PatchRepositoryUser,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    verify_repository_role(
        project,
        allowed_roles=["user", "manager", "administrator"],
        token=token,
        db=db,
    )

    if body.role:
        verify_repository_role(
            project,
            allowed_roles=["manager", "administrator"],
            token=token,
            db=db,
        )
        check_username_not_admin(username, db)
        repository_users.change_role_of_user_in_repository(
            db, project, body.role, username
        )
    if body.password:
        verify_repository_role(
            project,
            token=token,
            db=db,
        )
        verify_write_permission(project, token, db)
        if not is_admin(token, db) and token[USERNAME_CLAIM] != username:
            raise HTTPException(
                status_code=403,
                detail="The username does not match with your user. You have to be administrator to edit other users.",
            )

        try:
            t4c_manager.update_password_of_user(project, username, body.password)
        except HTTPError as err:
            if err.response.status_code == 404:
                t4c_manager.add_user_to_repository(project, username, body.password)
            else:
                raise HTTPException(
                    status_code=500,
                    detail="Invalid response from T4C Server",
                )

    if body.permission:
        verify_repository_role(
            project,
            allowed_roles=["manager", "administrator"],
            token=token,
            db=db,
        )
        check_username_not_admin(username, db)
        repo_user = repository_users.get_user_of_repository(
            db,
            project,
            username,
        )

        if repo_user.role == schema_repositories.RepositoryUserRole.MANAGER:
            raise HTTPException(
                status_code=403,
                detail="You are not allowed to set the permission of managers!",
            )
        repository_users.change_permission_of_user_in_repository(
            db, project, body.permission, username
        )


@router.delete(
    "/{username}",
    status_code=204,
    responses=AUTHENTICATION_RESPONSES,
)
def remove_user_from_repository(
    project: str,
    username: str,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    verify_repository_role(
        project, allowed_roles=["manager", "administrator"], token=token, db=db
    )
    check_username_not_admin(username, db)
    t4c_manager.remove_user_from_repository(project, username)
    return repository_users.delete_user_from_repository(db, project, username)

backend/t4cclient/routes/repositories/__init__.py METASEP
import logging
import typing as t
from importlib import metadata

import t4cclient.core.services.repositories as repository_service
from fastapi import APIRouter, Depends
from requests import Session
from t4cclient.config import USERNAME_CLAIM
from t4cclient.core.database import get_db, repositories
from t4cclient.core.database import users as database_users
from t4cclient.core.oauth.database import is_admin, verify_admin, verify_repository_role
from t4cclient.core.oauth.jwt_bearer import JWTBearer
from t4cclient.extensions.modelsources.t4c import connection
from t4cclient.routes.open_api_configuration import AUTHENTICATION_RESPONSES
from t4cclient.schemas.repositories import (
    GetRepositoryUserResponse,
    PostRepositoryRequest,
    RepositoryUserPermission,
    RepositoryUserRole,
)

from . import users as router_users

log = logging.getLogger(__name__)
router = APIRouter()


@router.get(
    "/",
    response_model=t.List[GetRepositoryUserResponse],
    tags=["Repositories"],
    responses=AUTHENTICATION_RESPONSES,
)
def get_repositories(db: Session = Depends(get_db), token=Depends(JWTBearer())):
    if is_admin(token, db):
        return [
            GetRepositoryUserResponse(
                repository_name=repo.name,
                permissions=repository_service.get_permission(
                    RepositoryUserPermission.WRITE, repo.name, db
                ),
                warnings=repository_service.get_warnings(repo.name, db),
                role=RepositoryUserRole.ADMIN,
            )
            for repo in repositories.get_all_repositories(db)
        ]

    db_user = database_users.get_user(db=db, username=token[USERNAME_CLAIM])
    return [
        GetRepositoryUserResponse(
            repository_name=repo.repository_name,
            role=repo.role,
            permissions=repository_service.get_permission(
                repo.permission, repo.repository_name, db
            ),
            warnings=repository_service.get_warnings(repo.repository_name, db),
        )
        for repo in db_user.repositories
    ]


@router.get("/{project}", tags=["Repositories"], responses=AUTHENTICATION_RESPONSES)
def get_repository_by_name(
    project: str, db: Session = Depends(get_db), token=Depends(JWTBearer())
):
    verify_repository_role(project, token=token, db=db)
    return repositories.get_repository(db, project)


@router.post("/", tags=["Repositories"], responses=AUTHENTICATION_RESPONSES)
def create_repository(
    body: PostRepositoryRequest,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    verify_admin(token, db)
    connection.create_repository(body.name)
    return repositories.create_repository(db, body.name)


@router.delete(
    "/{project}",
    tags=["Repositories"],
    status_code=204,
    responses=AUTHENTICATION_RESPONSES,
)
def delete_repository(
    project: str, db: Session = Depends(get_db), token=Depends(JWTBearer())
):
    verify_admin(token, db)
    repositories.delete_repository(db, project)


router.include_router(
    router_users.router,
    prefix="/{project}/users",
    tags=["Repository Users"],
)

# Load backup extension routes
eps = metadata.entry_points()["capellacollab.extensions.backups"]
for ep in eps:
    log.info("Add routes of backup extension %s", ep.name)
    router.include_router(
        ep.load().routes.router,
        prefix="/{project}/extensions/backups/" + ep.name,
        tags=[ep.name],
    )

# Load modelsource extension routes
eps = metadata.entry_points()["capellacollab.extensions.modelsources"]
for ep in eps:
    log.info("Add routes of modelsource %s", ep.name)
    router.include_router(
        ep.load().routes.router,
        prefix="/{project}/extensions/modelsources/" + ep.name,
        tags=[ep.name],
    )

backend/t4cclient/extensions/modelsources/__init__.py METASEP

backend/t4cclient/extensions/backups/__init__.py METASEP

backend/t4cclient/core/services/sessions.py METASEP
import logging
import re
import typing as t

import t4cclient.extensions.modelsources.t4c.connection as t4c_manager
from t4cclient import config
from t4cclient.core.operators import OPERATOR
from t4cclient.schemas.sessions import WorkspaceType
from t4cclient.sql_models.sessions import DatabaseSession

log = logging.getLogger(__name__)


def inject_attrs_in_sessions(
    db_sessions: t.List[DatabaseSession],
) -> t.List[t.Dict[str, t.Any]]:
    sessions_list = []
    for s in db_sessions:
        session_dict = s.__dict__
        session_dict["state"] = _determine_session_state(session_dict)
        session_dict["last_seen"] = t4c_manager.fetch_last_seen(session_dict["mac"])
        session_dict["owner"] = session_dict["owner_name"]

        sessions_list.append(session_dict)

    return sessions_list


def _determine_session_state(session: t.Dict[str, t.Any]) -> str:
    state = OPERATOR.get_session_state(session["id"])

    if session["type"] == WorkspaceType.READONLY:
        try:
            if state == "Running":
                logs = OPERATOR.get_session_logs(session["id"]).splitlines()
                for line in logs:
                    res = re.search(r"^---(.*?)---$", line)
                    if res:
                        state = res.group(1)
        except:
            log.exception("Could not parse log")
    return state

backend/t4cclient/core/services/repositories.py METASEP
import typing as t

import t4cclient.extensions.modelsources.git.crud as git_model_crud
import t4cclient.extensions.modelsources.t4c.connection as t4c_ext
import t4cclient.schemas.repositories as repository_schema
import t4cclient.schemas.repositories.users as users_schema
from sqlalchemy.orm.session import Session
from t4cclient.schemas.repositories import RepositoryUserPermission


def get_permission(
    repo_permission: RepositoryUserPermission, repository_name: str, db: Session
) -> t.List[RepositoryUserPermission]:
    allowed_permissions: t.List[RepositoryUserPermission] = []

    if git_model_crud.get_primary_model_of_repository(db, repository_name):
        allowed_permissions.append(RepositoryUserPermission.READ)

    if repo_permission == RepositoryUserPermission.WRITE:
        allowed_permissions.append(RepositoryUserPermission.WRITE)
    return allowed_permissions


def get_warnings(
    repository_name: str, db: Session
) -> t.List[repository_schema.Warning]:
    warnings: t.List[repository_schema.Warning] = []
    # if t4c_ext.get_t4c_status()["free"] == 0:
    warnings.append(repository_schema.Warning.LICENCE_LIMIT)

    if not git_model_crud.get_primary_model_of_repository(db, repository_name):
        warnings.append(repository_schema.Warning.NO_GIT_MODEL_DEFINED)
    return warnings

backend/t4cclient/core/services/__init__.py METASEP

backend/t4cclient/core/operators/k8s.py METASEP
import logging
import random
import string
import typing as t
from cProfile import label
from datetime import datetime

import kubernetes
import kubernetes.client.exceptions
import kubernetes.client.models
import kubernetes.config
from t4cclient import config
from t4cclient.core.operators.abc import Operator

log = logging.getLogger(__name__)

try:
    kubernetes.config.load_incluster_config()
except kubernetes.config.ConfigException:
    try:
        kubernetes.config.load_config(context=config.KUBERNETES_CONTEXT)
    except kubernetes.config.ConfigException:
        kubernetes.config.load_kube_config_from_dict(
            {
                "apiVersion": "v1",
                "kind": "Config",
                "clusters": [
                    {
                        "cluster": {
                            "insecure-skip-tls-verify": True,
                            "server": config.KUBERNETES_API_URL,
                        },
                        "name": "cluster",
                    }
                ],
                "contexts": [
                    {
                        "context": {"cluster": "cluster", "user": "tokenuser"},
                        "name": "cluster",
                    }
                ],
                "current-context": "cluster",
                "users": [
                    {
                        "name": "tokenuser",
                        "user": {"token": config.KUBERNETES_TOKEN},
                    }
                ],
            }
        )


class KubernetesOperator(Operator):
    def __init__(self) -> None:
        self.v1_core = kubernetes.client.CoreV1Api()
        self.v1_apps = kubernetes.client.AppsV1Api()
        self.v1_batch = kubernetes.client.BatchV1Api()

    def validate(self) -> str:
        try:
            self.v1_core.get_api_resources()
            return "ok"
        except:
            return "cannot connect"

    def start_persistent_session(
        self,
        username: str,
        password: str,
        repositories: t.List[str],
    ) -> t.Dict[str, t.Any]:
        log.info("Launching a persistent session for user %s", username)

        id = self._generate_id()
        self._create_persistent_volume_claim(username)
        deployment = self._create_deployment(
            config.PERSISTENT_IMAGE,
            id,
            {
                "T4C_LICENCE_SECRET": config.T4C_LICENCE,
                "T4C_SERVER_HOST": config.T4C_SERVER_HOST,
                "T4C_SERVER_PORT": config.T4C_SERVER_PORT,
                "T4C_REPOSITORIES": ",".join(repositories),
                "RMT_PASSWORD": password,
            },
            self._get_claim_name(username),
        )
        self._create_service(id, id)
        service = self._get_service(id)
        log.info("Launched a persistent session for user %s with id %s", username, id)
        return self._export_attrs(deployment, service)

    def start_readonly_session(
        self, password: str, git_url: str, git_revision: str, entrypoint: str
    ) -> t.Dict[str, t.Any]:
        id = self._generate_id()
        deployment = self._create_deployment(
            config.READONLY_IMAGE,
            id,
            {
                "GIT_USERNAME": config.GIT_USERNAME,
                "GIT_PASSWORD": config.GIT_PASSWORD,
                "GIT_URL": git_url,
                "GIT_REVISION": git_revision,
                "GIT_ENTRYPOINT": entrypoint,
                "RMT_PASSWORD": password,
            },
        )
        self._create_service(id, id)
        service = self._get_service(id)
        return self._export_attrs(deployment, service)

    def get_cronjob_last_state(self, name: str) -> str:
        job = self._get_last_job_of_cronjob(name)
        if job:
            return self._get_pod_state(label_selector="job-name=" + job)
        else:
            return "pending"

    def get_cronjob_last_starting_date(self, name: str) -> datetime | None:
        job = self._get_last_job_of_cronjob(name)
        if job:
            return self._get_pod_starttime(label_selector="job-name=" + job)
        else:
            return None

    def _get_last_job_of_cronjob(self, name: str) -> str | None:
        jobs = [
            item
            for item in self.v1_batch.list_namespaced_job(
                namespace=config.KUBERNETES_NAMESPACE
            ).items
            if item.metadata.owner_references
            and item.metadata.owner_references[0].name == name
        ]

        if jobs:
            return jobs[-1].metadata.name
        else:
            return None

    def get_session_state(self, id: str) -> str:
        self._get_pod_state(self, label_selector="app=" + id)

    def _get_pod_state(self, label_selector: str):
        try:
            pods = self.v1_core.list_namespaced_pod(
                namespace=config.KUBERNETES_NAMESPACE, label_selector=label_selector
            ).to_dict()

            log.debug("Receive k8s pod: %s", pods)
            try:
                phase = pods["items"][0]["status"]["phase"]
            except IndexError:
                return "NOT_FOUND"
            if phase == "Running":
                return "Running"
            elif phase == "Pending":
                status = pods["items"][0]["status"]

                conditions = status["conditions"]
                if conditions and conditions[-1]["reason"]:
                    return conditions[-1]["reason"]

                container_statuses = status["container_statuses"]
                if container_statuses:
                    return container_statuses[-1]["state"]["waiting"]["reason"]

            return "unknown"
        except kubernetes.client.exceptions.ApiException as e:
            log.warning("Kubernetes error", exc_info=True)
            return "error-" + str(e.status)
        except Exception as e:
            log.exception("Error parsing the session state")
            return "unknown"

    def _get_pod_starttime(self, label_selector: str) -> datetime | None:
        try:
            pods = self.v1_core.list_namespaced_pod(
                namespace=config.KUBERNETES_NAMESPACE, label_selector=label_selector
            ).to_dict()
            log.debug("Received k8s pods: %s", pods)

            return pods["items"][0]["status"]["start_time"]
        except Exception as e:
            log.exception("Error fetching the starting_time")
            return None

    def get_session_logs(self, id: str) -> str:
        pod_name = self.v1_core.list_namespaced_pod(
            namespace=config.KUBERNETES_NAMESPACE, label_selector="app=" + id
        ).to_dict()["items"][0]["metadata"]["name"]
        return self.v1_core.read_namespaced_pod_log(
            name=pod_name,
            namespace=config.KUBERNETES_NAMESPACE,
        )

    def get_job_logs(self, id: str) -> str:
        try:
            log = self.v1_core.read_namespaced_pod_log(
                name=id,
                namespace=config.KUBERNETES_NAMESPACE,
            )

            if log:
                return log
        except Exception:
            pass

        return "\n".join(
            [
                item.reason + ": " + item.message
                for item in self.v1_core.list_namespaced_event(
                    namespace=config.KUBERNETES_NAMESPACE,
                    field_selector="involvedObject.name=" + id,
                ).items
            ]
        )

    def create_cronjob(
        self, image: str, environment: t.Dict[str, str], schedule="* * * * *"
    ) -> str:
        id = self._generate_id()
        self._create_cronjob(
            name=id,
            image=image,
            environment=environment,
            schedule=schedule,
        )
        return id

    def trigger_cronjob(self, name: str) -> None:
        cronjob = self.v1_batch.read_namespaced_cron_job(
            namespace=config.KUBERNETES_NAMESPACE, name=name
        )
        job = kubernetes.client.V1Job(
            api_version="batch/v1",
            kind="Job",
            metadata=kubernetes.client.models.V1ObjectMeta(
                name=self._generate_id(),
                # This annotation is added by kubectl, probably best to add it ourselves as well
                annotations={"cronjob.kubernetes.io/instantiate": "manual"},
                owner_references=[
                    {
                        "apiVersion": "batch/v1",
                        "blockOwnerDeletion": None,
                        "controller": None,
                        "kind": "CronJob",
                        "name": name,
                        "uid": cronjob.metadata.uid,
                    }
                ],
            ),
            spec=cronjob.spec.job_template.spec,
        )
        self.v1_batch.create_namespaced_job(
            namespace=config.KUBERNETES_NAMESPACE, body=job
        )

    def delete_cronjob(self, id: str) -> None:
        self._delete_cronjob(id=id)

    def get_cronjob_last_run(self, name: str) -> str | None:
        job = self._get_last_job_of_cronjob(name)
        if job:
            return self._get_pod_id(label_selector="job-name=" + job)
        else:
            return None

    def _get_pod_id(self, label_selector: str) -> str:
        try:
            pods = self.v1_core.list_namespaced_pod(
                namespace=config.KUBERNETES_NAMESPACE, label_selector=label_selector
            ).to_dict()
            log.debug("Received k8s pods: %s", pods)

            return pods["items"][0]["metadata"]["name"]
        except Exception as e:
            log.exception("Error fetching the last run id")
            return ""

    def _generate_id(self):
        return "".join(random.choices(string.ascii_lowercase, k=25))

    def kill_session(self, id: str) -> None:
        log.info("Terminating session %s", id)
        status = self._delete_deployment(id)
        log.info(f"Deleted deployment {id}: {status and status.status}")
        self._delete_service(id)
        log.info(f"Deleted service {id}: {status and status.status}")

    def _export_attrs(
        self,
        deployment: kubernetes.client.V1Deployment,
        service: kubernetes.client.V1Service,
    ) -> t.Dict[str, t.Any]:
        return {
            "id": deployment.to_dict()["metadata"]["name"],
            "ports": set([3389]),
            "created_at": deployment.to_dict()["metadata"]["creation_timestamp"],
            "mac": "-",
            "host": service.to_dict()["metadata"]["name"]
            + "."
            + config.KUBERNETES_NAMESPACE,
        }

    def _create_deployment(
        self,
        image: str,
        name: str,
        environment: t.Dict,
        volume_claim_name: str = None,
    ) -> kubernetes.client.V1Deployment:
        volume_mount = []
        volume = []

        if volume_claim_name:
            volume_mount.append({"name": "workspace", "mountPath": "/workspace"})

            volume.append(
                {
                    "name": "workspace",
                    "persistentVolumeClaim": {"claimName": volume_claim_name},
                }
            )

        body = {
            "kind": "Deployment",
            "apiVersion": "apps/v1",
            "metadata": {"name": name},
            "spec": {
                "replicas": 1,
                "selector": {"matchLabels": {"app": name}},
                "template": {
                    "metadata": {"labels": {"app": name}},
                    "spec": {
                        "containers": [
                            {
                                "name": name,
                                "image": image,
                                "ports": [{"containerPort": 3389, "protocol": "TCP"}],
                                "env": [
                                    {"name": key, "value": value}
                                    for key, value in environment.items()
                                ],
                                "resources": {
                                    "limits": {"cpu": "2", "memory": "6Gi"},
                                    "requests": {"cpu": "0.4", "memory": "1.6Gi"},
                                },
                                "imagePullPolicy": "Always",
                                "volumeMounts": volume_mount,
                            },
                        ],
                        "volumes": volume,
                        "restartPolicy": "Always",
                    },
                },
            },
        }
        return self.v1_apps.create_namespaced_deployment(
            config.KUBERNETES_NAMESPACE, body
        )

    def _create_cronjob(
        self, name: str, image: str, environment: t.Dict[str, str], schedule="* * * * *"
    ) -> kubernetes.client.V1CronJob:
        body = {
            "kind": "CronJob",
            "apiVersion": "batch/v1",
            "metadata": {
                "name": name,
            },
            "spec": {
                "schedule": schedule,
                "jobTemplate": {
                    "spec": {
                        "template": {
                            "spec": {
                                "volumes": [
                                    {
                                        "name": "script",
                                        "configMap": {
                                            name: config.KUBERNETES_RELEASE_NAME
                                            + "-ease-backup",
                                        },
                                    }
                                ],
                                "containers": [
                                    {
                                        "name": name,
                                        "image": image,
                                        "imagePullPolicy": "Always",
                                        "env": [
                                            {"name": key, "value": value}
                                            for key, value in environment.items()
                                        ],
                                        "volumeMounts": [
                                            {
                                                "name": "script",
                                                "mountPath": "/opt/scripts",
                                            }
                                        ],
                                    }
                                ],
                                "restartPolicy": "Never",
                            }
                        }
                    }
                },
            },
        }

        return self.v1_batch.create_namespaced_cron_job(
            namespace=config.KUBERNETES_NAMESPACE, body=body
        )

    def _create_service(
        self, name: str, deployment_name: str
    ) -> kubernetes.client.V1Service:
        body = {
            "kind": "Service",
            "apiVersion": "v1",
            "metadata": {
                "name": name,
            },
            "spec": {
                "ports": [
                    {
                        "name": "rdp",
                        "protocol": "TCP",
                        "port": 3389,
                        "targetPort": 3389,
                    }
                ],
                "selector": {"app": deployment_name},
                "type": "ClusterIP",
            },
        }
        return self.v1_core.create_namespaced_service(config.KUBERNETES_NAMESPACE, body)

    def _create_persistent_volume_claim(self, username):
        body = {
            "apiVersion": "v1",
            "kind": "PersistentVolumeClaim",
            "metadata": {
                "name": self._get_claim_name(username),
            },
            "spec": {
                "accessModes": [config.KUBERNETES_STORAGE_ACCESS_MODE],
                "storageClassName": config.KUBERNETES_STORAGE_CLASS_NAME,
                "resources": {"requests": {"storage": "20Gi"}},
            },
        }
        try:
            self.v1_core.create_namespaced_persistent_volume_claim(
                config.KUBERNETES_NAMESPACE, body
            )
        except kubernetes.client.exceptions.ApiException as e:
            if e.status == 409:
                return
            raise

    def _get_claim_name(self, username: str) -> str:
        return (
            "persistent-session-"
            + username.replace("@", "-at-").replace(".", "-dot-").lower()
        )

    def _get_service(self, id: str):
        return self.v1_core.read_namespaced_service(id, config.KUBERNETES_NAMESPACE)

    def _delete_deployment(self, id: str) -> kubernetes.client.V1Status:
        try:
            return self.v1_apps.delete_namespaced_deployment(
                id, config.KUBERNETES_NAMESPACE
            )
        except kubernetes.client.exceptions.ApiException:
            log.exception("Error deleting deployment")

    def _delete_cronjob(self, id: str) -> kubernetes.client.V1Status:
        try:
            return self.v1_batch.delete_namespaced_cron_job(
                id, config.KUBERNETES_NAMESPACE
            )
        except kubernetes.client.exceptions.ApiException:
            log.exception("Error deleting cronjob")

    def _delete_service(self, id: str) -> kubernetes.client.V1Status:
        try:
            return self.v1_core.delete_namespaced_service(
                id, config.KUBERNETES_NAMESPACE
            )
        except kubernetes.client.exceptions.ApiException:
            log.exception("Error deleting service")

backend/t4cclient/core/operators/docker.py METASEP
import pathlib
import shutil
import typing as t

from t4cclient import config
from t4cclient.core.operators.abc import Operator

import docker


class DockerOperator(Operator):
    def __init__(self):
        self.client = docker.from_env()

    def start_persistent_session(
        self,
        username: str,
        password: str,
        repositories: t.List[str],
    ) -> t.Dict[str, t.Any]:
        path_to_workspace = pathlib.Path("/workspaces", username)
        if not path_to_workspace.exists():
            path_to_workspace.mkdir(mode=0o755)
            shutil.chown(path_to_workspace, user=1001380000)

        con = self.client.containers.run(
            image=config.PERSISTENT_IMAGE,
            volumes={
                f"{config.WORKSPACE_MOUNT_VOLUME}/workspaces/{username}": {
                    "bind": "/workspace",
                    "mode": "rw",
                }
            },
            ports={"3389/tcp": config.DOCKER_PORT_RANGE},
            environment={
                "RMT_PASSWORD": password,
                "T4C_REPOSITORIES": ",".join(repositories),
                "T4C_HOST": config.T4C_SERVER_HOST,
            },
            detach=True,
        )
        return self.__export_attrs_from_container(
            self.client.containers.get(con.attrs["Id"])
        )

    def start_readonly_session(
        self, password: str, git_url: str, git_revision: str, entrypoint: str
    ) -> t.Dict[str, t.Any]:
        con = self.client.containers.run(
            image=config.READONLY_IMAGE,
            ports={"3389/tcp": config.DOCKER_PORT_RANGE},
            environment={
                "RMT_PASSWORD": password,
                "GIT_USERNAME": config.GIT_USERNAME,
                "GIT_PASSWORD": config.GIT_PASSWORD,
                "GIT_URL": git_url,
                "GIT_REVISION": git_revision,
            },
            detach=True,
        )
        return self.__export_attrs_from_container(
            self.client.containers.get(con.attrs["Id"])
        )

    def get_session_state(self, id: str):
        try:
            return self.client.containers.get(id).attrs["State"]["Status"]
        except docker.errors.NotFound:
            return "removed"

    def kill_session(self, id: str):
        return self.client.containers.get(id).stop()

    def __export_attrs_from_container(self, container):
        return {
            "id": container.attrs["Id"],
            "ports": set(
                [
                    port["HostPort"]
                    for port in container.attrs["NetworkSettings"]
                    .get("Ports", {})
                    .get("3389/tcp", [])
                ]
            ),
            "created_at": container.attrs["Created"],
            "mac": container.attrs["NetworkSettings"]["MacAddress"],
            "host": config.DOCKER_HOST,
        }

backend/t4cclient/core/operators/abc.py METASEP
import abc
import typing as t
from datetime import datetime

from t4cclient.schemas.sessions import WorkspaceType


class Operator(abc.ABC):
    @classmethod
    @abc.abstractmethod
    def start_persistent_session(
        self,
        username: str,
        password: str,
        repositories: t.List[str],
    ) -> t.Dict[str, t.Any]:
        """Start / Create a session

        Parameters
        ---------
        username
            Username of the workspace user
        password
            Password for the remote connection
        repositories
            T4C Repositories that are predefined in the workspace

        Returns
        ------
            Dictionary with Session information.
        """

    @classmethod
    @abc.abstractmethod
    def start_readonly_session(
        self, password: str, git_url: str, git_revision: str, entrypoint: str
    ) -> t.Dict[str, t.Any]:
        """Start / Create a session

        Parameters
        ---------
        password
            Password for the remote connection
        git_url
            Git URL of the model that should be cloned
        git_branch
            Git Branch of the model that should be cloned

        Returns
        ------
            Dictionary with Session information.
        """

    @classmethod
    @abc.abstractmethod
    def get_session_state(self, id: str) -> str:
        """Get session state

        Paramters
        ---------
        id
            ID of the Session

        Returns
        ------
        state
            State of the current Session
        """

    @classmethod
    @abc.abstractmethod
    def kill_session(self, id: str) -> None:
        """Kill the session

        Paramters
        ---------
        id
            ID of the Session
        """

    @classmethod
    @abc.abstractmethod
    def get_session_logs(self, id: str) -> str:
        """Get session state

        Paramters
        ---------
        id
            ID of the Session

        Returns
        ------
        logs
            Logs of the current session
        """

    @classmethod
    @abc.abstractmethod
    def create_cronjob(
        self, image: str, environment: t.Dict[str, str], schedule="* * * * *"
    ) -> str:
        pass

    @classmethod
    @abc.abstractmethod
    def delete_cronjob(self, id: str) -> None:
        pass

    @classmethod
    @abc.abstractmethod
    def get_cronjob_last_run(self, id: str) -> str:
        pass

    @classmethod
    @abc.abstractmethod
    def get_cronjob_last_state(self, name: str) -> str:
        pass

    @classmethod
    @abc.abstractmethod
    def get_cronjob_last_starting_date(self, name: str) -> datetime | None:
        pass

    @classmethod
    @abc.abstractmethod
    def get_job_logs(self, id: str) -> str:
        pass

    @classmethod
    @abc.abstractmethod
    def trigger_cronjob(self, name: str) -> None:
        pass

backend/t4cclient/core/operators/__init__.py METASEP
from __future__ import annotations

from t4cclient.config import OPERATOR_TYPE
from t4cclient.core.operators.abc import Operator

from . import docker, k8s

OPERATORS = {
    "docker": docker.DockerOperator,
    "kubernetes": k8s.KubernetesOperator,
}
try:
    OPERATOR: Operator = OPERATORS[OPERATOR_TYPE]()
except KeyError:
    raise KeyError("Unsupported operator %s", OPERATOR_TYPE) from None

backend/t4cclient/core/oauth/jwt_bearer.py METASEP
import logging
import time
import typing as t

import requests
from fastapi import HTTPException, Request
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from jose import jwt
from pydantic import BaseModel
from t4cclient import config
from t4cclient.config import OAUTH_CLIENT_ID, OAUTH_ENDPOINT, USERNAME_CLAIM
from t4cclient.core.database import SessionLocal, users

log = logging.getLogger(__name__)


class JWTBearer(HTTPBearer):
    def __init__(self, auto_error: bool = True):
        super(JWTBearer, self).__init__(auto_error=auto_error)

    async def __call__(self, request: Request):
        credentials: HTTPAuthorizationCredentials = await super(
            JWTBearer, self
        ).__call__(request)
        if not credentials or credentials.scheme != "Bearer":
            if self.auto_error:
                raise HTTPException(
                    status_code=401,
                    detail="Not authenticated",
                    headers={"WWW-Authenticate": "Bearer"},
                )
            else:
                return None
        token_decoded = self.validate_token(credentials.credentials)
        self.initialize_user(token_decoded)
        return token_decoded

    def initialize_user(self, token_decoded: t.Dict[str, str]):
        with SessionLocal() as session:
            users.find_or_create_user(session, token_decoded[USERNAME_CLAIM])

    def validate_token(self, token: str) -> t.Dict[str, t.Any]:
        key = KeyStore.key_for_token(token)
        try:
            return jwt.decode(token, key.dict(), audience=OAUTH_CLIENT_ID)
        except jwt.ExpiredSignatureError:
            raise HTTPException(
                status_code=401,
                detail={
                    "err_code": "token_exp",
                    "reason": "The Signature of the token is expired. Please request a new access token.",
                },
            )
        except (jwt.JWTError, jwt.JWTClaimsError) as e:
            raise HTTPException(
                status_code=401,
                detail="The token verification failed. Please try again with another access token.",
            )


# Copied and adapted from https://github.com/marpaia/jwks/blob/master/jwks/jwks.py:


class _KeyStore:
    def __init__(
        self,
        *,
        jwks_uri: str,
        algorithms: t.List[str] = ["RS256"],
        key_refresh_interval=3600,
    ):
        self.jwks_uri = jwks_uri
        self.algorithms = algorithms
        self.public_keys = {}
        self.key_refresh_interval = key_refresh_interval
        self.public_keys_last_refreshed = 0
        self.refresh_keys()

    def keys_need_refresh(self) -> bool:
        return (
            time.time() - self.public_keys_last_refreshed
        ) > self.key_refresh_interval

    def refresh_keys(self) -> None:
        try:
            resp = requests.get(self.jwks_uri, timeout=config.REQUESTS_TIMEOUT)
        except Exception as e:
            log.error("Could not retrieve JWKS data from %s", self.jwks_uri)
            return
        jwks = JSONWebKeySet.parse_raw(resp.text)
        self.public_keys_last_refreshed = time.time()
        self.public_keys.clear()
        for key in jwks.keys:
            self.public_keys[key.kid] = key

    def key_for_token(self, token: str, *, in_retry: int = 0) -> t.Dict[str, t.Any]:
        # Before we do anything, the validation keys may need to be refreshed.
        # If so, refresh them.
        if self.keys_need_refresh():
            self.refresh_keys()

        # Try to extract the claims from the token so that we can use the key ID
        # to determine which key we should use to validate the token.
        try:
            unverified_claims = jwt.get_unverified_header(token)
        except Exception:
            raise InvalidTokenError("Unable to parse key ID from token")

        # See if we have the key identified by this key ID.
        try:
            return self.public_keys[unverified_claims["kid"]]
        except KeyError:
            # If we don't have this key and this is the first attempt (ie: we
            # haven't refreshed keys yet), then try to refresh the keys and try
            # again.
            if in_retry:
                raise KeyIDNotFoundError()
            self.refresh_keys()
            return self.key_for_token(token, in_retry=1)


def get_jwks_uri_for_azure_ad(authorization_endpoint=OAUTH_ENDPOINT):
    discoveryEndpoint = (
        f"{authorization_endpoint}/v2.0/.well-known/openid-configuration"
    )

    openid_config = requests.get(
        discoveryEndpoint,
        timeout=config.REQUESTS_TIMEOUT,
    ).json()
    return openid_config["jwks_uri"]


class JSONWebKey(BaseModel):
    # alg: str
    kty: str
    use: str
    n: str
    e: str
    kid: str
    x5t: str
    x5c: t.List[str]


class JSONWebKeySet(BaseModel):
    keys: t.List[JSONWebKey]


class InvalidTokenError(Exception):
    pass


class KeyIDNotFoundError(Exception):
    pass


# Our "singleton" key store:
KeyStore = _KeyStore(jwks_uri=get_jwks_uri_for_azure_ad())

backend/t4cclient/core/oauth/__init__.py METASEP
import typing as t

from requests_oauthlib import OAuth2Session
from t4cclient.config import (
    OAUTH_CLIENT_ID,
    OAUTH_CLIENT_SECRET,
    OAUTH_ENDPOINT,
    OAUTH_REDIRECT_URI,
    OAUTH_TOKEN_ENDPOINT,
)

auth_session = OAuth2Session(OAUTH_CLIENT_ID, redirect_uri=OAUTH_REDIRECT_URI)


def get_auth_redirect_url(state) -> t.Dict[str, str]:
    auth_url, state = auth_session.authorization_url(
        OAUTH_ENDPOINT + "/authorize", state=state, grant_type="authorization_code"
    )
    return {"auth_url": auth_url, "state": state}


def get_token(code: str) -> t.Dict[str, t.Any]:
    return auth_session.fetch_token(
        OAUTH_TOKEN_ENDPOINT,
        code=code,
        client_id=OAUTH_CLIENT_ID,
        client_secret=OAUTH_CLIENT_SECRET,
    )


def refresh_token(refresh_token: str) -> t.Dict[str, t.Any]:
    return auth_session.refresh_token(
        OAUTH_TOKEN_ENDPOINT,
        refresh_token=refresh_token,
        client_id=OAUTH_CLIENT_ID,
        client_secret=OAUTH_CLIENT_SECRET,
    )

class OAuthStub:
    def initiate_auth_code_flow(self, scopes, state):
        return get_auth_redirect_url(state)

    def acquire_token_by_auth_code_flow(self, auth_data, body, scopes=[]):
        get_token(body.code)

    def acquire_token_by_refresh_token(self, body, scopes=[]):
        ...

    def get_accounts(self):
        return []
    
    def remove_account(self, account):
        ...

backend/t4cclient/core/database/users.py METASEP
from sqlalchemy.orm import Session
from t4cclient.schemas.repositories.users import Role
from t4cclient.sql_models.users import DatabaseUser


def find_or_create_user(db: Session, username: str):
    user = get_user(db, username)
    if user:
        return user

    return create_user(db, username)


def get_user(db: Session, username: str):
    return db.query(DatabaseUser).filter(DatabaseUser.name == username).first()


def get_all_users(db: Session):
    return db.query(DatabaseUser).all()


def create_user(db: Session, username: str, role: Role = Role.USER):
    user = DatabaseUser(
        name=username,
        role=role,
        repositories=[],
    )
    db.add(user)
    db.commit()
    db.refresh(user)
    return user


def update_role_of_user(db: Session, username: str, role: Role):
    user = get_user(db, username)
    user.role = role
    db.commit()
    db.refresh(user)
    return user


def delete_user(db: Session, username: str):
    db.query(DatabaseUser).filter(DatabaseUser.name == username).delete()
    db.commit()

backend/t4cclient/core/database/sessions.py METASEP
from sqlalchemy.orm import Session
from t4cclient.sql_models.sessions import DatabaseSession


def get_sessions_for_user(db: Session, username: str):
    return (
        db.query(DatabaseSession).filter(DatabaseSession.owner_name == username).all()
    )


def get_sessions_for_repository(db: Session, repository: str):
    return (
        db.query(DatabaseSession).filter(DatabaseSession.repository == repository).all()
    )


def get_session_by_id(db: Session, id: str):
    return db.query(DatabaseSession).filter(DatabaseSession.id == id).first()


def get_all_sessions(db: Session):
    return db.query(DatabaseSession).all()


def create_session(db: Session, session: DatabaseSession):
    db.add(session)
    db.commit()
    db.refresh(session)
    return session


def delete_session(db: Session, session_id: str):
    db.query(DatabaseSession).filter(DatabaseSession.id == session_id).delete()
    db.commit()

backend/t4cclient/core/database/repository_users.py METASEP
from sqlalchemy.orm import Session
from t4cclient.schemas.repositories import (RepositoryUserPermission,
                                            RepositoryUserRole)
from t4cclient.sql_models.repositories import RepositoryUserAssociation


def get_users_of_repository(db: Session, repository_name: str):
    return (
        db.query(RepositoryUserAssociation)
        .filter(RepositoryUserAssociation.repository_name == repository_name)
        .all()
    )

def get_user_of_repository(db: Session, repository_name: str, username: str): 
    return (
        db.query(RepositoryUserAssociation)
        .filter(RepositoryUserAssociation.repository_name == repository_name)
        .filter(RepositoryUserAssociation.username == username)
        .first()
    )

def add_user_to_repository(
    db: Session,
    repository_name: str,
    role: RepositoryUserRole,
    username: str,
    permission: RepositoryUserPermission,
):
    association = RepositoryUserAssociation(
        repository_name=repository_name,
        username=username,
        role=role,
        permission=permission,
    )
    db.add(association)
    db.commit()
    db.refresh(association)
    return association


def change_role_of_user_in_repository(
    db: Session, repository_name: str, role: RepositoryUserRole, username: str
):
    repo_user = (
        db.query(RepositoryUserAssociation)
        .filter(RepositoryUserAssociation.repository_name == repository_name)
        .filter(RepositoryUserAssociation.username == username)
        .first()
    )
    if role == RepositoryUserRole.MANAGER:
        repo_user.permission = RepositoryUserPermission.WRITE
    repo_user.role = role
    db.commit()
    db.refresh(repo_user)
    return repo_user


def change_permission_of_user_in_repository(
    db: Session,
    repository_name: str,
    permission: RepositoryUserPermission,
    username: str,
):
    repo_user = (
        db.query(RepositoryUserAssociation)
        .filter(RepositoryUserAssociation.repository_name == repository_name)
        .filter(RepositoryUserAssociation.username == username)
        .first()
    )
    repo_user.permission = permission
    db.commit()
    db.refresh(repo_user)
    return repo_user


def delete_user_from_repository(db: Session, repository_name: str, username: str):
    db.query(RepositoryUserAssociation).filter(
        RepositoryUserAssociation.username == username
    ).filter(RepositoryUserAssociation.repository_name == repository_name).delete()
    db.commit()


def delete_all_repositories_for_user(db: Session, username: str):
    db.query(RepositoryUserAssociation).filter(
        RepositoryUserAssociation.username == username
    ).delete()
    db.commit()

backend/t4cclient/core/database/repositories.py METASEP
import typing as t

from sqlalchemy.orm import Session
from t4cclient.sql_models.repositories import DatabaseRepository


def get_repository(db: Session, name: str):
    return db.query(DatabaseRepository).filter(DatabaseRepository.name == name).first()


def get_all_repositories(db: Session) -> t.List[DatabaseRepository]:
    return db.query(DatabaseRepository).all()


def create_repository(db: Session, name: str):
    repo = DatabaseRepository(name=name, users=[])
    db.add(repo)
    db.commit()
    db.refresh(repo)
    return repo


def delete_repository(db: Session, name: str):
    db.query(DatabaseRepository).filter(DatabaseRepository.name == name).delete()
    db.commit()

backend/t4cclient/core/database/notices.py METASEP
from sqlalchemy.orm import Session
from t4cclient.schemas.notices import CreateNoticeRequest, NoticeResponse
from t4cclient.sql_models.notices import DatabaseNotice


def get_notice(db: Session, id: int):
    return db.query(DatabaseNotice).filter(DatabaseNotice.id == id).first()


def get_all_notices(db: Session):
    return db.query(DatabaseNotice).all()


def create_notice(db: Session, body: CreateNoticeRequest):
    notice = DatabaseNotice(**body.dict())
    db.add(notice)
    db.commit()
    db.refresh(notice)
    return notice


def delete_notice(db: Session, id: int):
    db.query(DatabaseNotice).filter(DatabaseNotice.id == id).delete()
    db.commit()

backend/t4cclient/core/database/__main__.py METASEP
import logging
import os
import pathlib

from alembic import command
from alembic.config import Config
from alembic.migration import MigrationContext
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from t4cclient import config
from t4cclient.core.database import Base, repositories, users
from t4cclient.schemas.repositories.users import Role

engine = create_engine(config.DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

LOGGER = logging.getLogger(__file__)


def migrate_db():
    if os.getenv("ALEMBIC_CONTEXT") != "1":
        root_dir = pathlib.Path(__file__).parents[2]

        # Get current revision of Database. If no revision is available, initialize the database.
        alembic_cfg = Config(root_dir / "alembic.ini")
        alembic_cfg.set_main_option("script_location", str(root_dir / "alembic"))
        alembic_cfg.set_main_option("sqlalchemy.url", config.DATABASE_URL)
        alembic_cfg.attributes["configure_logger"] = False

        engine = create_engine(config.DATABASE_URL)
        conn = engine.connect()

        context = MigrationContext.configure(conn)
        current_rev = context.get_current_revision()

        if current_rev:
            LOGGER.info("Upgrade database to head")
            command.upgrade(alembic_cfg, "head")
        else:
            LOGGER.info("Empty database detected.")
            Base.metadata.create_all(bind=engine)
            LOGGER.info("Database structure creation successful")
            command.stamp(alembic_cfg, "head")
            initialize_admin_user()
            initialize_default_repository()


def initialize_admin_user():
    LOGGER.info("Initialized adminuser " + config.INITIAL_ADMIN_USER)
    with SessionLocal() as db:
        users.create_user(db=db, username=config.INITIAL_ADMIN_USER, role=Role.ADMIN)


def initialize_default_repository():
    LOGGER.info("Initialized repository 'default'")
    with SessionLocal() as db:
        repositories.create_repository(db=db, name="default")

backend/t4cclient/core/database/__init__.py METASEP
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from t4cclient import config

engine = create_engine(config.DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()


def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

backend/t4cclient/alembic/versions/fc6250459067_use_project_id_as_reference_instead_of_.py METASEP
"""Use Project ID as reference instead of Project Name

Revision ID: fc6250459067
Revises: 377b60de4441
Create Date: 2021-09-03 15:29:23.047537

"""
import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision = 'fc6250459067'
down_revision = '377b60de4441'
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('git_models', sa.Column('project_id', sa.Integer(), nullable=False))
    op.drop_constraint('git_models_project_name_fkey', 'git_models', type_='foreignkey')
    op.create_foreign_key(None, 'git_models', 'projects', ['project_id'], ['id'])
    op.drop_column('git_models', 'project_name')
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('git_models', sa.Column('project_name', sa.VARCHAR(), autoincrement=False, nullable=False))
    op.drop_constraint(None, 'git_models', type_='foreignkey')
    op.create_foreign_key('git_models_project_name_fkey', 'git_models', 'projects', ['project_name'], ['name'])
    op.drop_column('git_models', 'project_id')
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/f3efdcedfdde_add_read_write_access.py METASEP
"""Add read/write access

Revision ID: f3efdcedfdde
Revises: d3c85f34aae6
Create Date: 2021-08-24 12:43:46.471793

"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = "f3efdcedfdde"
down_revision = "d3c85f34aae6"
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    repositoryuserpermission = postgresql.ENUM(
        "READ", "WRITE", name="repositoryuserpermission"
    )
    repositoryuserpermission.create(op.get_bind())

    op.add_column(
        "repository_user_association",
        sa.Column(
            "permission",
            sa.Enum("READ", "WRITE", name="repositoryuserpermission"),
            nullable=True,
        ),
    )
    op.execute("UPDATE repository_user_association SET permission='WRITE'")
    op.alter_column("repository_user_association", "permission", nullable=False)

    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column("repository_user_association", "permission")

    repositoryuserpermission = postgresql.ENUM(
        "READ", "WRITE", name="repositoryuserpermission"
    )
    repositoryuserpermission.drop(op.get_bind())
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/f3ed32b2cfb0_add_jenkinspipeline.py METASEP
"""Add JenkinsPipeline

Revision ID: f3ed32b2cfb0
Revises: fc6250459067
Create Date: 2021-09-06 16:24:02.228776

"""
import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision = 'f3ed32b2cfb0'
down_revision = 'fc6250459067'
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('jenkins',
    sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
    sa.Column('name', sa.String(), nullable=True),
    sa.Column('git_model_id', sa.Integer(), nullable=False),
    sa.ForeignKeyConstraint(['git_model_id'], ['git_models.id'], ),
    sa.PrimaryKeyConstraint('id', 'git_model_id')
    )
    op.create_index(op.f('ix_jenkins_id'), 'jenkins', ['id'], unique=False)
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f('ix_jenkins_id'), table_name='jenkins')
    op.drop_table('jenkins')
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/d7fe491603c3_add_cascades.py METASEP
"""Add cascades

Revision ID: d7fe491603c3
Revises: 7bdfe4e65e81
Create Date: 2021-09-08 10:38:53.633259

"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = 'd7fe491603c3'
down_revision = '9259062f0f62'
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint('git_models_repository_name_fkey', 'git_models', type_='foreignkey')
    op.drop_constraint('git_models_project_id_fkey', 'git_models', type_='foreignkey')
    op.create_foreign_key(None, 'git_models', 'projects', ['project_id'], ['id'], ondelete='CASCADE')
    op.create_foreign_key(None, 'git_models', 'repositories', ['repository_name'], ['name'], ondelete='CASCADE')
    op.drop_constraint('jenkins_git_model_id_fkey', 'jenkins', type_='foreignkey')
    op.create_foreign_key(None, 'jenkins', 'git_models', ['git_model_id'], ['id'], ondelete='CASCADE')
    op.drop_constraint('projects_repository_name_fkey', 'projects', type_='foreignkey')
    op.create_foreign_key(None, 'projects', 'repositories', ['repository_name'], ['name'], ondelete='CASCADE')
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint(None, 'projects', type_='foreignkey')
    op.create_foreign_key('projects_repository_name_fkey', 'projects', 'repositories', ['repository_name'], ['name'])
    op.drop_constraint(None, 'jenkins', type_='foreignkey')
    op.create_foreign_key('jenkins_git_model_id_fkey', 'jenkins', 'git_models', ['git_model_id'], ['id'])
    op.drop_constraint(None, 'git_models', type_='foreignkey')
    op.drop_constraint(None, 'git_models', type_='foreignkey')
    op.create_foreign_key('git_models_project_id_fkey', 'git_models', 'projects', ['project_id'], ['id'])
    op.create_foreign_key('git_models_repository_name_fkey', 'git_models', 'repositories', ['repository_name'], ['name'])
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/d6a23ac7f263_add_credentials_for_gitmodels.py METASEP
"""Add credentials for gitmodels

Revision ID: d6a23ac7f263
Revises: caa0ecb7b28d
Create Date: 2022-03-04 11:47:41.439896

"""
import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision = 'd6a23ac7f263'
down_revision = 'caa0ecb7b28d'
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('EASEBackup', sa.Column('reference', sa.String(), nullable=True))
    op.add_column('git_models', sa.Column('username', sa.String(), nullable=True))
    op.add_column('git_models', sa.Column('password', sa.String(), nullable=True))
    op.drop_constraint('git_models_project_id_fkey', 'git_models', type_='foreignkey')
    op.drop_column('git_models', 'project_id')
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('git_models', sa.Column('project_id', sa.INTEGER(), autoincrement=False, nullable=True))
    op.create_foreign_key('git_models_project_id_fkey', 'git_models', 'projects', ['project_id'], ['id'], ondelete='CASCADE')
    op.drop_column('git_models', 'password')
    op.drop_column('git_models', 'username')
    op.drop_column('EASEBackup', 'reference')
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/d3c85f34aae6_add_host_to_session.py METASEP
"""Add host to Session

Revision ID: d3c85f34aae6
Revises: 2eeda6a7bd66
Create Date: 2021-08-24 08:15:01.443971

"""
import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision = 'd3c85f34aae6'
down_revision = '2eeda6a7bd66'
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('sessions', sa.Column('host', sa.String(), nullable=True))
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('sessions', 'host')
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/caa0ecb7b28d_add_ease_backup_table.py METASEP
"""Add EASE backup table

Revision ID: caa0ecb7b28d
Revises: 687484695147
Create Date: 2022-03-03 14:20:15.424650

"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "caa0ecb7b28d"
down_revision = "687484695147"
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "EASEBackup",
        sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
        sa.Column("gitmodel", sa.Integer(), nullable=True),
        sa.Column("t4cmodel", sa.Integer(), nullable=True),
        sa.Column("project", sa.String(), nullable=False),
        sa.ForeignKeyConstraint(
            ["gitmodel"],
            ["git_models.id"],
        ),
        sa.ForeignKeyConstraint(
            ["project"],
            ["repositories.name"],
        ),
        sa.ForeignKeyConstraint(
            ["t4cmodel"],
            ["projects.id"],
        ),
        sa.PrimaryKeyConstraint("id", "project"),
    )
    op.create_index(op.f("ix_EASEBackup_id"), "EASEBackup", ["id"], unique=False)
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f("ix_EASEBackup_id"), table_name="EASEBackup")
    op.drop_table("EASEBackup")
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/c926d3e402a8_merge_branches_permissions_and_.py METASEP
"""Merge branches permissions and guacamole-rework

Revision ID: c926d3e402a8
Revises: 1b4c1dc944d6, 52aec4f341a5
Create Date: 2021-08-30 12:27:00.888738

"""
import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision = 'c926d3e402a8'
down_revision = ('1b4c1dc944d6', '52aec4f341a5')
branch_labels = None
depends_on = None


def upgrade():
    pass


def downgrade():
    pass

backend/t4cclient/alembic/versions/bfafdd03e30c_add_git_models_for_repositories.py METASEP
"""Add Git models for repositories

Revision ID: bfafdd03e30c
Revises: f3efdcedfdde
Create Date: 2021-08-24 12:54:08.768420

"""
import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision = 'bfafdd03e30c'
down_revision = 'f3efdcedfdde'
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('git_models',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('name', sa.String(), nullable=True),
    sa.Column('path', sa.String(), nullable=True),
    sa.Column('entrypoint', sa.String(), nullable=True),
    sa.Column('revision', sa.String(), nullable=True),
    sa.Column('primary', sa.Boolean(), nullable=True),
    sa.Column('repository_id', sa.Integer(), nullable=True),
    sa.ForeignKeyConstraint(['repository_id'], ['repositories.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_git_models_id'), 'git_models', ['id'], unique=False)
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f('ix_git_models_id'), table_name='git_models')
    op.drop_table('git_models')
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/9259062f0f62_remove_unique_constraint_for_project.py METASEP
"""Remove unique constraint for project

Revision ID: 9259062f0f62
Revises: f3ed32b2cfb0
Create Date: 2021-09-07 18:19:57.816445

"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "9259062f0f62"
down_revision = "f3ed32b2cfb0"
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index("ix_projects_name", table_name="projects")
    op.create_index(op.f("ix_projects_name"), "projects", ["name"], unique=False)
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f("ix_projects_name"), table_name="projects")
    op.create_index("ix_projects_name", "projects", ["name"], unique=False)
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/6a8bdec1dccb_add_databaseproject.py METASEP
"""Add DatabaseProject

Revision ID: 6a8bdec1dccb
Revises: c926d3e402a8
Create Date: 2021-09-02 16:10:04.355412

"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "6a8bdec1dccb"
down_revision = "c926d3e402a8"
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "projects",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("name", sa.String(), nullable=True),
        sa.Column("repository_name", sa.String(), nullable=True),
        sa.ForeignKeyConstraint(
            ["repository_name"],
            ["repositories.name"],
        ),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(op.f("ix_projects_id"), "projects", ["id"], unique=False)
    op.create_index(op.f("ix_projects_name"), "projects", ["name"], unique=True)
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f("ix_projects_name"), table_name="projects")
    op.drop_index(op.f("ix_projects_id"), table_name="projects")
    op.drop_table("projects")
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/687484695147_add_persistent_enum.py METASEP
"""Add Persistent Enum

Revision ID: 687484695147
Revises: e23ab83c2195
Create Date: 2021-10-07 15:09:50.518254

"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = "687484695147"
down_revision = "d7fe491603c3"
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    workspacetype = postgresql.ENUM("PERSISTENT", "READONLY", name="workspacetype")
    workspacetype.create(op.get_bind())
    op.add_column(
        "sessions",
        sa.Column(
            "type",
            sa.Enum("PERSISTENT", "READONLY", name="workspacetype"),
            nullable=False,
            server_default="PERSISTENT",
        ),
    )
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column("sessions", "type")

    workspacetype = postgresql.ENUM("PERSISTENT", "READONLY", name="workspacetype")
    workspacetype.drop(op.get_bind())
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/52aec4f341a5_use_repository_name_instead_of_.py METASEP
"""Use repository_name instead of repository_id as Foreign Key

Revision ID: 52aec4f341a5
Revises: bfafdd03e30c
Create Date: 2021-08-24 18:23:41.922890

"""
import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision = '52aec4f341a5'
down_revision = 'bfafdd03e30c'
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('git_models', sa.Column('repository_name', sa.String(), nullable=False))
    op.drop_constraint('git_models_repository_id_fkey', 'git_models', type_='foreignkey')
    op.create_foreign_key(None, 'git_models', 'repositories', ['repository_name'], ['name'])
    op.drop_column('git_models', 'repository_id')
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('git_models', sa.Column('repository_id', sa.INTEGER(), autoincrement=False, nullable=True))
    op.drop_constraint(None, 'git_models', type_='foreignkey')
    op.create_foreign_key('git_models_repository_id_fkey', 'git_models', 'repositories', ['repository_id'], ['id'])
    op.drop_column('git_models', 'repository_name')
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/377b60de4441_link_git_repositories_with_projects.py METASEP
"""Link Git Repositories with Projects

Revision ID: 377b60de4441
Revises: 6a8bdec1dccb
Create Date: 2021-09-03 12:58:16.636950

"""
import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision = '377b60de4441'
down_revision = '6a8bdec1dccb'
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('git_models', sa.Column('project_name', sa.String(), nullable=False))
    op.create_foreign_key(None, 'git_models', 'projects', ['project_name'], ['name'])
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint(None, 'git_models', type_='foreignkey')
    op.drop_column('git_models', 'project_name')
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/2eeda6a7bd66_add_notices_datastructures.py METASEP
"""Add notices datastructures

Revision ID: 2eeda6a7bd66
Revises: 279ec954b302
Create Date: 2021-08-23 14:05:20.897134

"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "2eeda6a7bd66"
down_revision = "279ec954b302"
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "notices",
        sa.Column("id", sa.Integer(), nullable=False),
        sa.Column("title", sa.String(), nullable=True),
        sa.Column("message", sa.String(), nullable=True),
        sa.Column(
            "level",
            sa.Enum(
                "PRIMARY",
                "SECONDARY",
                "SUCCESS",
                "DANGER",
                "WARNING",
                "INFO",
                "ALERT",
                name="noticelevel",
            ),
            nullable=True,
        ),
        sa.Column("scope", sa.String(), nullable=True),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(op.f("ix_notices_id"), "notices", ["id"], unique=False)
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f("ix_notices_id"), table_name="notices")
    op.drop_table("notices")
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/279ec954b302_session_add_passwords_for_rdp_and_.py METASEP
"""session: add passwords for rdp and guacamole

Revision ID: 279ec954b302
Revises: 
Create Date: 2021-08-12 23:01:08.764707

"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = '279ec954b302'
down_revision = None
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('sessions', sa.Column('rdp_password', sa.String(), nullable=True))
    op.add_column('sessions', sa.Column('guacamole_password', sa.String(), nullable=True))
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('sessions', 'guacamole_password')
    op.drop_column('sessions', 'rdp_password')
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/1b4c1dc944d6_remove_rdp_username.py METASEP
"""Remove RDP Username

Revision ID: 1b4c1dc944d6
Revises: d3c85f34aae6
Create Date: 2021-08-26 16:41:03.205051

"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "1b4c1dc944d6"
down_revision = "d3c85f34aae6"
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column("sessions", "rdp_username")
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column(
        "sessions",
        sa.Column("rdp_username", sa.VARCHAR(), autoincrement=False, nullable=True),
    )
    # ### end Alembic commands ###

backend/t4cclient/alembic/versions/0a16fb85f762_add_t4c_username_to_ease_backup.py METASEP
"""Add t4c username to ease backup

Revision ID: 0a16fb85f762
Revises: d6a23ac7f263
Create Date: 2022-03-04 14:00:41.976888

"""
import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision = '0a16fb85f762'
down_revision = 'd6a23ac7f263'
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('EASEBackup', sa.Column('username', sa.String(), nullable=True))
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('EASEBackup', 'username')
    # ### end Alembic commands ###

frontend/src/environments/environment.ts METASEP
export const environment = {
  production: true,
  backend_url: '/api/v1',
  privacy: 'https://example.com/privacy',
  imprint: 'https://example.com/imprint',
};

frontend/src/assets/.gitkeep METASEP

frontend/src/app/schemes.ts METASEP
export interface Session {
  ports: Array<string>;
  created_at: string;
  id: string;
  type: 'persistent' | 'readonly';
  rdp_username: string;
  rdp_password: string;
  guacamole_username: string;
  guacamole_password: string;
  guacamole_connection_id: string;
  repository: string;
  state: string;
  owner: string;
  mac: string;
}

export interface User {
  id: number;
  name: string;
  role: 'user' | 'administrator';
}

export interface RepositoryUser {
  repository_name: string;
  username: string;
  permission: 'read' | 'write';
  role: 'user' | 'manager' | 'administrator';
}

export interface SessionsUsage {
  free: number;
  total: number;
  errors: Array<string>;
}

frontend/src/app/app.module.ts METASEP
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { SessionOverviewComponent } from './session-overview/session-overview.component';
import { MatTableModule } from '@angular/material/table';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { HomeComponent } from './home/home.component';
import { HeaderComponent } from './header/header.component';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { SessionCreatedComponent } from './session-created/session-created.component';
import { MatCardModule } from '@angular/material/card';
import { MatSelectModule } from '@angular/material/select';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ClipboardModule } from '@angular/cdk/clipboard';
import { AuthComponent } from './auth/auth/auth.component';
import { AuthInterceptor } from './auth/http-interceptor/auth.interceptor';
import { GuacamoleComponent } from './session-created/guacamole/guacamole.component';
import { RDPComponent } from './session-created/rdp/rdp.component';
import { NoRepositoryComponent } from './home/no-repository/no-repository.component';
import { RequestSessionComponent } from './home/request-session/request-session.component';
import { SettingsComponent } from './settings/settings.component';
import { AdminSettingsComponent } from './settings/admin-settings/admin-settings.component';
import { RepositoryManagerSettingsComponent } from './settings/repository-manager-settings/repository-manager-settings.component';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { RepositorySettingsComponent } from './settings/repository-manager-settings/repository-settings/repository-settings.component';
import { MatListModule } from '@angular/material/list';
import { ActiveSessionsComponent } from './active-sessions/active-sessions.component';
import { LogoutComponent } from './auth/logout/logout/logout.component';
import { DeleteSessionDialogComponent } from './delete-session-dialog/delete-session-dialog.component';
import { MatDialogModule } from '@angular/material/dialog';
import { UserSettingsComponent } from './settings/user-settings/user-settings.component';
import { NoticeComponent } from './notice/notice.component';
import { MatExpansionModule } from '@angular/material/expansion';
import { ReconnectDialogComponent } from './active-sessions/reconnect-dialog/reconnect-dialog.component';
import { AlertSettingsComponent } from './settings/admin-settings/alert-settings/alert-settings.component';
import { AdminUserSettingsComponent } from './settings/admin-settings/admin-user-settings/admin-user-settings.component';
import { GitModelSettingsComponent } from './settings/repository-manager-settings/repository-settings/model-source/git-model-settings/git-model-settings.component';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { RepositorySyncSettingsComponent } from './settings/admin-settings/repository-sync-settings/repository-sync-settings.component';
import { T4CRepoSettingsComponent } from './settings/repository-manager-settings/repository-settings/model-source/t4c-repo-settings/t4c-repo-settings.component';
import { RepositoryUserSettingsComponent } from './settings/repository-manager-settings/repository-settings/repository-user-settings/repository-user-settings.component';
import { ProjectDeletionDialogComponent } from './settings/repository-manager-settings/repository-settings/model-source/t4c-repo-settings/project-deletion-dialog/project-deletion-dialog.component';
import { SimplebarAngularModule } from 'simplebar-angular';
import { GitModelDeletionDialogComponent } from './settings/repository-manager-settings/repository-settings/model-source/git-model-settings/git-model-deletion-dialog/git-model-deletion-dialog.component';
import { OverlayModule } from '@angular/cdk/overlay';
import { WarningComponent } from './home/request-session/warning/warning.component';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { WhitespaceUrlInterceptor } from './services/encoder/encoder.interceptor';
import { MatMenuModule } from '@angular/material/menu';
import { WorkspaceComponent } from './workspace/workspace.component';
import { FooterComponent } from './footer/footer.component';
import { TermsConditionsComponent } from './footer/terms-conditions/terms-conditions.component';
import { LegalComponent } from './footer/legal/legal.component';
import { LogoutRedirectComponent } from './auth/logout/logout-redirect/logout-redirect.component';
import { CreateRepositoryComponent } from './settings/admin-settings/create-repository/create-repository.component';
import { SessionCreationProgressComponent } from './session-creation-progress/session-creation-progress.component';
import { SessionProgressIconComponent } from './session-creation-progress/session-progress-icon/session-progress-icon.component';
import { LicencesComponent } from './session-overview/licences/licences.component';
import { BackupSettingsComponent } from './settings/repository-manager-settings/repository-settings/backup-settings/backup-settings.component';
import { GitBackupSettingsComponent } from './settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/ease-backup-settings.component';
import { JenkinsBackupSettingsComponent } from './settings/repository-manager-settings/repository-settings/backup-settings/jenkins-backup-settings/jenkins-backup-settings.component';
import { MatTabsModule } from '@angular/material/tabs';
import { CreateEASEBackupComponent } from './settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/create-ease-backup/create-ease-backup.component';
import { ModelSourceComponent } from './settings/repository-manager-settings/repository-settings/model-source/model-source.component';
import { ViewLogsDialogComponent } from './settings/repository-manager-settings/repository-settings/backup-settings/ease-backup-settings/view-logs-dialog/view-logs-dialog.component';

@NgModule({
  declarations: [
    AppComponent,
    SessionOverviewComponent,
    HomeComponent,
    HeaderComponent,
    SessionCreatedComponent,
    AuthComponent,
    GuacamoleComponent,
    RDPComponent,
    NoRepositoryComponent,
    RequestSessionComponent,
    SettingsComponent,
    AdminSettingsComponent,
    RepositoryManagerSettingsComponent,
    RepositorySettingsComponent,
    ActiveSessionsComponent,
    LogoutComponent,
    DeleteSessionDialogComponent,
    UserSettingsComponent,
    NoticeComponent,
    ReconnectDialogComponent,
    AlertSettingsComponent,
    AdminUserSettingsComponent,
    GitModelSettingsComponent,
    RepositorySyncSettingsComponent,
    T4CRepoSettingsComponent,
    RepositoryUserSettingsComponent,
    ProjectDeletionDialogComponent,
    GitModelDeletionDialogComponent,
    WarningComponent,
    WorkspaceComponent,
    FooterComponent,
    TermsConditionsComponent,
    LegalComponent,
    LogoutRedirectComponent,
    CreateRepositoryComponent,
    SessionCreationProgressComponent,
    SessionProgressIconComponent,
    LicencesComponent,
    BackupSettingsComponent,
    GitBackupSettingsComponent,
    JenkinsBackupSettingsComponent,
    CreateEASEBackupComponent,
    ModelSourceComponent,
    ViewLogsDialogComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatTableModule,
    HttpClientModule,
    MatToolbarModule,
    MatButtonModule,
    MatIconModule,
    MatProgressSpinnerModule,
    MatCardModule,
    MatSelectModule,
    ReactiveFormsModule,
    ClipboardModule,
    MatFormFieldModule,
    MatInputModule,
    MatListModule,
    MatDialogModule,
    MatExpansionModule,
    MatCheckboxModule,
    MatSnackBarModule,
    FormsModule,
    SimplebarAngularModule,
    OverlayModule,
    MatSlideToggleModule,
    MatMenuModule,
    MatTabsModule,
  ],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: WhitespaceUrlInterceptor,
      multi: true,
    },
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

frontend/src/app/app.component.ts METASEP
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { UserService } from './services/user/user.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  title = 'Capella Collaboration Plattform';
  header = true;
  footer = true;
  notice = true;

  constructor(private router: Router) {}

  ngOnInit(): void {}

  updateComponents(): void {
    switch (this.router.url.split('?')[0]) {
      case '/auth':
      case '/logout': {
        this.header = false;
        this.footer = false;
        this.notice = false;
        break;
      }
      default: {
        this.header = true;
        this.footer = true;
        this.notice = true;
      }
    }
  }

  updateTitle(): void {
    switch (this.router.url) {
      case '/settings': {
        this.title = 'Settings';
        break;
      }
      case '/': {
        this.title = 'Workspaces';
        break;
      }
      case '/overview': {
        this.title = 'Session Overview';
        break;
      }
      default: {
        this.title = 'Capella Collaboration Manager';
      }
    }
  }

  changedRoute(): void {
    this.updateTitle();
    this.updateComponents();
  }
}

frontend/src/app/app.component.spec.ts METASEP
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';

describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  });

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });

  it(`should have as title 't4cclient'`, () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app.title).toEqual('t4cclient');
  });

  it('should render title', () => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    const compiled = fixture.nativeElement;
    expect(compiled.querySelector('.content span').textContent).toContain('t4cclient app is running!');
  });
});

frontend/src/app/app.component.html METASEP
<div class="overall-wrapper">
  <app-header *ngIf="header" [title]="title"></app-header>
  <app-notice *ngIf="notice"></app-notice>
  <div class="wrapper">
    <router-outlet (activate)="changedRoute()"></router-outlet>
  </div>
  <app-footer *ngIf="footer" class="footer"></app-footer>
  <app-legal></app-legal>
</div>

frontend/src/app/app.component.css METASEP
.wrapper {
  margin: 10px;
  flex: 1;
}

.overall-wrapper {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

frontend/src/app/app-routing.module.ts METASEP
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ActiveSessionsComponent } from './active-sessions/active-sessions.component';
import { AuthGuardService } from './auth/auth-guard/auth-guard.service';
import { AuthRedirectComponent } from './auth/auth-redirect/auth-redirect.component';
import { AuthComponent } from './auth/auth/auth.component';
import { LogoutRedirectComponent } from './auth/logout/logout-redirect/logout-redirect.component';
import { LogoutComponent } from './auth/logout/logout/logout.component';
import { HomeComponent } from './home/home.component';
import { SessionOverviewComponent } from './session-overview/session-overview.component';
import { CreateRepositoryComponent } from './settings/admin-settings/create-repository/create-repository.component';
import { RepositorySettingsComponent } from './settings/repository-manager-settings/repository-settings/repository-settings.component';
import { SettingsComponent } from './settings/settings.component';

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    canActivate: [AuthGuardService],
  },
  {
    path: 'active-sessions',
    component: ActiveSessionsComponent,
    canActivate: [AuthGuardService],
  },
  {
    path: 'overview',
    component: SessionOverviewComponent,
    canActivate: [AuthGuardService],
  },
  { path: 'auth', component: AuthComponent },
  { path: 'oauth2/callback', component: AuthRedirectComponent },
  {
    path: 'settings',
    component: SettingsComponent,
    canActivate: [AuthGuardService],
  },
  {
    path: 'settings/projects/create',
    component: CreateRepositoryComponent,
    canActivate: [AuthGuardService],
  },
  {
    path: 'settings/projects/:repository',
    component: RepositorySettingsComponent,
    canActivate: [AuthGuardService],
  },
  {
    path: 'logout/redirect',
    component: LogoutRedirectComponent,
  },
  {
    path: 'logout',
    component: LogoutComponent,
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

backend/t4cclient/alembic/script.py.mako METASEP
"""${message}

Revision ID: ${up_revision}
Revises: ${down_revision | comma,n}
Create Date: ${create_date}

"""
import sqlalchemy as sa
from alembic import op
${imports if imports else ""}

# revision identifiers, used by Alembic.
revision = ${repr(up_revision)}
down_revision = ${repr(down_revision)}
branch_labels = ${repr(branch_labels)}
depends_on = ${repr(depends_on)}


def upgrade():
    ${upgrades if upgrades else "pass"}


def downgrade():
    ${downgrades if downgrades else "pass"}

backend/t4cclient/alembic/README METASEP
Generic single-database configuration.
backend/t4cclient/sql_models/users.py METASEP
from sqlalchemy import Column, Enum, Integer, String
from sqlalchemy.orm import relationship
from t4cclient.core.database import Base
from t4cclient.schemas.repositories.users import Role


class DatabaseUser(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, unique=True, index=True)
    role = Column(Enum(Role))
    repositories = relationship(
        "RepositoryUserAssociation",
        back_populates="user",
    )
    sessions = relationship(
        "DatabaseSession",
        back_populates="owner",
    )

backend/t4cclient/sql_models/sessions.py METASEP
from sqlalchemy import ARRAY, TIMESTAMP, Column, Enum, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from t4cclient.core.database import Base
from t4cclient.schemas.repositories import RepositoryUserPermission
from t4cclient.schemas.sessions import WorkspaceType


class DatabaseSession(Base):
    __tablename__ = "sessions"

    id = Column(String, primary_key=True, index=True)
    owner_name = Column(String, ForeignKey("users.name"))
    owner = relationship("DatabaseUser")
    ports = Column(ARRAY(Integer))
    created_at = Column(TIMESTAMP)
    rdp_password = Column(String)
    guacamole_username = Column(String)
    guacamole_password = Column(String)
    guacamole_connection_id = Column(String)
    host = Column(String)
    type = Column(Enum(WorkspaceType), nullable=False)
    repository = Column(String)
    mac = Column(String)

backend/t4cclient/sql_models/repositories.py METASEP
from sqlalchemy import Boolean, Column, Enum, ForeignKey, Integer, String, Table
from sqlalchemy.orm import relationship
from t4cclient.core.database import Base
from t4cclient.schemas.repositories import RepositoryUserPermission, RepositoryUserRole


class RepositoryUserAssociation(Base):
    __tablename__ = "repository_user_association"

    username = Column(ForeignKey("users.name"), primary_key=True)
    repository_name = Column(ForeignKey("repositories.name"), primary_key=True)
    user = relationship("DatabaseUser", back_populates="repositories")
    repository = relationship("DatabaseRepository", back_populates="users")
    permission = Column(Enum(RepositoryUserPermission), nullable=False)
    role = Column(Enum(RepositoryUserRole))


class DatabaseRepository(Base):
    __tablename__ = "repositories"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, unique=True, index=True)
    users = relationship(
        "RepositoryUserAssociation",
        back_populates="repository",
    )
    projects = relationship("DatabaseProject", back_populates="repository")
    git_models = relationship("DB_GitModel", back_populates="repository")

backend/t4cclient/sql_models/notices.py METASEP
from sqlalchemy.sql.schema import Column
from sqlalchemy.sql.sqltypes import Enum, Integer, String
from t4cclient.core.database import Base
from t4cclient.schemas.notices import NoticeLevel


class DatabaseNotice(Base):
    __tablename__ = "notices"

    id = Column(Integer, primary_key=True, index=True)
    title = Column(String)
    message = Column(String)
    level = Column(Enum(NoticeLevel))
    scope = Column(String)

backend/t4cclient/sql_models/__init__.py METASEP
# These import statements of the models are required and should not be removed! (SQLAlchemy will not load the models otherwise)
from . import notices, repositories, sessions, users

backend/t4cclient/schemas/sessions.py METASEP
import datetime
import enum
import typing as t

from pydantic import BaseModel
from t4cclient.schemas.repositories import RepositoryUserPermission


class WorkspaceType(enum.Enum):
    PERSISTENT = "persistent"
    READONLY = "readonly"


class GetSessionsResponse(BaseModel):
    id: str
    type: WorkspaceType
    ports: t.List[str]
    created_at: datetime.datetime
    owner: str
    repository: t.Optional[str]
    state: str
    guacamole_username: str
    guacamole_connection_id: str
    last_seen: str
    mac: str

    class Config:
        orm_mode = True


class AdvancedSessionResponse(GetSessionsResponse):
    rdp_password: str

    class Config:
        orm_mode = True


class PostSessionRequest(BaseModel):
    type: WorkspaceType
    repository: t.Optional[str]

    class Config:
        orm_mode = True


class GetSessionUsageResponse(BaseModel):
    free: int
    total: int
    errors: t.List[str]

    class Config:
        orm_mode = True

backend/t4cclient/schemas/oauth.py METASEP
from pydantic import BaseModel


class TokenRequest(BaseModel):
    code: str
    state: str

class RefreshTokenRequest(BaseModel): 
    refresh_token: str

backend/t4cclient/schemas/notices.py METASEP
import enum

from pydantic import BaseModel


class NoticeLevel(enum.Enum):
    PRIMARY = "primary"
    SECONDARY = "secondary"
    SUCCESS = "success"
    DANGER = "danger"
    WARNING = "warning"
    INFO = "info"
    ALERT = "alert"


class CreateNoticeRequest(BaseModel):
    level: NoticeLevel
    title: str
    message: str
    scope: str

    class Config:
        orm_mode = True


class NoticeResponse(CreateNoticeRequest):
    id: int

backend/t4cclient/schemas/guacamole.py METASEP
from pydantic import BaseModel


class GuacamoleAuthentication(BaseModel):
    token: str
    url: str

    class Config:
        orm_mode = True

backend/t4cclient/schemas/__init__.py METASEP

backend/t4cclient/routes/users.py METASEP
import typing as t

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from t4cclient.config import USERNAME_CLAIM
from t4cclient.core.database import get_db, repository_users, users
from t4cclient.core.oauth.database import is_admin, verify_admin
from t4cclient.core.oauth.jwt_bearer import JWTBearer
from t4cclient.routes.open_api_configuration import AUTHENTICATION_RESPONSES
from t4cclient.routes.sessions import inject_attrs_in_sessions
from t4cclient.schemas.repositories.users import (
    GetUserResponse,
    PatchUserRoleRequest,
    Role,
)
from t4cclient.schemas.sessions import AdvancedSessionResponse

router = APIRouter()


@router.get(
    "/", response_model=t.List[GetUserResponse], responses=AUTHENTICATION_RESPONSES
)
def get_users(token=Depends(JWTBearer()), db: Session = Depends(get_db)):
    verify_admin(token, db)
    return users.get_all_users(db)


@router.post("/", response_model=GetUserResponse, responses=AUTHENTICATION_RESPONSES)
def create_user(token=Depends(JWTBearer()), db: Session = Depends(get_db)):
    return users.create_user(db, token[USERNAME_CLAIM])


@router.get(
    "/{username}", response_model=GetUserResponse, responses=AUTHENTICATION_RESPONSES
)
def get_user(username: str, db: Session = Depends(get_db), token=Depends(JWTBearer())):
    if username != token[USERNAME_CLAIM] and not is_admin(token, db):
        raise HTTPException(
            status_code=403,
            detail="The username does not match with your username. You have to be administrator to see other users.",
        )
    return users.get_user(db=db, username=username)


@router.delete("/{username}", status_code=204, responses=AUTHENTICATION_RESPONSES)
def delete_user(
    username: str, db: Session = Depends(get_db), token=Depends(JWTBearer())
):
    verify_admin(token, db)
    repository_users.delete_all_repositories_for_user(db, username)
    users.delete_user(db=db, username=username)


@router.patch("/{username}/roles", responses=AUTHENTICATION_RESPONSES)
def update_role_of_user(
    username: str,
    body: PatchUserRoleRequest,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    verify_admin(token, db)
    users.find_or_create_user(db, username)
    if body.role == Role.ADMIN:
        repository_users.delete_all_repositories_for_user(db, username)
    return users.update_role_of_user(db, username, body.role)


@router.get("/{username}/sessions", response_model=t.List[AdvancedSessionResponse])
def get_sessions_for_user(
    username: str, db: Session = Depends(get_db), token=Depends(JWTBearer())
):
    if username != token[USERNAME_CLAIM] and not is_admin(token, db):
        raise HTTPException(
            status_code=403,
            detail="You can only see your own sessions. If you are a manager, please use the /sessions endpoint.",
        )

    user = users.get_user(db, username)
    return inject_attrs_in_sessions(user.sessions)

backend/t4cclient/routes/sync.py METASEP
import typing as t

import t4cclient.extensions.modelsources.t4c.connection as t4c_manager
from fastapi import APIRouter, Depends
from requests import Session
from t4cclient.core.database import get_db, repositories
from t4cclient.core.oauth import database as database_auth
from t4cclient.core.oauth.jwt_bearer import JWTBearer
from t4cclient.routes.open_api_configuration import AUTHENTICATION_RESPONSES

router = APIRouter()


@router.post(
    "/repositories",
    status_code=204,
    tags=["Repositories"],
    responses=AUTHENTICATION_RESPONSES,
)
def fetch_repositories_from_t4c(
    db: Session = Depends(get_db), token=Depends(JWTBearer())
):
    database_auth.verify_admin(token, db)

    t4c_server_repos = t4c_manager.get_repositories()
    repos = [repo.name for repo in repositories.get_all_repositories(db=db)]

    difference = list(set(t4c_server_repos) - set(repos))

    for repo in difference:
        repositories.create_repository(db=db, name=repo)

backend/t4cclient/routes/status.py METASEP
from fastapi import APIRouter, Depends
from pydantic import BaseModel
from sqlalchemy.orm import Session
from t4cclient import config
from t4cclient.core.database import get_db
from t4cclient.core.operators import OPERATOR
from t4cclient.extensions.guacamole import get_admin_token
from t4cclient.extensions.modelsources.t4c.connection import get_t4c_status


class StatusResponse(BaseModel):
    guacamole: str
    license_server: str
    database: str
    operator: str


router = APIRouter()


@router.get(
    "/status",
    response_model=StatusResponse,
)
def get_status(db: Session = Depends(get_db)):
    return StatusResponse(
        guacamole=validate_guacamole(),
        license_server=validate_license_server(),
        database=validate_session(db),
        operator=OPERATOR.validate(),
    )


def validate_guacamole() -> str:
    try:
        get_admin_token()
        return "ok"
    except:
        return "cannot authenticate"


def validate_license_server() -> str:
    try:
        get_t4c_status()
        return "ok"
    except:
        return "cannot reach license server"


def validate_session(session: Session) -> str:
    try:
        session.connection()
        return "ok"
    except:
        return "no connection"

backend/t4cclient/routes/sessions.py METASEP
import itertools
import logging
import typing as t

import t4cclient.core.database.repositories as repositories_crud
import t4cclient.extensions.modelsources.git.crud as git_models_crud
import t4cclient.extensions.modelsources.t4c.connection as t4c_manager
import t4cclient.schemas.repositories.users as users_schema
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from t4cclient.config import USERNAME_CLAIM
from t4cclient.core.credentials import generate_password
from t4cclient.core.database import get_db, sessions, users
from t4cclient.core.oauth.database import is_admin, verify_repository_role
from t4cclient.core.oauth.jwt_bearer import JWTBearer
from t4cclient.core.operators import OPERATOR
from t4cclient.core.services.sessions import inject_attrs_in_sessions
from t4cclient.extensions import guacamole
from t4cclient.routes import guacamole as guacamole_route
from t4cclient.routes.open_api_configuration import AUTHENTICATION_RESPONSES
from t4cclient.schemas.repositories import RepositoryUserRole
from t4cclient.schemas.sessions import (
    AdvancedSessionResponse,
    GetSessionsResponse,
    GetSessionUsageResponse,
    PostSessionRequest,
    WorkspaceType,
)
from t4cclient.sql_models.sessions import DatabaseSession

router = APIRouter()
log = logging.getLogger(__name__)


@router.get("/", response_model=t.List[GetSessionsResponse])
def get_current_sessions(db: Session = Depends(get_db), token=Depends(JWTBearer())):
    if is_admin(token, db):
        return inject_attrs_in_sessions(sessions.get_all_sessions(db))

    db_user = users.get_user(db=db, username=token[USERNAME_CLAIM])
    if not any(
        repo_user.role == RepositoryUserRole.MANAGER
        for repo_user in db_user.repositories
    ):
        raise HTTPException(
            status_code=403,
            detail="You have to be project manager for at least one repository.",
        )
    return inject_attrs_in_sessions(
        list(
            itertools.chain.from_iterable(
                [
                    sessions.get_sessions_for_repository(db, repository)
                    for repository in [
                        r.repository_name
                        for r in db_user.repositories
                        if r.role == RepositoryUserRole.MANAGER
                    ]
                ]
            )
        )
    )


@router.post(
    "/", response_model=AdvancedSessionResponse, responses=AUTHENTICATION_RESPONSES
)
def request_session(
    body: PostSessionRequest, db: Session = Depends(get_db), token=Depends(JWTBearer())
):

    rdp_password = generate_password(length=64)

    owner = token[USERNAME_CLAIM]

    log.info("Starting session creation for user %s", owner)

    guacamole_username = generate_password()
    guacamole_password = generate_password(length=64)

    guacamole_token = guacamole.get_admin_token()
    guacamole.create_user(guacamole_token, guacamole_username, guacamole_password)

    existing_user_sessions = sessions.get_sessions_for_user(db, owner)

    if body.type == WorkspaceType.PERSISTENT:
        body.repository = ""
        if WorkspaceType.PERSISTENT in [
            session.type for session in existing_user_sessions
        ]:
            raise HTTPException(
                status_code=404,
                detail={
                    "err_code": "existing_session",
                    "reason": "You already have a open Persistent Session. Please navigate to 'Active Sessions' to Reconnect",
                },
            )
        user = users.get_user(db, owner)
        if user.role == users_schema.Role.ADMIN:
            repositories = [
                repo.name for repo in repositories_crud.get_all_repositories(db)
            ]
        else:
            repositories = [repo.repository_name for repo in user.repositories]
        session = OPERATOR.start_persistent_session(
            username=token[USERNAME_CLAIM],
            password=rdp_password,
            repositories=repositories,
        )

    elif body.type == WorkspaceType.READONLY:
        if body.repository in [
            session.repository for session in existing_user_sessions
        ]:
            raise HTTPException(
                status_code=404,
                detail={
                    "err_code": "existing_session",
                    "reason": f"You already have a open Read-Only Session for the repository {body.repository}. Please navigate to 'Active Sessions' to Reconnect",
                },
            )
        verify_repository_role(repository=body.repository, token=token, db=db)
        git_model = git_models_crud.get_primary_model_of_repository(db, body.repository)
        if not git_model:
            raise HTTPException(
                status_code=404,
                detail={
                    "err_code": "git_model_not_found",
                    "reason": "The Model has no connected Git Model. Please contact a project manager or admininistrator",
                },
            )
        session = OPERATOR.start_readonly_session(
            password=rdp_password,
            git_url=git_model.path,
            git_revision=git_model.revision,
            entrypoint=git_model.entrypoint,
        )

    guacamole_identifier = guacamole.create_connection(
        guacamole_token,
        rdp_password,
        session["host"],
        list(session["ports"])[0],
    )["identifier"]

    guacamole.assign_user_to_connection(
        guacamole_token, guacamole_username, guacamole_identifier
    )

    database_model = DatabaseSession(
        guacamole_username=guacamole_username,
        guacamole_password=guacamole_password,
        rdp_password=rdp_password,
        guacamole_connection_id=guacamole_identifier,
        owner_name=owner,
        **body.dict(),
        **session,
    )
    response = sessions.create_session(db=db, session=database_model).__dict__
    response["owner"] = response["owner_name"]
    response["state"] = OPERATOR.get_session_state(response["id"])
    response["rdp_password"] = rdp_password
    response["guacamole_password"] = guacamole_password
    response["last_seen"] = t4c_manager.fetch_last_seen(response["mac"])

    return response


@router.delete("/{id}/", status_code=204, responses=AUTHENTICATION_RESPONSES)
def end_session(id: str, db: Session = Depends(get_db), token=Depends(JWTBearer())):
    s = sessions.get_session_by_id(db, id)
    if s.owner_name != token[USERNAME_CLAIM] and verify_repository_role(
        repository=s.repository,
        token=token,
        db=db,
        allowed_roles=["manager", "administrator"],
    ):
        raise HTTPException(
            status_code=403,
            detail="The owner of the repository does not match with your username. You have to be administrator or manager to delete other sessions.",
        )
    sessions.delete_session(db, id)
    OPERATOR.kill_session(id)


@router.get(
    "/usage",
    response_model=GetSessionUsageResponse,
    responses=AUTHENTICATION_RESPONSES,
    dependencies=[Depends(JWTBearer())],
)
def get_session_usage():
    return t4c_manager.get_t4c_status()


router.include_router(
    guacamole_route.router,
    prefix="/{id}/guacamole-tokens",
)

backend/t4cclient/routes/open_api_configuration.py METASEP
AUTHENTICATION_RESPONSES = {
    401: {
        "description": "Unauthorized",
        "content": {
            "application/json": {
                "example": {
                    "error": {
                        "detail": {
                            "err_code": "token_exp",
                            "reason": "The Signature of the token is expired. Please request a new access token or refresh the token.",
                        }
                    }
                }
            }
        },
    },
    403: {
        "description": "Forbidden",
        "content": {
            "application/json": {
                "example": {
                    "error": {
                        "detail": "One of the roles '[user, manager, administrator]' in the repository test is required."
                    }
                }
            }
        },
    },
}

backend/t4cclient/routes/oauth.py METASEP
import secrets
import typing as t
from functools import lru_cache

from cachetools import TTLCache
from fastapi import APIRouter, Depends
from msal import ConfidentialClientApplication

from t4cclient.config import (
    OAUTH_CLIENT_ID,
    OAUTH_CLIENT_SECRET,
    OAUTH_ENDPOINT,
)
from t4cclient.core.oauth import (
    jwt_bearer,
    OAuthStub,
)
from t4cclient.schemas.oauth import RefreshTokenRequest, TokenRequest


router = APIRouter()


@lru_cache()
def ad_session():
    return ConfidentialClientApplication(OAUTH_CLIENT_ID, client_credential=OAUTH_CLIENT_SECRET, authority=OAUTH_ENDPOINT)


# Make this a cache:
global_session_data = TTLCache(maxsize=128, ttl=3600)


@router.get("/", name="Get redirect URL for OAuth")
async def get_redirect_url():
    state = secrets.token_hex(32)
    assert state not in global_session_data
    session_data = ad_session().initiate_auth_code_flow(scopes=[], state=state)
    global_session_data[session_data["state"]] = session_data
    return {"auth_url": session_data["auth_uri"], "state": session_data["state"]}


@router.post("/tokens", name="Create access_token")
async def api_get_token(body: TokenRequest):
    auth_data = global_session_data[body.state]
    del global_session_data[body.state]
    token = ad_session().acquire_token_by_auth_code_flow(auth_data, body.dict(), scopes=[])

    # *Sigh* This is microsoft again. Instead of the access_token, we should use id_token :/
    # https://stackoverflow.com/questions/63195081/how-to-validate-a-jwt-from-azuread-in-python
    return {"access_token": token["id_token"], "refresh_token": token["refresh_token"], "token_type": token["token_type"]}


@router.put("/tokens", name="Refresh the access_token")
async def api_refresh_token(body: RefreshTokenRequest):
    return ad_session().acquire_token_by_refresh_token(body.refresh_token, scopes=[])


@router.get("/logout", name="Invalidate the token (log out)")
async def validate_token(jwt_decoded=Depends(jwt_bearer.JWTBearer())):
    for account in ad_session().get_accounts():
        if account["username"] == jwt_decoded["preferred_username"]:
            return ad_session().remove_account(account)
    return None


@router.get("/tokens", name="Validate the token")
async def validate_token(jwt_decoded=Depends(jwt_bearer.JWTBearer())):
    return jwt_decoded

backend/t4cclient/routes/notices.py METASEP
import typing as t

from fastapi import APIRouter, Depends
from requests import Session
from t4cclient.core.database import get_db, notices
from t4cclient.core.oauth.database import verify_admin
from t4cclient.core.oauth.jwt_bearer import JWTBearer
from t4cclient.routes.open_api_configuration import AUTHENTICATION_RESPONSES
from t4cclient.schemas.notices import CreateNoticeRequest, NoticeResponse

router = APIRouter()


@router.get(
    "/",
    response_model=t.List[NoticeResponse],
)
def get_notices(db: Session = Depends(get_db)):
    return notices.get_all_notices(db)


@router.get("/{id}")
def get_notice_by_id(id: int, db: Session = Depends(get_db)):
    return notices.get_notice(db, id)


@router.post("/", responses=AUTHENTICATION_RESPONSES)
def create_notice(
    body: CreateNoticeRequest,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    verify_admin(token, db)
    return notices.create_notice(db, body)


@router.delete(
    "/{id}",
    status_code=204,
    responses=AUTHENTICATION_RESPONSES,
)
def delete_notice(id: int, db: Session = Depends(get_db), token=Depends(JWTBearer())):
    verify_admin(token, db)
    return notices.delete_notice(db, id)

backend/t4cclient/routes/guacamole.py METASEP
import json

from fastapi import APIRouter, Depends, HTTPException
from requests import Session
from t4cclient.config import GUACAMOLE_PUBLIC_URI, USERNAME_CLAIM
from t4cclient.core.database import get_db, sessions
from t4cclient.core.oauth.jwt_bearer import JWTBearer
from t4cclient.extensions import guacamole
from t4cclient.routes.open_api_configuration import AUTHENTICATION_RESPONSES
from t4cclient.schemas.guacamole import GuacamoleAuthentication



router = APIRouter()


@router.post(
    "/",
    response_model=GuacamoleAuthentication,
    responses=AUTHENTICATION_RESPONSES,
)
def create_guacamole_token(
    id: str,
    db: Session = Depends(get_db),
    token=Depends(JWTBearer()),
):
    session = sessions.get_session_by_id(db, id)
    if session.owner_name != token[USERNAME_CLAIM]:
        raise HTTPException(
            status_code=403,
            detail="The owner of the session does not match with your username.",
        )

    token = guacamole.get_token(session.guacamole_username, session.guacamole_password)
    return GuacamoleAuthentication(token=json.dumps(token), url=GUACAMOLE_PUBLIC_URI + "/#/")

backend/t4cclient/routes/__init__.py METASEP
from fastapi import APIRouter

from . import notices, oauth, repositories, sessions, sync, users

router = APIRouter()
router.include_router(sessions.router, prefix="/sessions", tags=["Sessions"])
router.include_router(sync.router, prefix="/sync", tags=["T4C Server Synchronization"])
router.include_router(repositories.router, prefix="/projects")
router.include_router(users.router, prefix="/users", tags=["Users"])
router.include_router(oauth.router, prefix="/auth/oauth", tags=["Authentication"])
router.include_router(notices.router, prefix="/notices", tags=["Notices"])

backend/t4cclient/extensions/guacamole.py METASEP
import uuid

import requests
from requests.auth import HTTPBasicAuth
from t4cclient import config
from t4cclient.config import GUACAMOLE_URI
from t4cclient.core.credentials import generate_password

GUACAMOLE_PREFIX = GUACAMOLE_URI + "/api/session/data/postgresql"
headers = {"Content-Type": "application/x-www-form-urlencoded"}


def get_admin_token() -> str:
    r = requests.post(
        GUACAMOLE_URI + "/api/tokens",
        auth=HTTPBasicAuth(config.GUACAMOLE_USERNAME, config.GUACAMOLE_PASSWORD),
        headers=headers,
        timeout=config.REQUESTS_TIMEOUT,
    )
    r.raise_for_status()
    return r.json()["authToken"]


def get_token(username: str, password: str) -> str:
    r = requests.post(
        GUACAMOLE_URI + "/api/tokens",
        auth=HTTPBasicAuth(username, password),
        headers=headers,
        timeout=config.REQUESTS_TIMEOUT,
    )
    r.raise_for_status()
    return r.json()


def create_user(
    token: str,
    username: str = generate_password(10),
    password: str = generate_password(128),
) -> None:
    r = requests.post(
        GUACAMOLE_PREFIX + "/users?token=" + token,
        json={"username": username, "password": password, "attributes": {}},
        timeout=config.REQUESTS_TIMEOUT,
    )
    r.raise_for_status()
    return r.json()


def assign_user_to_connection(token: str, username: str, connection_id: str):
    r = requests.patch(
        f"{GUACAMOLE_PREFIX}/users/{username}/permissions?token={token}",
        json=[
            {
                "op": "add",
                "path": f"/connectionPermissions/{connection_id}",
                "value": "READ",
            }
        ],
        timeout=config.REQUESTS_TIMEOUT,
    )
    r.raise_for_status()


def delete_user(token: str, username: str):
    r = requests.delete(
        f"{GUACAMOLE_PREFIX}/users/{username}?token={token}",
        timeout=config.REQUESTS_TIMEOUT,
    )
    r.raise_for_status()
    return r.json()


def delete_connection(token: str, connection_name: str):
    r = requests.delete(
        f"{GUACAMOLE_PREFIX}/connections/{connection_name}?token={token}",
        timeout=config.REQUESTS_TIMEOUT,
    )
    r.raise_for_status()
    return r.json()


def create_connection(
    token: str,
    rdp_password: str,
    rdp_host: str,
    rdp_port: int,
):
    r = requests.post(
        f"{GUACAMOLE_PREFIX}/connections?token={token}",
        json={
            "parentIdentifier": "ROOT",
            "name": str(uuid.uuid4()),
            "protocol": "rdp",
            "parameters": {
                "hostname": rdp_host,
                "username": "techuser",
                "password": rdp_password,
                "port": rdp_port,
                "ignore-cert": True,
                "server-layout": "de-de-qwertz",
            },
            "attributes": {},
        },
        timeout=config.REQUESTS_TIMEOUT,
    )

    r.raise_for_status()
    return r.json()

backend/t4cclient/extensions/__init__.py METASEP
from importlib import metadata


def load_modelsource(name: str):
    try:
        ep = next(
            i
            for i in metadata.entry_points()["capellacollab.extensions.modelsources"]
            if i.name == name
        )
    except StopIteration:
        raise ValueError(f"Unknown modelsource {name}")

    return ep.load()

backend/t4cclient/core/garbage_cleaner.py METASEP
import logging

import click
from t4cclient.core import database
from t4cclient.core.database import sessions
from t4cclient.routes.sessions import inject_attrs_in_sessions

LOGGER = logging.getLogger(__file__)


@click.command()
def clean_old_sessions():
    with database.SessionLocal() as db:
        for session in inject_attrs_in_sessions(sessions.get_all_sessions(db)):
            if session["state"] == "exited":
                try:
                    sessions.delete_session(db, session["id"])
                except Exception as e:
                    LOGGER.info(
                        "Removing then container with id %s failed",
                        session["id"],
                        exc_info=True,
                    )


if __name__ == "__main__":
    clean_old_sessions()

backend/t4cclient/core/credentials.py METASEP
import secrets
import string


def generate_password(length: int = 10) -> str:
    return "".join(
        secrets.choice(string.ascii_letters + string.digits) for _ in range(length)
    )

backend/t4cclient/core/__init__.py METASEP

backend/t4cclient/alembic/env.py METASEP
import os
from logging.config import fileConfig

os.environ["ALEMBIC_CONTEXT"] = "1"

from sqlalchemy import engine_from_config, pool
from t4cclient.config import DATABASE_URL

from alembic import context

# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config

# this will overwrite the ini-file sqlalchemy.url path
# with the path given in the config of the main code
config.set_main_option("sqlalchemy.url", DATABASE_URL)


# Interpret the config file for Python logging.
# This line sets up loggers basically.
if config.attributes.get("configure_logger", True):
    fileConfig(config.config_file_name)

# add your model's MetaData object here
# for 'autogenerate' support
from t4cclient.core.database import Base

target_metadata = Base.metadata
# target_metadata = None

# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.


def run_migrations_offline():
    """Run migrations in 'offline' mode.

    This configures the context with just a URL
    and not an Engine, though an Engine is acceptable
    here as well.  By skipping the Engine creation
    we don't even need a DBAPI to be available.

    Calls to context.execute() here emit the given string to the
    script output.

    """
    url = config.get_main_option("sqlalchemy.url")
    context.configure(
        url=url,
        target_metadata=target_metadata,
        literal_binds=True,
        dialect_opts={"paramstyle": "named"},
    )

    with context.begin_transaction():
        context.run_migrations()


def run_migrations_online():
    """Run migrations in 'online' mode.

    In this scenario we need to create an Engine
    and associate a connection with the context.

    """
    connectable = engine_from_config(
        config.get_section(config.config_ini_section),
        prefix="sqlalchemy.",
        poolclass=pool.NullPool,
    )

    with connectable.connect() as connection:
        context.configure(connection=connection, target_metadata=target_metadata)

        with context.begin_transaction():
            context.run_migrations()


if context.is_offline_mode():
    run_migrations_offline()
else:
    run_migrations_online()

frontend/src/test.ts METASEP
// This file is required by karma.conf.js and loads recursively all the .spec and framework files

import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import {
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';

declare const require: {
  context(path: string, deep?: boolean, filter?: RegExp): {
    keys(): string[];
    <T>(id: string): T;
  };
};

// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

frontend/src/styles.css METASEP
/* You can add global styles to this file, and also import other style files */

html,
body {
  height: 100%;
}
body {
  margin: 0;
  font-family: Roboto, "Helvetica Neue", sans-serif;
}

.expansion-panel > .mat-content {
  justify-content: space-between;
}

.mat-content > mat-panel-title {
  flex: 2;
}
.mat-content > mat-panel-description {
  flex: 1;
}

mat-form-field.mat-form-field-invalid {
  animation: add-margin-for-mat-error;
  animation-duration: 0.3s;
  margin-bottom: 13px;
}

@keyframes add-margin-for-mat-error {
  from {
    margin-bottom: 0;
  }
  to {
    margin-bottom: 13px;
  }
}

:root {
  --primary-color: #3f51b5;
  --error-color: darkred;
  --warning-color: darkorange;
  --success-color: darkgreen;
}

button.primary {
  background-color: var(--primary-color);
  color: white;
}

.primaryText {
  color: var(--primary-color);
}

button.success {
  background-color: green;
  color: white;
}

mat-card {
  width: fit-content;
  margin: 10px;
}

mat-form-field {
  margin-right: 10px;
}

h1 {
  margin: 10px;
}

.flexbox {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  flex-wrap: wrap;
}

button {
  margin: 5px;
}

mat-spinner {
  margin-left: auto;
  margin-right: auto;
}

.mat-icon {
  vertical-align: middle;
}

.workspace-toggle * .mat-slide-toggle-bar {
  background-color: green !important;
}

.workspace-toggle * .mat-slide-toggle-thumb {
  background-color: #fafafa !important;
}

frontend/src/polyfills.ts METASEP
/**
 * This file includes polyfills needed by Angular and is loaded before the app.
 * You can add your own extra polyfills to this file.
 *
 * This file is divided into 2 sections:
 *   1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
 *   2. Application imports. Files imported after ZoneJS that should be loaded before your main
 *      file.
 *
 * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
 * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
 * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
 *
 * Learn more in https://angular.io/guide/browser-support
 */

/***************************************************************************************************
 * BROWSER POLYFILLS
 */

/**
 * IE11 requires the following for NgClass support on SVG elements
 */
// import 'classlist.js';  // Run `npm install --save classlist.js`.

/**
 * Web Animations `@angular/platform-browser/animations`
 * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
 * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
 */
// import 'web-animations-js';  // Run `npm install --save web-animations-js`.

/**
 * By default, zone.js will patch all possible macroTask and DomEvents
 * user can disable parts of macroTask/DomEvents patch by setting following flags
 * because those flags need to be set before `zone.js` being loaded, and webpack
 * will put import in the top of bundle, so user need to create a separate file
 * in this directory (for example: zone-flags.ts), and put the following flags
 * into that file, and then add the following code before importing zone.js.
 * import './zone-flags';
 *
 * The flags allowed in zone-flags.ts are listed here.
 *
 * The following flags will work for all browsers.
 *
 * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
 * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
 * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
 *
 *  in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
 *  with the following flag, it will bypass `zone.js` patch for IE/Edge
 *
 *  (window as any).__Zone_enable_cross_context_check = true;
 *
 */

/***************************************************************************************************
 * Zone JS is required by default for Angular itself.
 */
import 'zone.js';  // Included with Angular CLI.


/***************************************************************************************************
 * APPLICATION IMPORTS
 */

frontend/src/main.ts METASEP
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch((err) => console.error(err));

frontend/src/index.html METASEP
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Capella Collaboration</title>
    <base href="/" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="icon" type="image/x-icon" href="favicon.ico" />
    <link rel="preconnect" href="https://fonts.gstatic.com" />
    <link
      href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap"
      rel="stylesheet"
    />
    <link
      href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet"
    />
  </head>
  <body class="mat-typography">
    <app-root></app-root>
  </body>
</html>

frontend/src/custom-theme.scss METASEP
@use "~@angular/material" as mat;

@include mat.core();

$primary-palette: (
  50: #e8eaf6,
  100: #c5cbe9,
  200: #9fa8da,
  300: #7985cb,
  400: #5c6bc0,
  500: #3f51b5,
  600: #394aae,
  700: #3140a5,
  800: #29379d,
  900: #1b278d,
  A100: #c6cbff,
  A200: #939dff,
  A400: #606eff,
  A700: #4757ff,
  contrast: (
    50: #000000,
    100: #000000,
    200: #000000,
    300: #000000,
    400: #ffffff,
    500: #ffffff,
    600: #ffffff,
    700: #ffffff,
    800: #ffffff,
    900: #ffffff,
    A100: #000000,
    A200: #000000,
    A400: #ffffff,
    A700: #ffffff,
  ),
);

$primary: mat.define-palette($primary-palette);
$theme: mat.define-light-theme(
  (
    color: (
      primary: $primary,
      accent: $primary,
    ),
  )
);

@include mat.all-component-themes($theme);

backend/t4cclient/alembic.ini METASEP
# A generic, single database configuration.

[alembic]
# path to migration scripts
script_location = alembic

# template used to generate migration files
# file_template = %%(rev)s_%%(slug)s

# sys.path path, will be prepended to sys.path if present.
# defaults to the current working directory.
prepend_sys_path = .

# timezone to use when rendering the date
# within the migration file as well as the filename.
# string value is passed to dateutil.tz.gettz()
# leave blank for localtime
# timezone =

# max length of characters to apply to the
# "slug" field
# truncate_slug_length = 40

# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false

# set to 'true' to allow .pyc and .pyo files without
# a source .py file to be detected as revisions in the
# versions/ directory
# sourceless = false

# version location specification; this defaults
# to alembic/versions.  When using multiple version
# directories, initial revisions must be specified with --version-path
# version_locations = %(here)s/bar %(here)s/bat alembic/versions

# the output encoding used when revision files
# are written from script.py.mako
# output_encoding = utf-8

# We set the sqlalchemy URL in alembic/env.py
sqlalchemy.url = 


[post_write_hooks]
# post_write_hooks defines scripts or Python functions that are run
# on newly generated revision scripts.  See the documentation for further
# detail and examples

# format using "black" - use the console_scripts runner, against the "black" entrypoint
# hooks = black
# black.type = console_scripts
# black.entrypoint = black
# black.options = -l 79 REVISION_SCRIPT_FILENAME

# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = WARN
handlers = console
qualname =

[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine

[logger_alembic]
level = INFO
handlers =
qualname = alembic

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S

backend/t4cclient/config.py METASEP
import configparser
import logging
import os
import pathlib

config_parser = configparser.RawConfigParser()
config_directory = pathlib.Path(__file__).parents[1] / "config"
config_file_path = config_directory / "config.ini"
config_parser.read(config_file_path)

log = logging.getLogger(__name__)


def get_config(group: str, key: str, fallback: str = "") -> str:
    config = config_parser.get(
        group, key, fallback=os.environ.get(f"{group}_{key.upper()}", fallback)
    )

    if not config:
        log.warning(
            "Configuration %s of group %s not found. Defaulting to empty string.",
            key,
            group,
        )

    return config


PERSISTENT_IMAGE = get_config("DOCKER", "PERSISTENT_IMAGE")
READONLY_IMAGE = get_config("DOCKER", "READONLY_IMAGE")
EASE_IMAGE = get_config("DOCKER", "EASE_IMAGE")
WORKSPACE_MOUNT_VOLUME = get_config("DOCKER", "WORKSPACE_MOUNT_VOLUME")
DOCKER_PORT_RANGE = get_config("DOCKER", "PORT_RANGE")
DOCKER_HOST = get_config("DOCKER", "CONTAINER_HOST")

GUACAMOLE_URI = get_config("GUACAMOLE", "BASE_URI")
GUACAMOLE_PUBLIC_URI = get_config("GUACAMOLE", "PUBLIC_URI")
GUACAMOLE_USERNAME = get_config("GUACAMOLE", "USERNAME")
GUACAMOLE_PASSWORD = get_config("GUACAMOLE", "PASSWORD")

OAUTH_TOKEN_ENDPOINT = get_config("OAUTH", "token_issuance_endpoint")
OAUTH_ENDPOINT = get_config("OAUTH", "authorization_endpoint")
OAUTH_CLIENT_ID = get_config("OAUTH", "client_id")
OAUTH_CLIENT_SECRET = get_config("OAUTH", "client_secret")
OAUTH_REDIRECT_URI = get_config("OAUTH", "redirect_uri")
USERNAME_CLAIM = get_config("OAUTH", "USERNAME_CLAIM")
DATABASE_URL = get_config("SQL", "DATABASE_URL")

T4C_SERVER_USERNAME = get_config("T4C_SERVER", "USERNAME")
T4C_SERVER_PASSWORD = get_config("T4C_SERVER", "PASSWORD")
T4C_SERVER_HOST = get_config("T4C_SERVER", "HOST")
T4C_SERVER_PORT = get_config("T4C_SERVER", "PORT")
T4C_LICENCE = get_config("T4C_SERVER", "LICENCE")

T4C_USAGE_API = get_config("T4C_SERVER", "USAGE_API")
T4C_REST_API = get_config("T4C_SERVER", "REST_API")

KUBERNETES_CONTEXT = get_config("KUBERNETES", "CONTEXT", "default")
KUBERNETES_NAMESPACE = get_config("KUBERNETES", "NAMESPACE")
KUBERNETES_STORAGE_CLASS_NAME = get_config(
    "KUBERNETES", "STORAGE_CLASS_NAME", "persistent-sessions-csi"
)
KUBERNETES_STORAGE_ACCESS_MODE = get_config(
    "KUBERNETES", "STORAGE_ACCESS_MODE", "ReadWriteMany"
)
KUBERNETES_TOKEN = get_config("KUBERNETES", "NAMESPACE")
KUBERNETES_API_URL = get_config("KUBERNETES", "API_URL")
KUBERNETES_RELEASE_NAME = get_config("KUBERNETES", "RELEASE_NAME")
OPERATOR_TYPE = get_config("OPERATOR", "TYPE")

JENKINS_BASE_URL = get_config("JENKINS", "BASE_URL")
JENKINS_USERNAME = get_config("JENKINS", "USERNAME")
JENKINS_PASSWORD = get_config("JENKINS", "PASSWORD")

JENKINS_GIT_USERNAME = get_config("JENKINS_GIT", "USERNAME")
JENKINS_GIT_EMAIL = get_config("JENKINS_GIT", "EMAIL")
JENKINS_GIT_CREDENTIAL_ID = get_config("JENKINS_GIT", "CREDENTIAL_ID")
JENKINS_GIT_SCRIPT_REPO_URL = get_config("JENKINS_GIT", "SCRIPT_REPO_URL")

GIT_USERNAME = get_config("GIT", "USERNAME")
GIT_PASSWORD = get_config("GIT", "PASSWORD")

INITIAL_ADMIN_USER = get_config("USERS", "INITIAL_ADMIN")

REQUESTS_TIMEOUT = 0.5
LOGGING_LEVEL = get_config("LOGGING", "LEVEL", "DEBUG")

backend/t4cclient/__main__.py METASEP
import uvicorn
from t4cclient import app

if __name__ == "__main__":
    uvicorn.run(app)
backend/t4cclient/__init__.py METASEP
import logging
import random
import string
import time
from importlib import metadata

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

# This import statement is required and should not be removed! (Alembic will not work otherwise)
import t4cclient.sql_models
from t4cclient import config
from t4cclient.core.database import __main__ as database
from t4cclient.routes import router, status

logging.basicConfig(level=logging.INFO)
log = logging.getLogger(__name__)

# Load extension models
eps = (
    metadata.entry_points()["capellacollab.extensions.backups"]
    + metadata.entry_points()["capellacollab.extensions.modelsources"]
)
for ep in eps:
    log.info("Import models of extension %s", ep.name)
    ep.load().models

database.migrate_db()


class HealthcheckFilter(logging.Filter):
    def filter(self, record: logging.LogRecord) -> bool:
        return record.getMessage().find("/healthcheck") == -1


logging.getLogger("uvicorn.access").addFilter(HealthcheckFilter())
logging.basicConfig(level=config.LOGGING_LEVEL)

app = FastAPI(title="T4C Client Manager")

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["POST", "GET", "OPTIONS", "DELETE", "PUT", "PATCH"],
    allow_headers=["*"],
)


@app.middleware("http")
async def log_requests(request, call_next):
    idem = "".join(random.choices(string.ascii_uppercase + string.digits, k=6))
    log.debug(f"rid={idem} start request path={request.url.path}")
    start_time = time.time()

    response = await call_next(request)

    process_time = (time.time() - start_time) * 1000
    formatted_process_time = "{0:.2f}".format(process_time)
    log.debug(
        f"rid={idem} completed_in={formatted_process_time}ms status_code={response.status_code}"
    )

    return response


@app.get("/healthcheck", tags=["Healthcheck"])
async def healthcheck():
    return {"status": "alive"}


app.include_router(status.router, prefix="", tags=["Status"])
app.include_router(router, prefix="/api/v1")

helm/templates/nginx/nginx.deployment.yaml METASEP
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-nginx
  labels: 
    id: {{ .Release.Name }}-deployment-nginx
  annotations:
    checksum/config: {{ include (print $.Template.BasePath "/nginx/nginx.configmap.yaml") . | sha256sum }}
spec:
  replicas: {{ .Values.replicaCount | default 1 }}
  selector: 
    matchLabels: 
      id: {{ .Release.Name }}-deployment-nginx
  template:
    metadata: 
      labels: 
        id: {{ .Release.Name }}-deployment-nginx
    spec:
      volumes:
        - name: {{ .Release.Name }}-nginx
          configMap:
            name: {{ .Release.Name }}-nginx
      containers:
        - name: {{ .Release.Name }}-nginx
          image: nginxinc/nginx-unprivileged
          imagePullPolicy: Always
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          resources:
            limits:
              cpu: "1"
              memory: 100Mi
            requests:
              cpu: "0.25"
              memory: 50Mi
          volumeMounts:
            - name: {{ .Release.Name }}-nginx
              mountPath: /etc/nginx
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}

helm/templates/nginx/nginx.configmap.yaml METASEP
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-nginx
  namespace: {{ .Release.Namespace }}
  labels: 
    id: {{ .Release.Name }}-configmap-nginx
data:
  nginx.conf: |- 
    {{ tpl (.Files.Get "config/nginx.conf") . | nindent 4 }}

helm/templates/nginx/nginx.clusterip.yaml METASEP
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}-nginx-clusterip
  labels: 
    id: {{ .Release.Name }}-service-nginx-clusterip
spec:
  type: ClusterIP
  selector:
    id: {{ .Release.Name }}-deployment-nginx
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http

helm/templates/ingress/ingress.yaml METASEP
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ .Release.Name }}-nginx
  labels: 
    id: {{ .Release.Name }}-nginx
  annotations:
    {{ if eq .Values.target "local" }}
    ingress.kubernetes.io/ssl-redirect: "false"
    {{ else }}
    kubernetes.io/ingress.class: nginx
    {{ end }}
spec:
  rules:
    - host: {{ .Values.general.host }}
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: {{ .Release.Name }}-frontend
                port:
                  number: 80
          - path: /api/v1
            pathType: Prefix
            backend:
              service:
                name: {{ .Release.Name }}-nginx-clusterip
                port:
                  number: 80
          - path: /guacamole
            pathType: Prefix
            backend:
              service:
                name: {{ .Release.Name }}-guacamole-guacamole
                port:
                  number: 8080

helm/templates/guacamole/postgres.volume.yaml METASEP
{{ if .Values.database.deploy }}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: {{ .Release.Name }}-volume-guacamole-postgres
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: {{ .Values.database.guacamole.internal.storageClassName }}
{{ end }}

helm/templates/guacamole/postgres.service.yaml METASEP
{{ if .Values.database.deploy }}
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}-guacamole-postgres
  labels: 
    id: {{ .Release.Name }}-service-guacamole-postgres
spec:
  type: ClusterIP
  selector:
    id: {{ .Release.Name }}-deployment-guacamole-postgres
  ports:
    - port: 5432
      targetPort: postgres
      protocol: TCP
      name: postgres
{{ end }}
helm/templates/guacamole/postgres.deployment.yaml METASEP
{{ if .Values.database.deploy }}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-guacamole-postgres
  labels: 
    id: {{ .Release.Name }}-deployment-guacamole-postgres
spec:
  replicas: 1
  selector: 
    matchLabels: 
      id: {{ .Release.Name }}-deployment-guacamole-postgres
  template:
    metadata: 
      labels: 
        id: {{ .Release.Name }}-deployment-guacamole-postgres
    spec:
      volumes:
        - name: {{ .Release.Name }}-data
          persistentVolumeClaim:
            claimName: {{ .Release.Name }}-volume-guacamole-postgres
        - name: {{ .Release.Name }}-initsql
          configMap:
            name: {{ .Release.Name }}-configmap-guacamole-postgres
      containers:
        - name: {{ .Release.Name }}-guacamole-postgres
          image: postgres:14.1
          imagePullPolicy: {{ .Values.pullPolicy }}
          env:
            - name: PGDATA
              value: /var/lib/postgresql/data/data
            - name: POSTGRES_DB
              value: guacamole
            - name: POSTGRES_PASSWORD
              value: {{ .Values.database.guacamole.internal.password }}
            - name: POSTGRES_USER
              value: guacamole
            - name: POSTGRES_HOST_AUTH_METHOD
              value: md5
            - name: POSTGRES_INITDB_ARGS
              value: "--auth-host=md5"
          ports:
            - name: postgres
              containerPort: 5432
              protocol: TCP
          readinessProbe:
            exec:
              command: ["psql", "-W", "{{ .Values.database.guacamole.internal.password }}", "-U", "guacamole", "-d", "guacamole", "-c", "SELECT 1"]
            initialDelaySeconds: 15
            timeoutSeconds: 2
          livenessProbe:
            exec:
              command: ["psql", "-W", "{{ .Values.database.guacamole.internal.password }}", "-U", "guacamole", "-d", "guacamole", "-c", "SELECT 1"]
            initialDelaySeconds: 45
            timeoutSeconds: 2
          resources:
            requests:
              memory: "128Mi"
              cpu: "250m"
            limits:
              memory: "1Gi"
              cpu: "1"
          volumeMounts:
            - name: {{ .Release.Name }}-data
              mountPath: /var/lib/postgresql/data
            - name: {{ .Release.Name }}-initsql
              mountPath: /docker-entrypoint-initdb.d
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}
{{ end }}

helm/templates/guacamole/postgres.configmap.yaml METASEP

{{ if .Values.database.deploy }}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap-guacamole-postgres
  namespace: {{ .Release.Namespace }}
  labels: 
    id: {{ .Release.Name }}-configmap-guacamole-postgres
data:
  initdb.sql: |- 
    {{ .Files.Get "config/initdb.sql" | nindent 4 }}
{{ end }}


helm/templates/guacamole/guacd.service.yaml METASEP
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}-guacamole-guacd
  labels: 
    id: {{ .Release.Name }}-service-guacamole-guacd
spec:
  type: ClusterIP
  selector:
    id: {{ .Release.Name }}-deployment-guacamole-guacd
  ports:
    - port: 4822
      targetPort: guacd
      protocol: TCP
      name: guacd

helm/templates/guacamole/guacd.deployment.yaml METASEP
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-guacamole-guacd
  labels: 
    id: {{ .Release.Name }}-deployment-guacamole-guacd
spec:
  replicas: {{ .Values.replicaCount | default 1 }}
  selector: 
    matchLabels: 
      id: {{ .Release.Name }}-deployment-guacamole-guacd
  template:
    metadata: 
      labels: 
        id: {{ .Release.Name }}-deployment-guacamole-guacd
    spec:
      containers:
        - name: {{ .Release.Name }}-guacamole-guacd
          image: guacamole/guacd:latest
          imagePullPolicy: {{ .Values.pullPolicy }}
          ports:
            - name: guacd
              containerPort: 4822
              protocol: TCP
          readinessProbe:
            tcpSocket:
              port: 4822
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            tcpSocket:
              port: 4822
            initialDelaySeconds: 15
            periodSeconds: 20
          resources:
            requests:
              memory: "512Mi"
              cpu: "250m"
            limits:
              memory: "1Gi"
              cpu: "1"
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}

helm/templates/guacamole/guacamole.service.yaml METASEP
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}-guacamole-guacamole
  labels: 
    id: {{ .Release.Name }}-service-guacamole-guacamole
spec:
  type: ClusterIP
  selector:
    id: {{ .Release.Name }}-deployment-guacamole-guacamole
  ports:
    - port: 8080
      targetPort: http
      protocol: TCP
      name: http
helm/templates/guacamole/guacamole.deployment.yaml METASEP
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-guacamole-guacamole
  labels: 
    id: {{ .Release.Name }}-deployment-guacamole-guacamole
spec:
  replicas: {{ .Values.replicaCount | default 1 }}
  selector: 
    matchLabels: 
      id: {{ .Release.Name }}-deployment-guacamole-guacamole
  template:
    metadata: 
      labels: 
        id: {{ .Release.Name }}-deployment-guacamole-guacamole
    spec:
      containers:
        - name: {{ .Release.Name }}-guacamole-guacamole
          image: guacamole/guacamole:latest
          imagePullPolicy: {{ .Values.pullPolicy }}
          env:
            - name: GUACD_HOSTNAME
              value: {{ .Release.Name }}-guacamole-guacd
          {{ if .Values.database.deploy }}
            - name: POSTGRES_DATABASE
              value: "guacamole"
            - name: POSTGRES_HOSTNAME
              value: {{ .Release.Name }}-guacamole-postgres
            - name: POSTGRES_PASSWORD
              value: {{ .Values.database.guacamole.internal.password }}
            - name: POSTGRES_USER
              value: guacamole
          {{ else }}
            - name: POSTGRES_DATABASE
              value: {{ .Values.database.guacamole.external.database }}
            - name: POSTGRES_HOSTNAME
              value: {{ .Values.database.guacamole.external.hostname }}
            - name: POSTGRES_PASSWORD
              value: {{ .Values.database.guacamole.external.password }}
            - name: POSTGRES_USER
              value: {{ .Values.database.guacamole.external.username }}
            - name: POSTGRESQL_SSL_MODE
              value: require
          {{ end }}
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          readinessProbe:
            tcpSocket:
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            tcpSocket:
              port: 8080
            initialDelaySeconds: 15
            periodSeconds: 20          
          resources:
            requests:
              memory: "1Gi"
              cpu: "500m"
            limits:
              memory: "2Gi"
              cpu: "2"
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}

helm/templates/frontend/frontend.service.yaml METASEP
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}-frontend
  labels: 
    id: {{ .Release.Name }}-service-frontend
spec:
  type: ClusterIP
  selector:
    id: {{ .Release.Name }}-deployment-frontend
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http

helm/templates/frontend/frontend.deployment.yaml METASEP
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-frontend
  labels: 
    id: {{ .Release.Name }}-deployment-frontend
spec:
  replicas: {{ .Values.replicaCount | default 1 }}
  selector: 
    matchLabels: 
      id: {{ .Release.Name }}-deployment-frontend
  template:
    metadata: 
      labels: 
        id: {{ .Release.Name }}-deployment-frontend
    spec:
      containers:
        - name: {{ .Release.Name }}-frontend
          image: {{ .Values.docker.registry }}{{ .Values.docker.images.frontend }}
          imagePullPolicy: {{ .Values.pullPolicy }}
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          resources:
            limits:
              cpu: "1"
              memory: 50Mi
            requests:
              cpu: "0.25"
              memory: 5Mi
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}

helm/templates/backup/ease.configmap.yaml METASEP
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-ease-backup
  namespace: {{ .Release.Namespace }}
  labels: 
    id: {{ .Release.Name }}-configmap-ease-backup
data:
  t4c2git.py: |- 
    {{ tpl (.Files.Get "config/t4c2git.py") . | nindent 4 }}
helm/templates/backend/postgres.volume.yaml METASEP
{{ if .Values.database.deploy }}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: {{ .Release.Name }}-volume-backend-postgres
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: {{ .Values.database.backend.internal.storageClassName }}
{{ end }}

helm/templates/backend/postgres.service.yaml METASEP
{{ if .Values.database.deploy }}
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}-backend-postgres
  labels: 
    id: {{ .Release.Name }}-service-backend-postgres
spec:
  type: ClusterIP
  selector:
    id: {{ .Release.Name }}-deployment-backend-postgres
  ports:
    - port: 5432
      targetPort: postgres
      protocol: TCP
      name: postgres
{{ end }}
helm/templates/backend/postgres.deployment.yaml METASEP
{{ if .Values.database.deploy }}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-backend-postgres
  labels: 
    id: {{ .Release.Name }}-deployment-backend-postgres
spec:
  replicas: 1
  selector: 
    matchLabels: 
      id: {{ .Release.Name }}-deployment-backend-postgres
  template:
    metadata: 
      labels: 
        id: {{ .Release.Name }}-deployment-backend-postgres
    spec:
      volumes:
        - name: {{ .Release.Name }}-data
          persistentVolumeClaim:
            claimName: {{ .Release.Name }}-volume-backend-postgres
      containers:
        - name: {{ .Release.Name }}-backend-postgres
          image: postgres:14.1
          imagePullPolicy: {{ .Values.pullPolicy }}
          env:
            - name: PGDATA
              value: /var/lib/postgresql/data/data
            - name: POSTGRES_DB
              value: backend
            - name: POSTGRES_PASSWORD
              value: {{ .Values.database.backend.internal.password }}
            - name: POSTGRES_USER
              value: backend
          ports:
            - name: postgres
              containerPort: 5432
              protocol: TCP
          readinessProbe:
            exec:
              command: ["psql", "-W", "{{ .Values.database.backend.internal.password }}", "-U", "backend", "-d", "backend", "-c", "SELECT 1"]
            initialDelaySeconds: 15
            timeoutSeconds: 2
          livenessProbe:
            exec:
              command: ["psql", "-W", "{{ .Values.database.backend.internal.password }}", "-U", "backend", "-d", "backend", "-c", "SELECT 1"]
            initialDelaySeconds: 45
            timeoutSeconds: 2
          resources:
            requests:
              memory: "128Mi"
              cpu: "250m"
            limits:
              memory: "1Gi"
              cpu: "1"
          volumeMounts:
            - name: {{ .Release.Name }}-data
              mountPath: /var/lib/postgresql/data
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}
{{ end }}

helm/templates/backend/garbage_cleaner.cronjob.yaml METASEP
{{- /* 
apiVersion: batch/v1
kind: CronJob
metadata:
  name: {{ .Release.Name }}-garbage-cleaner
  annotations:
    checksum/config_env: {{ include (print $.Template.BasePath "/backend/backend_env.configmap.yaml") . | sha256sum }}
spec:
  schedule: "{{ .Values.backend.garbageCleaner.cron }}"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: "OnFailure"
          containers: 
            - name: {{ .Release.Name }}-garbage-cleaner
              image: {{ .Values.docker.registry }}{{ .Values.docker.images.backend }}
              command: ["python3"]
              args: ["-m", "t4cclient.core.garbage_cleaner"]
              imagePullPolicy: {{ $.Values.pullPolicy }}
              envFrom:
                - configMapRef: 
                    name: {{ .Release.Name }}-backend-env
              resources: 
                limits:
                  cpu: "0.5"
                  memory: 100Mi
                requests:
                  cpu: "0.25"
                  memory: 10Mi
              securityContext:
                {{- toYaml $.Values.securityContext | nindent 16 }}
*/}}
helm/templates/backend/backend_env.configmap.yaml METASEP
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-backend-env
  namespace: {{ .Release.Namespace }}
  labels: 
    id: {{ .Release.Name }}-configmap-backend-env
data:
    OAUTH_TOKEN_ISSUANCE_ENDPOINT: {{ .Values.backend.oauth.tokenIssuanceEndpoint }}
    OAUTH_AUTHORIZATION_ENDPOINT: {{ .Values.backend.oauth.authorizationEndpoint }}
    OAUTH_CLIENT_ID: "{{ .Values.backend.oauth.client.id }}"
    OAUTH_CLIENT_SECRET: "{{ .Values.backend.oauth.client.secret }}"
    OAUTH_REDIRECT_URI: "{{ .Values.general.scheme }}://{{ .Values.general.host }}/oauth2/callback"
    OAUTH_USERNAME_CLAIM: {{ .Values.backend.oauth.usernameClaim }}
    DOCKER_PERSISTENT_IMAGE: {{ .Values.docker.registry }}{{ .Values.docker.images.workspaces.persistent }}
    DOCKER_READONLY_IMAGE: {{ .Values.docker.registry }}{{ .Values.docker.images.workspaces.readonly }}
    DOCKER_EASE_IMAGE: {{ .Values.docker.registry }}{{ .Values.docker.images.ease }}
    GUACAMOLE_BASE_URI: "http://{{ .Release.Name }}-guacamole-guacamole:8080/guacamole"
    GUACAMOLE_PUBLIC_URI: "{{ .Values.general.scheme }}://{{ .Values.general.host }}:{{ .Values.general.port }}/guacamole"
    GUACAMOLE_USERNAME: "{{ .Values.guacamole.username }}"
    GUACAMOLE_PASSWORD: "{{ .Values.guacamole.password }}"
    {{ if .Values.database.deploy }}
    SQL_DATABASE_URL: "postgresql://backend:{{ .Values.database.backend.internal.password }}@{{ .Release.Name }}-backend-postgres:5432/backend"
    {{ else }}
    SQL_DATABASE_URL: {{ .Values.database.backend.external.uri }}
    {{ end }}
    T4C_SERVER_USAGE_API: {{ .Values.t4cServer.apis.usageStats }}
    T4C_SERVER_REST_API: {{ .Values.t4cServer.apis.restAPI }}
    T4C_SERVER_USERNAME: {{ .Values.t4cServer.username }}
    T4C_SERVER_PASSWORD: {{ .Values.t4cServer.password }}
    T4C_SERVER_HOST: "{{ .Values.t4cServer.host }}"
    T4C_SERVER_PORT: "{{ .Values.t4cServer.port }}"
    T4C_SERVER_LICENCE: "{{ .Values.t4cServer.licenseKey }}"
    KUBERNETES_NAMESPACE: {{ .Values.backend.k8sSessionNamespace }}
    KUBERNETES_STORAGE_CLASS_NAME: {{ .Values.backend.storageClassName }}
    KUBERNETES_STORAGE_ACCESS_MODE: {{ .Values.backend.storageAccessMode }}
    KUBERNETES_RELEASE_NAME: {{ .Release.Name }}
    OPERATOR_TYPE: kubernetes
    JENKINS_USERNAME: {{ .Values.jenkins.username }}
    JENKINS_PASSWORD: {{ .Values.jenkins.password }}
    JENKINS_BASE_URL: {{ .Values.jenkins.baseURL }}
    JENKINS_GIT_USERNAME: {{ .Values.git.username }}
    JENKINS_GIT_EMAIL: {{ .Values.git.email }}
    JENKINS_GIT_CREDENTIAL_ID: {{ .Values.git.credentialID }}
    JENKINS_GIT_SCRIPT_REPO_URL: {{ .Values.git.scriptRepoURL }}
    GIT_USERNAME: {{ .Values.git.username }}
    GIT_PASSWORD: {{ .Values.git.password }}
    USERS_INITIAL_ADMIN: {{ .Values.database.backend.initialAdmin }}

helm/templates/backend/backend.serviceaccount.yaml METASEP
apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{ .Release.Name }}-serviceaccount-backend
  namespace: {{ .Release.Namespace }}
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 namespace: {{ .Values.backend.k8sSessionNamespace }}
 name: {{ .Release.Name }}-role-backend
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "create", "delete"]
- apiGroups: [""]
  resources: ["services"]
  verbs: ["get", "create", "delete"]
- apiGroups: [""]
  resources: ["persistentvolumeclaims"]
  verbs: ["get", "create"]
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: {{ .Release.Name }}-rolebinding-backend
  namespace: {{ .Values.backend.k8sSessionNamespace }}
subjects:
- kind: ServiceAccount
  name: {{ .Release.Name }}-serviceaccount-backend
  apiGroup: ""
  namespace: {{ .Release.Namespace }}
roleRef:
  kind: Role
  name: {{ .Release.Name }}-role-backend
  apiGroup: rbac.authorization.k8s.io

helm/templates/backend/backend.service.yaml METASEP
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}-backend
  labels: 
    id: {{ .Release.Name }}-service-backend
spec:
  type: ClusterIP
  selector:
    id: {{ .Release.Name }}-deployment-backend
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http

helm/templates/backend/backend.deployment.yaml METASEP
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-backend
  labels: 
    id: {{ .Release.Name }}-deployment-backend
  annotations:
    checksum/config: {{ include (print $.Template.BasePath "/backend/backend.configmap.yaml") . | sha256sum }}
    checksum/config_env: {{ include (print $.Template.BasePath "/backend/backend_env.configmap.yaml") . | sha256sum }}
spec:
  replicas: {{ .Values.replicaCount | default 1 }}
  selector: 
    matchLabels: 
      id: {{ .Release.Name }}-deployment-backend
  template:
    metadata: 
      labels: 
        id: {{ .Release.Name }}-deployment-backend
    spec:
      serviceAccountName: {{ .Release.Name }}-serviceaccount-backend
      volumes:
        - name: {{ .Release.Name }}-backend
          configMap:
            name: {{ .Release.Name }}-backend
      containers:
        - name: {{ .Release.Name }}-backend
          image: {{ .Values.docker.registry }}{{ .Values.docker.images.backend }}
          imagePullPolicy: {{ .Values.pullPolicy }}
          envFrom:
            - configMapRef: 
                name: {{ .Release.Name }}-backend-env
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /healthcheck
              port: http
          readinessProbe: 
            httpGet:
              path: /healthcheck
              port: http
          resources:
            limits:
              cpu: "1"
              memory: 200Mi
            requests:
              cpu: "0.25"
              memory: 20Mi
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}

helm/templates/backend/backend.configmap.yaml METASEP
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-backend
  namespace: {{ .Release.Namespace }}
  labels: 
    id: {{ .Release.Name }}-configmap-backend
data:

frontend/tsconfig.spec.json METASEP
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/spec",
    "types": [
      "jasmine"
    ]
  },
  "files": [
    "src/test.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.spec.ts",
    "src/**/*.d.ts"
  ]
}

frontend/tsconfig.json METASEP
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2017",
    "module": "es2020",
    "lib": [
      "es2018",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}

frontend/tsconfig.app.json METASEP
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": []
  },
  "files": [
    "src/main.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

frontend/package.json METASEP
{
  "name": "t4cclient",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~12.1.0",
    "@angular/cdk": "^12.1.1",
    "@angular/common": "~12.1.0",
    "@angular/compiler": "~12.1.0",
    "@angular/core": "~12.1.0",
    "@angular/forms": "~12.1.0",
    "@angular/material": "^12.1.1",
    "@angular/platform-browser": "~12.1.0",
    "@angular/platform-browser-dynamic": "~12.1.0",
    "@angular/router": "~12.1.0",
    "rxjs": "~6.6.0",
    "simplebar-angular": "^2.3.5",
    "tslib": "^2.2.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~12.1.0",
    "@angular/cli": "~12.1.0",
    "@angular/compiler-cli": "~12.1.0",
    "@types/jasmine": "~3.6.0",
    "@types/node": "^12.11.1",
    "jasmine-core": "~3.7.0",
    "karma": "~6.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "typescript": "~4.3.2"
  }
}

frontend/package-lock.json METASEP
{
  "name": "t4cclient",
  "version": "0.0.0",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "": {
      "name": "t4cclient",
      "version": "0.0.0",
      "dependencies": {
        "@angular/animations": "~12.1.0",
        "@angular/cdk": "^12.1.1",
        "@angular/common": "~12.1.0",
        "@angular/compiler": "~12.1.0",
        "@angular/core": "~12.1.0",
        "@angular/forms": "~12.1.0",
        "@angular/material": "^12.1.1",
        "@angular/platform-browser": "~12.1.0",
        "@angular/platform-browser-dynamic": "~12.1.0",
        "@angular/router": "~12.1.0",
        "rxjs": "~6.6.0",
        "simplebar-angular": "^2.3.5",
        "tslib": "^2.2.0",
        "zone.js": "~0.11.4"
      },
      "devDependencies": {
        "@angular-devkit/build-angular": "~12.1.0",
        "@angular/cli": "~12.1.0",
        "@angular/compiler-cli": "~12.1.0",
        "@types/jasmine": "~3.6.0",
        "@types/node": "^12.11.1",
        "jasmine-core": "~3.7.0",
        "karma": "~6.3.0",
        "karma-chrome-launcher": "~3.1.0",
        "karma-coverage": "~2.0.3",
        "karma-jasmine": "~4.0.0",
        "karma-jasmine-html-reporter": "^1.5.0",
        "typescript": "~4.3.2"
      }
    },
    "node_modules/@angular-devkit/architect": {
      "version": "0.1201.4",
      "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1201.4.tgz",
      "integrity": "sha512-hGO5NrZxV8Z7sILwokt7H+1sMf+5tJS9PJszvYlIBSzG0LBkOwwLQDb4MD42ATXFru57SXNqMZDVKoi1kTgxAw==",
      "dev": true,
      "dependencies": {
        "@angular-devkit/core": "12.1.4",
        "rxjs": "6.6.7"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0",
        "npm": "^6.11.0 || ^7.5.6",
        "yarn": ">= 1.13.0"
      }
    },
    "node_modules/@angular-devkit/build-angular": {
      "version": "12.1.4",
      "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-12.1.4.tgz",
      "integrity": "sha512-9kMdnaU2dr8o7gJpuBsEHLUpa6huF8uZQEd1+jhKfByEY/xTQo8qztvmbhFhrSfDvdYRygNHItpt3pYEoCEOig==",
      "dev": true,
      "dependencies": {
        "@angular-devkit/architect": "0.1201.4",
        "@angular-devkit/build-optimizer": "0.1201.4",
        "@angular-devkit/build-webpack": "0.1201.4",
        "@angular-devkit/core": "12.1.4",
        "@babel/core": "7.14.6",
        "@babel/generator": "7.14.5",
        "@babel/helper-annotate-as-pure": "7.14.5",
        "@babel/plugin-proposal-async-generator-functions": "7.14.7",
        "@babel/plugin-transform-async-to-generator": "7.14.5",
        "@babel/plugin-transform-runtime": "7.14.5",
        "@babel/preset-env": "7.14.7",
        "@babel/runtime": "7.14.6",
        "@babel/template": "7.14.5",
        "@discoveryjs/json-ext": "0.5.3",
        "@jsdevtools/coverage-istanbul-loader": "3.0.5",
        "@ngtools/webpack": "12.1.4",
        "ansi-colors": "4.1.1",
        "babel-loader": "8.2.2",
        "browserslist": "^4.9.1",
        "cacache": "15.2.0",
        "caniuse-lite": "^1.0.30001032",
        "circular-dependency-plugin": "5.2.2",
        "copy-webpack-plugin": "9.0.0",
        "core-js": "3.15.1",
        "critters": "0.0.10",
        "css-loader": "5.2.6",
        "css-minimizer-webpack-plugin": "3.0.1",
        "find-cache-dir": "3.3.1",
        "glob": "7.1.7",
        "https-proxy-agent": "5.0.0",
        "inquirer": "8.1.1",
        "jest-worker": "27.0.2",
        "karma-source-map-support": "1.4.0",
        "less": "4.1.1",
        "less-loader": "10.0.0",
        "license-webpack-plugin": "2.3.20",
        "loader-utils": "2.0.0",
        "mini-css-extract-plugin": "1.6.2",
        "minimatch": "3.0.4",
        "open": "8.2.1",
        "ora": "5.4.1",
        "parse5-html-rewriting-stream": "6.0.1",
        "postcss": "8.3.5",
        "postcss-import": "14.0.2",
        "postcss-loader": "6.1.0",
        "postcss-preset-env": "6.7.0",
        "raw-loader": "4.0.2",
        "regenerator-runtime": "0.13.7",
        "resolve-url-loader": "4.0.0",
        "rxjs": "6.6.7",
        "sass": "1.35.1",
        "sass-loader": "12.1.0",
        "semver": "7.3.5",
        "source-map": "0.7.3",
        "source-map-loader": "3.0.0",
        "source-map-support": "0.5.19",
        "style-loader": "2.0.0",
        "stylus": "0.54.8",
        "stylus-loader": "6.1.0",
        "terser": "5.7.0",
        "terser-webpack-plugin": "5.1.3",
        "text-table": "0.2.0",
        "tree-kill": "1.2.2",
        "tslib": "2.3.0",
        "webpack": "5.44.0",
        "webpack-dev-middleware": "5.0.0",
        "webpack-dev-server": "3.11.2",
        "webpack-merge": "5.8.0",
        "webpack-subresource-integrity": "1.5.2"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0",
        "npm": "^6.11.0 || ^7.5.6",
        "yarn": ">= 1.13.0"
      },
      "peerDependencies": {
        "@angular/compiler-cli": "^12.0.0 || ^12.1.0-next",
        "@angular/localize": "^12.0.0 || ^12.1.0-next",
        "@angular/service-worker": "^12.0.0 || ^12.1.0-next",
        "karma": "^6.3.0",
        "ng-packagr": "^12.0.0 || ^12.1.0-next",
        "protractor": "^7.0.0",
        "tailwindcss": "^2.0.0",
        "tslint": "^6.1.0",
        "typescript": "~4.2.3 || ~4.3.2"
      },
      "peerDependenciesMeta": {
        "@angular/localize": {
          "optional": true
        },
        "@angular/service-worker": {
          "optional": true
        },
        "karma": {
          "optional": true
        },
        "ng-packagr": {
          "optional": true
        },
        "protractor": {
          "optional": true
        },
        "tailwindcss": {
          "optional": true
        },
        "tslint": {
          "optional": true
        }
      }
    },
    "node_modules/@angular-devkit/build-angular/node_modules/tslib": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
      "dev": true
    },
    "node_modules/@angular-devkit/build-optimizer": {
      "version": "0.1201.4",
      "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.1201.4.tgz",
      "integrity": "sha512-Hq+mDUe4xIyq4939JZaUkptsM89WnZOk8Qel6mS0T/bxMX/qs+nuGD5o+xDKkuayogbiTrLmyZBib0/90eSXEA==",
      "dev": true,
      "dependencies": {
        "source-map": "0.7.3",
        "tslib": "2.3.0",
        "typescript": "4.3.4"
      },
      "bin": {
        "build-optimizer": "src/build-optimizer/cli.js"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0",
        "npm": "^6.11.0 || ^7.5.6",
        "yarn": ">= 1.13.0"
      },
      "peerDependencies": {
        "webpack": "^5.30.0"
      },
      "peerDependenciesMeta": {
        "webpack": {
          "optional": true
        }
      }
    },
    "node_modules/@angular-devkit/build-optimizer/node_modules/tslib": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
      "dev": true
    },
    "node_modules/@angular-devkit/build-optimizer/node_modules/typescript": {
      "version": "4.3.4",
      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz",
      "integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==",
      "dev": true,
      "bin": {
        "tsc": "bin/tsc",
        "tsserver": "bin/tsserver"
      },
      "engines": {
        "node": ">=4.2.0"
      }
    },
    "node_modules/@angular-devkit/build-webpack": {
      "version": "0.1201.4",
      "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1201.4.tgz",
      "integrity": "sha512-eMmbyHyWJZMQ1tfwVdja/iAk/eXJFYrF8b27gDV9gGI7MGB3KJ93AhkbPbcvlw4Hhx4+6M11GfeXzbwH0q9pnQ==",
      "dev": true,
      "dependencies": {
        "@angular-devkit/architect": "0.1201.4",
        "rxjs": "6.6.7"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0",
        "npm": "^6.11.0 || ^7.5.6",
        "yarn": ">= 1.13.0"
      },
      "peerDependencies": {
        "webpack": "^5.30.0",
        "webpack-dev-server": "^3.1.4"
      }
    },
    "node_modules/@angular-devkit/core": {
      "version": "12.1.4",
      "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.1.4.tgz",
      "integrity": "sha512-KOzGD8JbP/7EeUwPiU5x+fo3ZEQ5R4IVW5WoH92PaO3mdpqXC7UL2MWLct8PUe9il9nqJMvrBMldSSvP9PCT2w==",
      "dev": true,
      "dependencies": {
        "ajv": "8.6.0",
        "ajv-formats": "2.1.0",
        "fast-json-stable-stringify": "2.1.0",
        "magic-string": "0.25.7",
        "rxjs": "6.6.7",
        "source-map": "0.7.3"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0",
        "npm": "^6.11.0 || ^7.5.6",
        "yarn": ">= 1.13.0"
      }
    },
    "node_modules/@angular-devkit/schematics": {
      "version": "12.1.4",
      "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-12.1.4.tgz",
      "integrity": "sha512-yD3y3pK/K5piOgvALFoCCiPp4H8emNa3yZL+vlpEpewVLpF1MM55LeTxc0PI5s0uqtOGVnvcbA5wYgMm3YsUEA==",
      "dev": true,
      "dependencies": {
        "@angular-devkit/core": "12.1.4",
        "ora": "5.4.1",
        "rxjs": "6.6.7"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0",
        "npm": "^6.11.0 || ^7.5.6",
        "yarn": ">= 1.13.0"
      }
    },
    "node_modules/@angular/animations": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-12.1.5.tgz",
      "integrity": "sha512-t17n8RuzkY7lYawmI01WuNWf70ttvEPknmS3sh7q2IAsBdRiLQCBmh6Hw5q0SBaQNoRWNIcUWKBwl4EmyXOtrA==",
      "dependencies": {
        "tslib": "^2.2.0"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0"
      },
      "peerDependencies": {
        "@angular/core": "12.1.5"
      }
    },
    "node_modules/@angular/cdk": {
      "version": "12.2.13",
      "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-12.2.13.tgz",
      "integrity": "sha512-zSKRhECyFqhingIeyRInIyTvYErt4gWo+x5DQr0b7YLUbU8DZSwWnG4w76Ke2s4U8T7ry1jpJBHoX/e8YBpGMg==",
      "dependencies": {
        "tslib": "^2.2.0"
      },
      "optionalDependencies": {
        "parse5": "^5.0.0"
      },
      "peerDependencies": {
        "@angular/common": "^12.0.0 || ^13.0.0-0",
        "@angular/core": "^12.0.0 || ^13.0.0-0",
        "rxjs": "^6.5.3 || ^7.0.0"
      }
    },
    "node_modules/@angular/cli": {
      "version": "12.1.4",
      "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-12.1.4.tgz",
      "integrity": "sha512-LpyhyqWe3bFcuH3MrXeYoIPI1htjwG1b5ehETfq4qsMvNmuFON6QI+F7EWEpX7lItVQc2bES+ogasTZsZue/uw==",
      "dev": true,
      "hasInstallScript": true,
      "dependencies": {
        "@angular-devkit/architect": "0.1201.4",
        "@angular-devkit/core": "12.1.4",
        "@angular-devkit/schematics": "12.1.4",
        "@schematics/angular": "12.1.4",
        "@yarnpkg/lockfile": "1.1.0",
        "ansi-colors": "4.1.1",
        "debug": "4.3.1",
        "ini": "2.0.0",
        "inquirer": "8.1.1",
        "jsonc-parser": "3.0.0",
        "npm-package-arg": "8.1.5",
        "npm-pick-manifest": "6.1.1",
        "open": "8.2.1",
        "ora": "5.4.1",
        "pacote": "11.3.4",
        "resolve": "1.20.0",
        "semver": "7.3.5",
        "symbol-observable": "4.0.0",
        "uuid": "8.3.2"
      },
      "bin": {
        "ng": "bin/ng"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0",
        "npm": "^6.11.0 || ^7.5.6",
        "yarn": ">= 1.13.0"
      }
    },
    "node_modules/@angular/common": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/common/-/common-12.1.5.tgz",
      "integrity": "sha512-xs33eMhV79S85nbH5FVmujKY3OoczloW9oOGRe5tCzxsDDv85hadrB8Mbm3qI5WQ99DNk8M2+P0MW6uiyCAWkQ==",
      "dependencies": {
        "tslib": "^2.2.0"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0"
      },
      "peerDependencies": {
        "@angular/core": "12.1.5",
        "rxjs": "^6.5.3"
      }
    },
    "node_modules/@angular/compiler": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-12.1.5.tgz",
      "integrity": "sha512-MBrNCuTFmBiTy+sqmBYRqfBHPBJeONvRWOxHepn/CMtjHJiTZ+PHG61Chu2ySxLBuOZxAGaP4GMcqIc15G742g==",
      "dependencies": {
        "tslib": "^2.2.0"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0"
      }
    },
    "node_modules/@angular/compiler-cli": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-12.1.5.tgz",
      "integrity": "sha512-5YqZ5heKS3G5t3Fg9L26UedNnum8F9yjNDgUq0qvYR2b6nEDOLYgUxuUSRtg6IGDglSgbxpkgkGNd/SHF9Iu8A==",
      "dev": true,
      "dependencies": {
        "@babel/core": "^7.8.6",
        "@babel/types": "^7.8.6",
        "canonical-path": "1.0.0",
        "chokidar": "^3.0.0",
        "convert-source-map": "^1.5.1",
        "dependency-graph": "^0.11.0",
        "magic-string": "^0.25.0",
        "minimist": "^1.2.0",
        "reflect-metadata": "^0.1.2",
        "semver": "^7.0.0",
        "source-map": "^0.6.1",
        "sourcemap-codec": "^1.4.8",
        "tslib": "^2.2.0",
        "yargs": "^17.0.0"
      },
      "bin": {
        "ivy-ngcc": "ngcc/main-ivy-ngcc.js",
        "ng-xi18n": "src/extract_i18n.js",
        "ngc": "src/main.js",
        "ngcc": "ngcc/main-ngcc.js"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0"
      },
      "peerDependencies": {
        "@angular/compiler": "12.1.5",
        "typescript": ">=4.2.3 <4.4"
      }
    },
    "node_modules/@angular/compiler-cli/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/@angular/core": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/core/-/core-12.1.5.tgz",
      "integrity": "sha512-okXnhAPxfblAWSe5M/IqrSATi+ul83a9o9PWOTFR/XCVcbx+neE2IwIr1dIDKBKj91b1CFalLS+uOSkN05PNkA==",
      "dependencies": {
        "tslib": "^2.2.0"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0"
      },
      "peerDependencies": {
        "rxjs": "^6.5.3",
        "zone.js": "~0.11.4"
      }
    },
    "node_modules/@angular/forms": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-12.1.5.tgz",
      "integrity": "sha512-ABfBRCZYVbR5MUkMNrYU/ovCjXtCedk0h4phzCimGl6hBcpbumT9z/3m0TsY9sQnLq0BaCfKNklnHwCuO9mSSg==",
      "dependencies": {
        "tslib": "^2.2.0"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0"
      },
      "peerDependencies": {
        "@angular/common": "12.1.5",
        "@angular/core": "12.1.5",
        "@angular/platform-browser": "12.1.5",
        "rxjs": "^6.5.3"
      }
    },
    "node_modules/@angular/material": {
      "version": "12.2.13",
      "resolved": "https://registry.npmjs.org/@angular/material/-/material-12.2.13.tgz",
      "integrity": "sha512-6g2GyN4qp2D+DqY2AwrQuPB3cd9gybvQVXvNRbTPXEulHr+LgGei00ySdFHFp6RvdGSMZ4i3LM1Fq3VkFxhCfQ==",
      "dependencies": {
        "tslib": "^2.2.0"
      },
      "peerDependencies": {
        "@angular/animations": "^12.0.0 || ^13.0.0-0",
        "@angular/cdk": "12.2.13",
        "@angular/common": "^12.0.0 || ^13.0.0-0",
        "@angular/core": "^12.0.0 || ^13.0.0-0",
        "@angular/forms": "^12.0.0 || ^13.0.0-0",
        "rxjs": "^6.5.3 || ^7.0.0"
      }
    },
    "node_modules/@angular/platform-browser": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-12.1.5.tgz",
      "integrity": "sha512-UNlmvCY8cS1/WojCJtgf/EMMN8qdPV1IQa6vZ6/ChQiS38YlH+aQEOCcxtSSfMFmWjaz7j67u55vSlkvA4rApQ==",
      "dependencies": {
        "tslib": "^2.2.0"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0"
      },
      "peerDependencies": {
        "@angular/animations": "12.1.5",
        "@angular/common": "12.1.5",
        "@angular/core": "12.1.5"
      },
      "peerDependenciesMeta": {
        "@angular/animations": {
          "optional": true
        }
      }
    },
    "node_modules/@angular/platform-browser-dynamic": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-12.1.5.tgz",
      "integrity": "sha512-4Anc2pRGRnBHzSeWMYOaEs6hUYw09N/WsOg1lHevZ8abwXyo80xOKiZa+kfgFkst0XaY8DzuDQFnj7opcEVdCQ==",
      "dependencies": {
        "tslib": "^2.2.0"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0"
      },
      "peerDependencies": {
        "@angular/common": "12.1.5",
        "@angular/compiler": "12.1.5",
        "@angular/core": "12.1.5",
        "@angular/platform-browser": "12.1.5"
      }
    },
    "node_modules/@angular/router": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/router/-/router-12.1.5.tgz",
      "integrity": "sha512-ZZFLcaenVFKCyaxD3mU4cuV4RNFwCEN6JLWmkOFkwIt01RVJcvPaPxiv4pfQf5hnk2HeSciMA0J+UIzSu5YKMA==",
      "dependencies": {
        "tslib": "^2.2.0"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0"
      },
      "peerDependencies": {
        "@angular/common": "12.1.5",
        "@angular/core": "12.1.5",
        "@angular/platform-browser": "12.1.5",
        "rxjs": "^6.5.3"
      }
    },
    "node_modules/@babel/code-frame": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz",
      "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==",
      "dev": true,
      "dependencies": {
        "@babel/highlight": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/compat-data": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz",
      "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==",
      "dev": true,
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/core": {
      "version": "7.14.6",
      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz",
      "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==",
      "dev": true,
      "dependencies": {
        "@babel/code-frame": "^7.14.5",
        "@babel/generator": "^7.14.5",
        "@babel/helper-compilation-targets": "^7.14.5",
        "@babel/helper-module-transforms": "^7.14.5",
        "@babel/helpers": "^7.14.6",
        "@babel/parser": "^7.14.6",
        "@babel/template": "^7.14.5",
        "@babel/traverse": "^7.14.5",
        "@babel/types": "^7.14.5",
        "convert-source-map": "^1.7.0",
        "debug": "^4.1.0",
        "gensync": "^1.0.0-beta.2",
        "json5": "^2.1.2",
        "semver": "^6.3.0",
        "source-map": "^0.5.0"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/babel"
      }
    },
    "node_modules/@babel/core/node_modules/semver": {
      "version": "6.3.0",
      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
      "dev": true,
      "bin": {
        "semver": "bin/semver.js"
      }
    },
    "node_modules/@babel/core/node_modules/source-map": {
      "version": "0.5.7",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/@babel/generator": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
      "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.14.5",
        "jsesc": "^2.5.1",
        "source-map": "^0.5.0"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/generator/node_modules/source-map": {
      "version": "0.5.7",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/@babel/helper-annotate-as-pure": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz",
      "integrity": "sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.14.5"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz",
      "integrity": "sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA==",
      "dev": true,
      "dependencies": {
        "@babel/helper-explode-assignable-expression": "^7.16.7",
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-compilation-targets": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz",
      "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==",
      "dev": true,
      "dependencies": {
        "@babel/compat-data": "^7.16.4",
        "@babel/helper-validator-option": "^7.16.7",
        "browserslist": "^4.17.5",
        "semver": "^6.3.0"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0"
      }
    },
    "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
      "version": "6.3.0",
      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
      "dev": true,
      "bin": {
        "semver": "bin/semver.js"
      }
    },
    "node_modules/@babel/helper-create-class-features-plugin": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.7.tgz",
      "integrity": "sha512-kIFozAvVfK05DM4EVQYKK+zteWvY85BFdGBRQBytRyY3y+6PX0DkDOn/CZ3lEuczCfrCxEzwt0YtP/87YPTWSw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-annotate-as-pure": "^7.16.7",
        "@babel/helper-environment-visitor": "^7.16.7",
        "@babel/helper-function-name": "^7.16.7",
        "@babel/helper-member-expression-to-functions": "^7.16.7",
        "@babel/helper-optimise-call-expression": "^7.16.7",
        "@babel/helper-replace-supers": "^7.16.7",
        "@babel/helper-split-export-declaration": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0"
      }
    },
    "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-annotate-as-pure": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz",
      "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-create-regexp-features-plugin": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz",
      "integrity": "sha512-fk5A6ymfp+O5+p2yCkXAu5Kyj6v0xh0RBeNcAkYUMDvvAAoxvSKXn+Jb37t/yWFiQVDFK1ELpUTD8/aLhCPu+g==",
      "dev": true,
      "dependencies": {
        "@babel/helper-annotate-as-pure": "^7.16.7",
        "regexpu-core": "^4.7.1"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0"
      }
    },
    "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/@babel/helper-annotate-as-pure": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz",
      "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-define-polyfill-provider": {
      "version": "0.2.4",
      "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.4.tgz",
      "integrity": "sha512-OrpPZ97s+aPi6h2n1OXzdhVis1SGSsMU2aMHgLcOKfsp4/v1NWpx3CWT3lBj5eeBq9cDkPkh+YCfdF7O12uNDQ==",
      "dev": true,
      "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"
      },
      "peerDependencies": {
        "@babel/core": "^7.4.0-0"
      }
    },
    "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": {
      "version": "6.3.0",
      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
      "dev": true,
      "bin": {
        "semver": "bin/semver.js"
      }
    },
    "node_modules/@babel/helper-environment-visitor": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz",
      "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-explode-assignable-expression": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz",
      "integrity": "sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-function-name": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz",
      "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==",
      "dev": true,
      "dependencies": {
        "@babel/helper-get-function-arity": "^7.16.7",
        "@babel/template": "^7.16.7",
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-function-name/node_modules/@babel/template": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz",
      "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==",
      "dev": true,
      "dependencies": {
        "@babel/code-frame": "^7.16.7",
        "@babel/parser": "^7.16.7",
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-get-function-arity": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz",
      "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-hoist-variables": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz",
      "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-member-expression-to-functions": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz",
      "integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-module-imports": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz",
      "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-module-transforms": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz",
      "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==",
      "dev": true,
      "dependencies": {
        "@babel/helper-environment-visitor": "^7.16.7",
        "@babel/helper-module-imports": "^7.16.7",
        "@babel/helper-simple-access": "^7.16.7",
        "@babel/helper-split-export-declaration": "^7.16.7",
        "@babel/helper-validator-identifier": "^7.16.7",
        "@babel/template": "^7.16.7",
        "@babel/traverse": "^7.16.7",
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-module-transforms/node_modules/@babel/template": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz",
      "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==",
      "dev": true,
      "dependencies": {
        "@babel/code-frame": "^7.16.7",
        "@babel/parser": "^7.16.7",
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-optimise-call-expression": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz",
      "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-plugin-utils": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz",
      "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==",
      "dev": true,
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-remap-async-to-generator": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz",
      "integrity": "sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-annotate-as-pure": "^7.16.7",
        "@babel/helper-wrap-function": "^7.16.8",
        "@babel/types": "^7.16.8"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/helper-annotate-as-pure": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz",
      "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-replace-supers": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz",
      "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-environment-visitor": "^7.16.7",
        "@babel/helper-member-expression-to-functions": "^7.16.7",
        "@babel/helper-optimise-call-expression": "^7.16.7",
        "@babel/traverse": "^7.16.7",
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-simple-access": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz",
      "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
      "version": "7.16.0",
      "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz",
      "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.0"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-split-export-declaration": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz",
      "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-validator-identifier": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz",
      "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==",
      "dev": true,
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-validator-option": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz",
      "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==",
      "dev": true,
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-wrap-function": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz",
      "integrity": "sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-function-name": "^7.16.7",
        "@babel/template": "^7.16.7",
        "@babel/traverse": "^7.16.8",
        "@babel/types": "^7.16.8"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-wrap-function/node_modules/@babel/template": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz",
      "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==",
      "dev": true,
      "dependencies": {
        "@babel/code-frame": "^7.16.7",
        "@babel/parser": "^7.16.7",
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helpers": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz",
      "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==",
      "dev": true,
      "dependencies": {
        "@babel/template": "^7.16.7",
        "@babel/traverse": "^7.16.7",
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helpers/node_modules/@babel/template": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz",
      "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==",
      "dev": true,
      "dependencies": {
        "@babel/code-frame": "^7.16.7",
        "@babel/parser": "^7.16.7",
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/highlight": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz",
      "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-validator-identifier": "^7.16.7",
        "chalk": "^2.0.0",
        "js-tokens": "^4.0.0"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/parser": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.8.tgz",
      "integrity": "sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw==",
      "dev": true,
      "bin": {
        "parser": "bin/babel-parser.js"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz",
      "integrity": "sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0",
        "@babel/plugin-proposal-optional-chaining": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.13.0"
      }
    },
    "node_modules/@babel/plugin-proposal-async-generator-functions": {
      "version": "7.14.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz",
      "integrity": "sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.14.5",
        "@babel/helper-remap-async-to-generator": "^7.14.5",
        "@babel/plugin-syntax-async-generators": "^7.8.4"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-proposal-class-properties": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz",
      "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==",
      "dev": true,
      "dependencies": {
        "@babel/helper-create-class-features-plugin": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-proposal-class-static-block": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.7.tgz",
      "integrity": "sha512-dgqJJrcZoG/4CkMopzhPJjGxsIe9A8RlkQLnL/Vhhx8AA9ZuaRwGSlscSh42hazc7WSrya/IK7mTeoF0DP9tEw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-create-class-features-plugin": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-class-static-block": "^7.14.5"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.12.0"
      }
    },
    "node_modules/@babel/plugin-proposal-dynamic-import": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz",
      "integrity": "sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-dynamic-import": "^7.8.3"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-proposal-export-namespace-from": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz",
      "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-proposal-json-strings": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz",
      "integrity": "sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-json-strings": "^7.8.3"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-proposal-logical-assignment-operators": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz",
      "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz",
      "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-proposal-numeric-separator": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz",
      "integrity": "sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-numeric-separator": "^7.10.4"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-proposal-object-rest-spread": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.7.tgz",
      "integrity": "sha512-3O0Y4+dw94HA86qSg9IHfyPktgR7q3gpNVAeiKQd+8jBKFaU5NQS1Yatgo4wY+UFNuLjvxcSmzcsHqrhgTyBUA==",
      "dev": true,
      "dependencies": {
        "@babel/compat-data": "^7.16.4",
        "@babel/helper-compilation-targets": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
        "@babel/plugin-transform-parameters": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-proposal-optional-catch-binding": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz",
      "integrity": "sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-proposal-optional-chaining": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz",
      "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0",
        "@babel/plugin-syntax-optional-chaining": "^7.8.3"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-proposal-private-methods": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.7.tgz",
      "integrity": "sha512-7twV3pzhrRxSwHeIvFE6coPgvo+exNDOiGUMg39o2LiLo1Y+4aKpfkcLGcg1UHonzorCt7SNXnoMyCnnIOA8Sw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-create-class-features-plugin": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-proposal-private-property-in-object": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz",
      "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==",
      "dev": true,
      "dependencies": {
        "@babel/helper-annotate-as-pure": "^7.16.7",
        "@babel/helper-create-class-features-plugin": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-proposal-private-property-in-object/node_modules/@babel/helper-annotate-as-pure": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz",
      "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/plugin-proposal-unicode-property-regex": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz",
      "integrity": "sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-create-regexp-features-plugin": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=4"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-syntax-async-generators": {
      "version": "7.8.4",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
      "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.8.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-syntax-class-properties": {
      "version": "7.12.13",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
      "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.12.13"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-syntax-class-static-block": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
      "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.14.5"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-syntax-dynamic-import": {
      "version": "7.8.3",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
      "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.8.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-syntax-export-namespace-from": {
      "version": "7.8.3",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
      "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.8.3"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-syntax-json-strings": {
      "version": "7.8.3",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
      "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.8.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
      "version": "7.10.4",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
      "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.10.4"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
      "version": "7.8.3",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
      "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.8.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-syntax-numeric-separator": {
      "version": "7.10.4",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
      "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.10.4"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-syntax-object-rest-spread": {
      "version": "7.8.3",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
      "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.8.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-syntax-optional-catch-binding": {
      "version": "7.8.3",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
      "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.8.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-syntax-optional-chaining": {
      "version": "7.8.3",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
      "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.8.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-syntax-private-property-in-object": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
      "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.14.5"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-syntax-top-level-await": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
      "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.14.5"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-arrow-functions": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz",
      "integrity": "sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-async-to-generator": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz",
      "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==",
      "dev": true,
      "dependencies": {
        "@babel/helper-module-imports": "^7.14.5",
        "@babel/helper-plugin-utils": "^7.14.5",
        "@babel/helper-remap-async-to-generator": "^7.14.5"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-block-scoped-functions": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz",
      "integrity": "sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-block-scoping": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz",
      "integrity": "sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-classes": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz",
      "integrity": "sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==",
      "dev": true,
      "dependencies": {
        "@babel/helper-annotate-as-pure": "^7.16.7",
        "@babel/helper-environment-visitor": "^7.16.7",
        "@babel/helper-function-name": "^7.16.7",
        "@babel/helper-optimise-call-expression": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/helper-replace-supers": "^7.16.7",
        "@babel/helper-split-export-declaration": "^7.16.7",
        "globals": "^11.1.0"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-annotate-as-pure": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz",
      "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/plugin-transform-computed-properties": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz",
      "integrity": "sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-destructuring": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz",
      "integrity": "sha512-VqAwhTHBnu5xBVDCvrvqJbtLUa++qZaWC0Fgr2mqokBlulZARGyIvZDoqbPlPaKImQ9dKAcCzbv+ul//uqu70A==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-dotall-regex": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz",
      "integrity": "sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==",
      "dev": true,
      "dependencies": {
        "@babel/helper-create-regexp-features-plugin": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-duplicate-keys": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz",
      "integrity": "sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-exponentiation-operator": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz",
      "integrity": "sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA==",
      "dev": true,
      "dependencies": {
        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-for-of": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz",
      "integrity": "sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-function-name": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz",
      "integrity": "sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA==",
      "dev": true,
      "dependencies": {
        "@babel/helper-compilation-targets": "^7.16.7",
        "@babel/helper-function-name": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-literals": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz",
      "integrity": "sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-member-expression-literals": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz",
      "integrity": "sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-modules-amd": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz",
      "integrity": "sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==",
      "dev": true,
      "dependencies": {
        "@babel/helper-module-transforms": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7",
        "babel-plugin-dynamic-import-node": "^2.3.3"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-modules-commonjs": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz",
      "integrity": "sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==",
      "dev": true,
      "dependencies": {
        "@babel/helper-module-transforms": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/helper-simple-access": "^7.16.7",
        "babel-plugin-dynamic-import-node": "^2.3.3"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-modules-systemjs": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz",
      "integrity": "sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-hoist-variables": "^7.16.7",
        "@babel/helper-module-transforms": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/helper-validator-identifier": "^7.16.7",
        "babel-plugin-dynamic-import-node": "^2.3.3"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-modules-umd": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz",
      "integrity": "sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==",
      "dev": true,
      "dependencies": {
        "@babel/helper-module-transforms": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz",
      "integrity": "sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-create-regexp-features-plugin": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0"
      }
    },
    "node_modules/@babel/plugin-transform-new-target": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz",
      "integrity": "sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-object-super": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz",
      "integrity": "sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/helper-replace-supers": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-parameters": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz",
      "integrity": "sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-property-literals": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz",
      "integrity": "sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-regenerator": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz",
      "integrity": "sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==",
      "dev": true,
      "dependencies": {
        "regenerator-transform": "^0.14.2"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-reserved-words": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz",
      "integrity": "sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-runtime": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.5.tgz",
      "integrity": "sha512-fPMBhh1AV8ZyneiCIA+wYYUH1arzlXR1UMcApjvchDhfKxhy2r2lReJv8uHEyihi4IFIGlr1Pdx7S5fkESDQsg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-module-imports": "^7.14.5",
        "@babel/helper-plugin-utils": "^7.14.5",
        "babel-plugin-polyfill-corejs2": "^0.2.2",
        "babel-plugin-polyfill-corejs3": "^0.2.2",
        "babel-plugin-polyfill-regenerator": "^0.2.2",
        "semver": "^6.3.0"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-runtime/node_modules/semver": {
      "version": "6.3.0",
      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
      "dev": true,
      "bin": {
        "semver": "bin/semver.js"
      }
    },
    "node_modules/@babel/plugin-transform-shorthand-properties": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz",
      "integrity": "sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-spread": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz",
      "integrity": "sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-sticky-regex": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz",
      "integrity": "sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-template-literals": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz",
      "integrity": "sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-typeof-symbol": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz",
      "integrity": "sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-unicode-escapes": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz",
      "integrity": "sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q==",
      "dev": true,
      "dependencies": {
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/plugin-transform-unicode-regex": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz",
      "integrity": "sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q==",
      "dev": true,
      "dependencies": {
        "@babel/helper-create-regexp-features-plugin": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/preset-env": {
      "version": "7.14.7",
      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.7.tgz",
      "integrity": "sha512-itOGqCKLsSUl0Y+1nSfhbuuOlTs0MJk2Iv7iSH+XT/mR8U1zRLO7NjWlYXB47yhK4J/7j+HYty/EhFZDYKa/VA==",
      "dev": true,
      "dependencies": {
        "@babel/compat-data": "^7.14.7",
        "@babel/helper-compilation-targets": "^7.14.5",
        "@babel/helper-plugin-utils": "^7.14.5",
        "@babel/helper-validator-option": "^7.14.5",
        "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.14.5",
        "@babel/plugin-proposal-async-generator-functions": "^7.14.7",
        "@babel/plugin-proposal-class-properties": "^7.14.5",
        "@babel/plugin-proposal-class-static-block": "^7.14.5",
        "@babel/plugin-proposal-dynamic-import": "^7.14.5",
        "@babel/plugin-proposal-export-namespace-from": "^7.14.5",
        "@babel/plugin-proposal-json-strings": "^7.14.5",
        "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5",
        "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5",
        "@babel/plugin-proposal-numeric-separator": "^7.14.5",
        "@babel/plugin-proposal-object-rest-spread": "^7.14.7",
        "@babel/plugin-proposal-optional-catch-binding": "^7.14.5",
        "@babel/plugin-proposal-optional-chaining": "^7.14.5",
        "@babel/plugin-proposal-private-methods": "^7.14.5",
        "@babel/plugin-proposal-private-property-in-object": "^7.14.5",
        "@babel/plugin-proposal-unicode-property-regex": "^7.14.5",
        "@babel/plugin-syntax-async-generators": "^7.8.4",
        "@babel/plugin-syntax-class-properties": "^7.12.13",
        "@babel/plugin-syntax-class-static-block": "^7.14.5",
        "@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-private-property-in-object": "^7.14.5",
        "@babel/plugin-syntax-top-level-await": "^7.14.5",
        "@babel/plugin-transform-arrow-functions": "^7.14.5",
        "@babel/plugin-transform-async-to-generator": "^7.14.5",
        "@babel/plugin-transform-block-scoped-functions": "^7.14.5",
        "@babel/plugin-transform-block-scoping": "^7.14.5",
        "@babel/plugin-transform-classes": "^7.14.5",
        "@babel/plugin-transform-computed-properties": "^7.14.5",
        "@babel/plugin-transform-destructuring": "^7.14.7",
        "@babel/plugin-transform-dotall-regex": "^7.14.5",
        "@babel/plugin-transform-duplicate-keys": "^7.14.5",
        "@babel/plugin-transform-exponentiation-operator": "^7.14.5",
        "@babel/plugin-transform-for-of": "^7.14.5",
        "@babel/plugin-transform-function-name": "^7.14.5",
        "@babel/plugin-transform-literals": "^7.14.5",
        "@babel/plugin-transform-member-expression-literals": "^7.14.5",
        "@babel/plugin-transform-modules-amd": "^7.14.5",
        "@babel/plugin-transform-modules-commonjs": "^7.14.5",
        "@babel/plugin-transform-modules-systemjs": "^7.14.5",
        "@babel/plugin-transform-modules-umd": "^7.14.5",
        "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.7",
        "@babel/plugin-transform-new-target": "^7.14.5",
        "@babel/plugin-transform-object-super": "^7.14.5",
        "@babel/plugin-transform-parameters": "^7.14.5",
        "@babel/plugin-transform-property-literals": "^7.14.5",
        "@babel/plugin-transform-regenerator": "^7.14.5",
        "@babel/plugin-transform-reserved-words": "^7.14.5",
        "@babel/plugin-transform-shorthand-properties": "^7.14.5",
        "@babel/plugin-transform-spread": "^7.14.6",
        "@babel/plugin-transform-sticky-regex": "^7.14.5",
        "@babel/plugin-transform-template-literals": "^7.14.5",
        "@babel/plugin-transform-typeof-symbol": "^7.14.5",
        "@babel/plugin-transform-unicode-escapes": "^7.14.5",
        "@babel/plugin-transform-unicode-regex": "^7.14.5",
        "@babel/preset-modules": "^0.1.4",
        "@babel/types": "^7.14.5",
        "babel-plugin-polyfill-corejs2": "^0.2.2",
        "babel-plugin-polyfill-corejs3": "^0.2.2",
        "babel-plugin-polyfill-regenerator": "^0.2.2",
        "core-js-compat": "^3.15.0",
        "semver": "^6.3.0"
      },
      "engines": {
        "node": ">=6.9.0"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/preset-env/node_modules/semver": {
      "version": "6.3.0",
      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
      "dev": true,
      "bin": {
        "semver": "bin/semver.js"
      }
    },
    "node_modules/@babel/preset-modules": {
      "version": "0.1.5",
      "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz",
      "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==",
      "dev": true,
      "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"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/@babel/runtime": {
      "version": "7.14.6",
      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz",
      "integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==",
      "dev": true,
      "dependencies": {
        "regenerator-runtime": "^0.13.4"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/template": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
      "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
      "dev": true,
      "dependencies": {
        "@babel/code-frame": "^7.14.5",
        "@babel/parser": "^7.14.5",
        "@babel/types": "^7.14.5"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/traverse": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.8.tgz",
      "integrity": "sha512-xe+H7JlvKsDQwXRsBhSnq1/+9c+LlQcCK3Tn/l5sbx02HYns/cn7ibp9+RV1sIUqu7hKg91NWsgHurO9dowITQ==",
      "dev": true,
      "dependencies": {
        "@babel/code-frame": "^7.16.7",
        "@babel/generator": "^7.16.8",
        "@babel/helper-environment-visitor": "^7.16.7",
        "@babel/helper-function-name": "^7.16.7",
        "@babel/helper-hoist-variables": "^7.16.7",
        "@babel/helper-split-export-declaration": "^7.16.7",
        "@babel/parser": "^7.16.8",
        "@babel/types": "^7.16.8",
        "debug": "^4.1.0",
        "globals": "^11.1.0"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/traverse/node_modules/@babel/generator": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz",
      "integrity": "sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==",
      "dev": true,
      "dependencies": {
        "@babel/types": "^7.16.8",
        "jsesc": "^2.5.1",
        "source-map": "^0.5.0"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/traverse/node_modules/source-map": {
      "version": "0.5.7",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/@babel/types": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz",
      "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==",
      "dev": true,
      "dependencies": {
        "@babel/helper-validator-identifier": "^7.16.7",
        "to-fast-properties": "^2.0.0"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@csstools/convert-colors": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz",
      "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==",
      "dev": true,
      "engines": {
        "node": ">=4.0.0"
      }
    },
    "node_modules/@discoveryjs/json-ext": {
      "version": "0.5.3",
      "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz",
      "integrity": "sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==",
      "dev": true,
      "engines": {
        "node": ">=10.0.0"
      }
    },
    "node_modules/@istanbuljs/schema": {
      "version": "0.1.3",
      "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
      "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/@jsdevtools/coverage-istanbul-loader": {
      "version": "3.0.5",
      "resolved": "https://registry.npmjs.org/@jsdevtools/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.5.tgz",
      "integrity": "sha512-EUCPEkaRPvmHjWAAZkWMT7JDzpw7FKB00WTISaiXsbNOd5hCHg77XLA8sLYLFDo1zepYLo2w7GstN8YBqRXZfA==",
      "dev": true,
      "dependencies": {
        "convert-source-map": "^1.7.0",
        "istanbul-lib-instrument": "^4.0.3",
        "loader-utils": "^2.0.0",
        "merge-source-map": "^1.1.0",
        "schema-utils": "^2.7.0"
      }
    },
    "node_modules/@juggle/resize-observer": {
      "version": "3.3.1",
      "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.3.1.tgz",
      "integrity": "sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw=="
    },
    "node_modules/@ngtools/webpack": {
      "version": "12.1.4",
      "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-12.1.4.tgz",
      "integrity": "sha512-hXc8dTnRfDB7o1Pd7a07aw0rjGmVLXU28+cTHQJliosgD3obcjfZ4QPA0k97vlQMtqVJawuShRfyiUKrpsJf8Q==",
      "dev": true,
      "dependencies": {
        "enhanced-resolve": "5.8.2"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0",
        "npm": "^6.11.0 || ^7.5.6",
        "yarn": ">= 1.13.0"
      },
      "peerDependencies": {
        "@angular/compiler-cli": "^12.0.0 || ^12.1.0-next",
        "typescript": "~4.2.3 || ~4.3.2",
        "webpack": "^5.30.0"
      }
    },
    "node_modules/@nodelib/fs.scandir": {
      "version": "2.1.5",
      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
      "dev": true,
      "dependencies": {
        "@nodelib/fs.stat": "2.0.5",
        "run-parallel": "^1.1.9"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/@nodelib/fs.stat": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
      "dev": true,
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/@nodelib/fs.walk": {
      "version": "1.2.8",
      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
      "dev": true,
      "dependencies": {
        "@nodelib/fs.scandir": "2.1.5",
        "fastq": "^1.6.0"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/@npmcli/git": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.1.0.tgz",
      "integrity": "sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw==",
      "dev": true,
      "dependencies": {
        "@npmcli/promise-spawn": "^1.3.2",
        "lru-cache": "^6.0.0",
        "mkdirp": "^1.0.4",
        "npm-pick-manifest": "^6.1.1",
        "promise-inflight": "^1.0.1",
        "promise-retry": "^2.0.1",
        "semver": "^7.3.5",
        "which": "^2.0.2"
      }
    },
    "node_modules/@npmcli/git/node_modules/which": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
      "dev": true,
      "dependencies": {
        "isexe": "^2.0.0"
      },
      "bin": {
        "node-which": "bin/node-which"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/@npmcli/installed-package-contents": {
      "version": "1.0.7",
      "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz",
      "integrity": "sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==",
      "dev": true,
      "dependencies": {
        "npm-bundled": "^1.1.1",
        "npm-normalize-package-bin": "^1.0.1"
      },
      "bin": {
        "installed-package-contents": "index.js"
      },
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/@npmcli/move-file": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
      "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
      "dev": true,
      "dependencies": {
        "mkdirp": "^1.0.4",
        "rimraf": "^3.0.2"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/@npmcli/node-gyp": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz",
      "integrity": "sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA==",
      "dev": true
    },
    "node_modules/@npmcli/promise-spawn": {
      "version": "1.3.2",
      "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz",
      "integrity": "sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg==",
      "dev": true,
      "dependencies": {
        "infer-owner": "^1.0.4"
      }
    },
    "node_modules/@npmcli/run-script": {
      "version": "1.8.6",
      "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.8.6.tgz",
      "integrity": "sha512-e42bVZnC6VluBZBAFEr3YrdqSspG3bgilyg4nSLBJ7TRGNCzxHa92XAHxQBLYg0BmgwO4b2mf3h/l5EkEWRn3g==",
      "dev": true,
      "dependencies": {
        "@npmcli/node-gyp": "^1.0.2",
        "@npmcli/promise-spawn": "^1.3.2",
        "node-gyp": "^7.1.0",
        "read-package-json-fast": "^2.0.1"
      }
    },
    "node_modules/@schematics/angular": {
      "version": "12.1.4",
      "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-12.1.4.tgz",
      "integrity": "sha512-xGqgGI6GWk4EFdKis8FmSESxoLgjnLQbaRE1t1KZCkSKJzqkOj0R9wiDrtZfcrbPxIkLL+3fAk2ThwwPznT6yw==",
      "dev": true,
      "dependencies": {
        "@angular-devkit/core": "12.1.4",
        "@angular-devkit/schematics": "12.1.4",
        "jsonc-parser": "3.0.0"
      },
      "engines": {
        "node": "^12.14.1 || >=14.0.0",
        "npm": "^6.11.0 || ^7.5.6",
        "yarn": ">= 1.13.0"
      }
    },
    "node_modules/@socket.io/base64-arraybuffer": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
      "integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==",
      "dev": true,
      "engines": {
        "node": ">= 0.6.0"
      }
    },
    "node_modules/@tootallnate/once": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
      "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
      "dev": true,
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/@trysound/sax": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
      "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
      "dev": true,
      "engines": {
        "node": ">=10.13.0"
      }
    },
    "node_modules/@types/component-emitter": {
      "version": "1.2.11",
      "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz",
      "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==",
      "dev": true
    },
    "node_modules/@types/cookie": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
      "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==",
      "dev": true
    },
    "node_modules/@types/cors": {
      "version": "2.8.12",
      "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
      "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==",
      "dev": true
    },
    "node_modules/@types/eslint": {
      "version": "8.2.2",
      "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.2.tgz",
      "integrity": "sha512-nQxgB8/Sg+QKhnV8e0WzPpxjIGT3tuJDDzybkDi8ItE/IgTlHo07U0shaIjzhcvQxlq9SDRE42lsJ23uvEgJ2A==",
      "dev": true,
      "dependencies": {
        "@types/estree": "*",
        "@types/json-schema": "*"
      }
    },
    "node_modules/@types/eslint-scope": {
      "version": "3.7.3",
      "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz",
      "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==",
      "dev": true,
      "dependencies": {
        "@types/eslint": "*",
        "@types/estree": "*"
      }
    },
    "node_modules/@types/estree": {
      "version": "0.0.50",
      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
      "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==",
      "dev": true
    },
    "node_modules/@types/glob": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
      "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
      "dev": true,
      "dependencies": {
        "@types/minimatch": "*",
        "@types/node": "*"
      }
    },
    "node_modules/@types/jasmine": {
      "version": "3.6.11",
      "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.6.11.tgz",
      "integrity": "sha512-S6pvzQDvMZHrkBz2Mcn/8Du7cpr76PlRJBAoHnSDNbulULsH5dp0Gns+WRyNX5LHejz/ljxK4/vIHK/caHt6SQ==",
      "dev": true
    },
    "node_modules/@types/json-schema": {
      "version": "7.0.9",
      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
      "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
      "dev": true
    },
    "node_modules/@types/minimatch": {
      "version": "3.0.5",
      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
      "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
      "dev": true
    },
    "node_modules/@types/node": {
      "version": "12.20.42",
      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.42.tgz",
      "integrity": "sha512-aI3/oo5DzyiI5R/xAhxxRzfZlWlsbbqdgxfTPkqu/Zt+23GXiJvMCyPJT4+xKSXOnLqoL8jJYMLTwvK2M3a5hw==",
      "dev": true
    },
    "node_modules/@types/parse-json": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
      "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
      "dev": true
    },
    "node_modules/@types/source-list-map": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
      "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==",
      "dev": true
    },
    "node_modules/@types/webpack-sources": {
      "version": "0.1.9",
      "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.9.tgz",
      "integrity": "sha512-bvzMnzqoK16PQIC8AYHNdW45eREJQMd6WG/msQWX5V2+vZmODCOPb4TJcbgRljTZZTwTM4wUMcsI8FftNA7new==",
      "dev": true,
      "dependencies": {
        "@types/node": "*",
        "@types/source-list-map": "*",
        "source-map": "^0.6.1"
      }
    },
    "node_modules/@types/webpack-sources/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/@webassemblyjs/ast": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
      "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
      "dev": true,
      "dependencies": {
        "@webassemblyjs/helper-numbers": "1.11.1",
        "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
      }
    },
    "node_modules/@webassemblyjs/floating-point-hex-parser": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
      "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
      "dev": true
    },
    "node_modules/@webassemblyjs/helper-api-error": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
      "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
      "dev": true
    },
    "node_modules/@webassemblyjs/helper-buffer": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
      "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
      "dev": true
    },
    "node_modules/@webassemblyjs/helper-numbers": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
      "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
      "dev": true,
      "dependencies": {
        "@webassemblyjs/floating-point-hex-parser": "1.11.1",
        "@webassemblyjs/helper-api-error": "1.11.1",
        "@xtuc/long": "4.2.2"
      }
    },
    "node_modules/@webassemblyjs/helper-wasm-bytecode": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
      "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
      "dev": true
    },
    "node_modules/@webassemblyjs/helper-wasm-section": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
      "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
      "dev": true,
      "dependencies": {
        "@webassemblyjs/ast": "1.11.1",
        "@webassemblyjs/helper-buffer": "1.11.1",
        "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
        "@webassemblyjs/wasm-gen": "1.11.1"
      }
    },
    "node_modules/@webassemblyjs/ieee754": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
      "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
      "dev": true,
      "dependencies": {
        "@xtuc/ieee754": "^1.2.0"
      }
    },
    "node_modules/@webassemblyjs/leb128": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
      "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
      "dev": true,
      "dependencies": {
        "@xtuc/long": "4.2.2"
      }
    },
    "node_modules/@webassemblyjs/utf8": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
      "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
      "dev": true
    },
    "node_modules/@webassemblyjs/wasm-edit": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
      "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
      "dev": true,
      "dependencies": {
        "@webassemblyjs/ast": "1.11.1",
        "@webassemblyjs/helper-buffer": "1.11.1",
        "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
        "@webassemblyjs/helper-wasm-section": "1.11.1",
        "@webassemblyjs/wasm-gen": "1.11.1",
        "@webassemblyjs/wasm-opt": "1.11.1",
        "@webassemblyjs/wasm-parser": "1.11.1",
        "@webassemblyjs/wast-printer": "1.11.1"
      }
    },
    "node_modules/@webassemblyjs/wasm-gen": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
      "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
      "dev": true,
      "dependencies": {
        "@webassemblyjs/ast": "1.11.1",
        "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
        "@webassemblyjs/ieee754": "1.11.1",
        "@webassemblyjs/leb128": "1.11.1",
        "@webassemblyjs/utf8": "1.11.1"
      }
    },
    "node_modules/@webassemblyjs/wasm-opt": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
      "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
      "dev": true,
      "dependencies": {
        "@webassemblyjs/ast": "1.11.1",
        "@webassemblyjs/helper-buffer": "1.11.1",
        "@webassemblyjs/wasm-gen": "1.11.1",
        "@webassemblyjs/wasm-parser": "1.11.1"
      }
    },
    "node_modules/@webassemblyjs/wasm-parser": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
      "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
      "dev": true,
      "dependencies": {
        "@webassemblyjs/ast": "1.11.1",
        "@webassemblyjs/helper-api-error": "1.11.1",
        "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
        "@webassemblyjs/ieee754": "1.11.1",
        "@webassemblyjs/leb128": "1.11.1",
        "@webassemblyjs/utf8": "1.11.1"
      }
    },
    "node_modules/@webassemblyjs/wast-printer": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
      "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
      "dev": true,
      "dependencies": {
        "@webassemblyjs/ast": "1.11.1",
        "@xtuc/long": "4.2.2"
      }
    },
    "node_modules/@xtuc/ieee754": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
      "dev": true
    },
    "node_modules/@xtuc/long": {
      "version": "4.2.2",
      "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
      "dev": true
    },
    "node_modules/@yarnpkg/lockfile": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
      "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
      "dev": true
    },
    "node_modules/abab": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
      "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==",
      "dev": true
    },
    "node_modules/abbrev": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
      "dev": true
    },
    "node_modules/accepts": {
      "version": "1.3.7",
      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
      "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
      "dev": true,
      "dependencies": {
        "mime-types": "~2.1.24",
        "negotiator": "0.6.2"
      },
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/acorn": {
      "version": "8.7.0",
      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
      "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
      "dev": true,
      "bin": {
        "acorn": "bin/acorn"
      },
      "engines": {
        "node": ">=0.4.0"
      }
    },
    "node_modules/adjust-sourcemap-loader": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz",
      "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==",
      "dev": true,
      "dependencies": {
        "loader-utils": "^2.0.0",
        "regex-parser": "^2.2.11"
      },
      "engines": {
        "node": ">=8.9"
      }
    },
    "node_modules/agent-base": {
      "version": "6.0.2",
      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
      "dev": true,
      "dependencies": {
        "debug": "4"
      },
      "engines": {
        "node": ">= 6.0.0"
      }
    },
    "node_modules/agentkeepalive": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.0.tgz",
      "integrity": "sha512-0PhAp58jZNw13UJv7NVdTGb0ZcghHUb3DrZ046JiiJY/BOaTTpbwdHq2VObPCBV8M2GPh7sgrJ3AQ8Ey468LJw==",
      "dev": true,
      "dependencies": {
        "debug": "^4.1.0",
        "depd": "^1.1.2",
        "humanize-ms": "^1.2.1"
      },
      "engines": {
        "node": ">= 8.0.0"
      }
    },
    "node_modules/aggregate-error": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
      "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
      "dev": true,
      "dependencies": {
        "clean-stack": "^2.0.0",
        "indent-string": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/ajv": {
      "version": "8.6.0",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz",
      "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==",
      "dev": true,
      "dependencies": {
        "fast-deep-equal": "^3.1.1",
        "json-schema-traverse": "^1.0.0",
        "require-from-string": "^2.0.2",
        "uri-js": "^4.2.2"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/ajv-errors": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
      "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
      "dev": true,
      "peerDependencies": {
        "ajv": ">=5.0.0"
      }
    },
    "node_modules/ajv-formats": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz",
      "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==",
      "dev": true,
      "dependencies": {
        "ajv": "^8.0.0"
      },
      "peerDependencies": {
        "ajv": "^8.0.0"
      },
      "peerDependenciesMeta": {
        "ajv": {
          "optional": true
        }
      }
    },
    "node_modules/alphanum-sort": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
      "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
      "dev": true
    },
    "node_modules/ansi-colors": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
      "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/ansi-escapes": {
      "version": "4.3.2",
      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
      "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
      "dev": true,
      "dependencies": {
        "type-fest": "^0.21.3"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/ansi-html": {
      "version": "0.0.7",
      "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
      "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
      "dev": true,
      "engines": [
        "node >= 0.8.0"
      ],
      "bin": {
        "ansi-html": "bin/ansi-html"
      }
    },
    "node_modules/ansi-regex": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/ansi-styles": {
      "version": "3.2.1",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
      "dev": true,
      "dependencies": {
        "color-convert": "^1.9.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/anymatch": {
      "version": "3.1.2",
      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
      "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
      "dev": true,
      "dependencies": {
        "normalize-path": "^3.0.0",
        "picomatch": "^2.0.4"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/aproba": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
      "dev": true
    },
    "node_modules/are-we-there-yet": {
      "version": "1.1.7",
      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz",
      "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==",
      "dev": true,
      "dependencies": {
        "delegates": "^1.0.0",
        "readable-stream": "^2.0.6"
      }
    },
    "node_modules/are-we-there-yet/node_modules/readable-stream": {
      "version": "2.3.7",
      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
      "dev": true,
      "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"
      }
    },
    "node_modules/are-we-there-yet/node_modules/string_decoder": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
      "dev": true,
      "dependencies": {
        "safe-buffer": "~5.1.0"
      }
    },
    "node_modules/arr-diff": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/arr-flatten": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/arr-union": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/array-flatten": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
      "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
      "dev": true
    },
    "node_modules/array-union": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/array-uniq": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/array-unique": {
      "version": "0.3.2",
      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/asn1": {
      "version": "0.2.6",
      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
      "dev": true,
      "dependencies": {
        "safer-buffer": "~2.1.0"
      }
    },
    "node_modules/assert-plus": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
      "dev": true,
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/assign-symbols": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/async": {
      "version": "2.6.3",
      "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
      "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
      "dev": true,
      "dependencies": {
        "lodash": "^4.17.14"
      }
    },
    "node_modules/async-each": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
      "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
      "dev": true
    },
    "node_modules/async-limiter": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
      "dev": true
    },
    "node_modules/asynckit": {
      "version": "0.4.0",
      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
      "dev": true
    },
    "node_modules/atob": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
      "dev": true,
      "bin": {
        "atob": "bin/atob.js"
      },
      "engines": {
        "node": ">= 4.5.0"
      }
    },
    "node_modules/autoprefixer": {
      "version": "9.8.8",
      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz",
      "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==",
      "dev": true,
      "dependencies": {
        "browserslist": "^4.12.0",
        "caniuse-lite": "^1.0.30001109",
        "normalize-range": "^0.1.2",
        "num2fraction": "^1.2.2",
        "picocolors": "^0.2.1",
        "postcss": "^7.0.32",
        "postcss-value-parser": "^4.1.0"
      },
      "bin": {
        "autoprefixer": "bin/autoprefixer"
      },
      "funding": {
        "type": "tidelift",
        "url": "https://tidelift.com/funding/github/npm/autoprefixer"
      }
    },
    "node_modules/autoprefixer/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/autoprefixer/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/autoprefixer/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/aws-sign2": {
      "version": "0.7.0",
      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
      "dev": true,
      "engines": {
        "node": "*"
      }
    },
    "node_modules/aws4": {
      "version": "1.11.0",
      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
      "dev": true
    },
    "node_modules/babel-loader": {
      "version": "8.2.2",
      "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz",
      "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==",
      "dev": true,
      "dependencies": {
        "find-cache-dir": "^3.3.1",
        "loader-utils": "^1.4.0",
        "make-dir": "^3.1.0",
        "schema-utils": "^2.6.5"
      },
      "engines": {
        "node": ">= 8.9"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0",
        "webpack": ">=2"
      }
    },
    "node_modules/babel-loader/node_modules/json5": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
      "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
      "dev": true,
      "dependencies": {
        "minimist": "^1.2.0"
      },
      "bin": {
        "json5": "lib/cli.js"
      }
    },
    "node_modules/babel-loader/node_modules/loader-utils": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
      "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
      "dev": true,
      "dependencies": {
        "big.js": "^5.2.2",
        "emojis-list": "^3.0.0",
        "json5": "^1.0.1"
      },
      "engines": {
        "node": ">=4.0.0"
      }
    },
    "node_modules/babel-plugin-dynamic-import-node": {
      "version": "2.3.3",
      "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
      "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
      "dev": true,
      "dependencies": {
        "object.assign": "^4.1.0"
      }
    },
    "node_modules/babel-plugin-polyfill-corejs2": {
      "version": "0.2.3",
      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.3.tgz",
      "integrity": "sha512-NDZ0auNRzmAfE1oDDPW2JhzIMXUk+FFe2ICejmt5T4ocKgiQx3e0VCRx9NCAidcMtL2RUZaWtXnmjTCkx0tcbA==",
      "dev": true,
      "dependencies": {
        "@babel/compat-data": "^7.13.11",
        "@babel/helper-define-polyfill-provider": "^0.2.4",
        "semver": "^6.1.1"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
      "version": "6.3.0",
      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
      "dev": true,
      "bin": {
        "semver": "bin/semver.js"
      }
    },
    "node_modules/babel-plugin-polyfill-corejs3": {
      "version": "0.2.5",
      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.5.tgz",
      "integrity": "sha512-ninF5MQNwAX9Z7c9ED+H2pGt1mXdP4TqzlHKyPIYmJIYz0N+++uwdM7RnJukklhzJ54Q84vA4ZJkgs7lu5vqcw==",
      "dev": true,
      "dependencies": {
        "@babel/helper-define-polyfill-provider": "^0.2.2",
        "core-js-compat": "^3.16.2"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/babel-plugin-polyfill-regenerator": {
      "version": "0.2.3",
      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.3.tgz",
      "integrity": "sha512-JVE78oRZPKFIeUqFGrSORNzQnrDwZR16oiWeGM8ZyjBn2XAT5OjP+wXx5ESuo33nUsFUEJYjtklnsKbxW5L+7g==",
      "dev": true,
      "dependencies": {
        "@babel/helper-define-polyfill-provider": "^0.2.4"
      },
      "peerDependencies": {
        "@babel/core": "^7.0.0-0"
      }
    },
    "node_modules/balanced-match": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
      "dev": true
    },
    "node_modules/base": {
      "version": "0.11.2",
      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
      "dev": true,
      "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"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/base/node_modules/define-property": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
      "dev": true,
      "dependencies": {
        "is-descriptor": "^1.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/base64-js": {
      "version": "1.5.1",
      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
      "dev": true,
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ]
    },
    "node_modules/base64id": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
      "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
      "dev": true,
      "engines": {
        "node": "^4.5.0 || >= 5.9"
      }
    },
    "node_modules/batch": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
      "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
      "dev": true
    },
    "node_modules/bcrypt-pbkdf": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
      "dev": true,
      "dependencies": {
        "tweetnacl": "^0.14.3"
      }
    },
    "node_modules/big.js": {
      "version": "5.2.2",
      "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
      "dev": true,
      "engines": {
        "node": "*"
      }
    },
    "node_modules/binary-extensions": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/bindings": {
      "version": "1.5.0",
      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
      "dev": true,
      "optional": true,
      "dependencies": {
        "file-uri-to-path": "1.0.0"
      }
    },
    "node_modules/bl": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
      "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
      "dev": true,
      "dependencies": {
        "buffer": "^5.5.0",
        "inherits": "^2.0.4",
        "readable-stream": "^3.4.0"
      }
    },
    "node_modules/body-parser": {
      "version": "1.19.1",
      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz",
      "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==",
      "dev": true,
      "dependencies": {
        "bytes": "3.1.1",
        "content-type": "~1.0.4",
        "debug": "2.6.9",
        "depd": "~1.1.2",
        "http-errors": "1.8.1",
        "iconv-lite": "0.4.24",
        "on-finished": "~2.3.0",
        "qs": "6.9.6",
        "raw-body": "2.4.2",
        "type-is": "~1.6.18"
      },
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/body-parser/node_modules/debug": {
      "version": "2.6.9",
      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
      "dev": true,
      "dependencies": {
        "ms": "2.0.0"
      }
    },
    "node_modules/body-parser/node_modules/ms": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
      "dev": true
    },
    "node_modules/bonjour": {
      "version": "3.5.0",
      "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
      "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
      "dev": true,
      "dependencies": {
        "array-flatten": "^2.1.0",
        "deep-equal": "^1.0.1",
        "dns-equal": "^1.0.0",
        "dns-txt": "^2.0.2",
        "multicast-dns": "^6.0.1",
        "multicast-dns-service-types": "^1.1.0"
      }
    },
    "node_modules/boolbase": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
      "dev": true
    },
    "node_modules/brace-expansion": {
      "version": "1.1.11",
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
      "dev": true,
      "dependencies": {
        "balanced-match": "^1.0.0",
        "concat-map": "0.0.1"
      }
    },
    "node_modules/braces": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
      "dev": true,
      "dependencies": {
        "fill-range": "^7.0.1"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/browserslist": {
      "version": "4.19.1",
      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz",
      "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==",
      "dev": true,
      "dependencies": {
        "caniuse-lite": "^1.0.30001286",
        "electron-to-chromium": "^1.4.17",
        "escalade": "^3.1.1",
        "node-releases": "^2.0.1",
        "picocolors": "^1.0.0"
      },
      "bin": {
        "browserslist": "cli.js"
      },
      "engines": {
        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/browserslist"
      }
    },
    "node_modules/buffer": {
      "version": "5.7.1",
      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
      "dev": true,
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ],
      "dependencies": {
        "base64-js": "^1.3.1",
        "ieee754": "^1.1.13"
      }
    },
    "node_modules/buffer-from": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
      "dev": true
    },
    "node_modules/buffer-indexof": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
      "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
      "dev": true
    },
    "node_modules/builtins": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz",
      "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=",
      "dev": true
    },
    "node_modules/bytes": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz",
      "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==",
      "dev": true,
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/cacache": {
      "version": "15.2.0",
      "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz",
      "integrity": "sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==",
      "dev": true,
      "dependencies": {
        "@npmcli/move-file": "^1.0.1",
        "chownr": "^2.0.0",
        "fs-minipass": "^2.0.0",
        "glob": "^7.1.4",
        "infer-owner": "^1.0.4",
        "lru-cache": "^6.0.0",
        "minipass": "^3.1.1",
        "minipass-collect": "^1.0.2",
        "minipass-flush": "^1.0.5",
        "minipass-pipeline": "^1.2.2",
        "mkdirp": "^1.0.3",
        "p-map": "^4.0.0",
        "promise-inflight": "^1.0.1",
        "rimraf": "^3.0.2",
        "ssri": "^8.0.1",
        "tar": "^6.0.2",
        "unique-filename": "^1.1.1"
      },
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/cache-base": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
      "dev": true,
      "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"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/call-bind": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
      "dev": true,
      "dependencies": {
        "function-bind": "^1.1.1",
        "get-intrinsic": "^1.0.2"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/callsites": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/camelcase": {
      "version": "5.3.1",
      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/can-use-dom": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/can-use-dom/-/can-use-dom-0.1.0.tgz",
      "integrity": "sha1-IsxKNKCrxDlQ9CxkEQJKP2NmtFo="
    },
    "node_modules/caniuse-api": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
      "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
      "dev": true,
      "dependencies": {
        "browserslist": "^4.0.0",
        "caniuse-lite": "^1.0.0",
        "lodash.memoize": "^4.1.2",
        "lodash.uniq": "^4.5.0"
      }
    },
    "node_modules/caniuse-lite": {
      "version": "1.0.30001300",
      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001300.tgz",
      "integrity": "sha512-cVjiJHWGcNlJi8TZVKNMnvMid3Z3TTdDHmLDzlOdIiZq138Exvo0G+G0wTdVYolxKb4AYwC+38pxodiInVtJSA==",
      "dev": true,
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/browserslist"
      }
    },
    "node_modules/canonical-path": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz",
      "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==",
      "dev": true
    },
    "node_modules/caseless": {
      "version": "0.12.0",
      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
      "dev": true
    },
    "node_modules/chalk": {
      "version": "2.4.2",
      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
      "dev": true,
      "dependencies": {
        "ansi-styles": "^3.2.1",
        "escape-string-regexp": "^1.0.5",
        "supports-color": "^5.3.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/chardet": {
      "version": "0.7.0",
      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
      "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
      "dev": true
    },
    "node_modules/chokidar": {
      "version": "3.5.2",
      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
      "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
      "dev": true,
      "dependencies": {
        "anymatch": "~3.1.2",
        "braces": "~3.0.2",
        "glob-parent": "~5.1.2",
        "is-binary-path": "~2.1.0",
        "is-glob": "~4.0.1",
        "normalize-path": "~3.0.0",
        "readdirp": "~3.6.0"
      },
      "engines": {
        "node": ">= 8.10.0"
      },
      "optionalDependencies": {
        "fsevents": "~2.3.2"
      }
    },
    "node_modules/chownr": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
      "dev": true,
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/chrome-trace-event": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
      "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
      "dev": true,
      "engines": {
        "node": ">=6.0"
      }
    },
    "node_modules/circular-dependency-plugin": {
      "version": "5.2.2",
      "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz",
      "integrity": "sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ==",
      "dev": true,
      "engines": {
        "node": ">=6.0.0"
      },
      "peerDependencies": {
        "webpack": ">=4.0.1"
      }
    },
    "node_modules/class-utils": {
      "version": "0.3.6",
      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
      "dev": true,
      "dependencies": {
        "arr-union": "^3.1.0",
        "define-property": "^0.2.5",
        "isobject": "^3.0.0",
        "static-extend": "^0.1.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/class-utils/node_modules/define-property": {
      "version": "0.2.5",
      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
      "dev": true,
      "dependencies": {
        "is-descriptor": "^0.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/class-utils/node_modules/is-accessor-descriptor": {
      "version": "0.1.6",
      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/class-utils/node_modules/is-data-descriptor": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/class-utils/node_modules/is-descriptor": {
      "version": "0.1.6",
      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
      "dev": true,
      "dependencies": {
        "is-accessor-descriptor": "^0.1.6",
        "is-data-descriptor": "^0.1.4",
        "kind-of": "^5.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/class-utils/node_modules/kind-of": {
      "version": "5.1.0",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
      "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/clean-stack": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/cli-cursor": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
      "dev": true,
      "dependencies": {
        "restore-cursor": "^3.1.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/cli-spinners": {
      "version": "2.6.1",
      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz",
      "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==",
      "dev": true,
      "engines": {
        "node": ">=6"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/cli-width": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
      "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
      "dev": true,
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/cliui": {
      "version": "7.0.4",
      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
      "dev": true,
      "dependencies": {
        "string-width": "^4.2.0",
        "strip-ansi": "^6.0.0",
        "wrap-ansi": "^7.0.0"
      }
    },
    "node_modules/clone": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
      "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
      "dev": true,
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/clone-deep": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
      "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
      "dev": true,
      "dependencies": {
        "is-plain-object": "^2.0.4",
        "kind-of": "^6.0.2",
        "shallow-clone": "^3.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/code-point-at": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/collection-visit": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
      "dev": true,
      "dependencies": {
        "map-visit": "^1.0.0",
        "object-visit": "^1.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/color-convert": {
      "version": "1.9.3",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
      "dev": true,
      "dependencies": {
        "color-name": "1.1.3"
      }
    },
    "node_modules/color-name": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
      "dev": true
    },
    "node_modules/colord": {
      "version": "2.9.2",
      "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz",
      "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==",
      "dev": true
    },
    "node_modules/colorette": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz",
      "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==",
      "dev": true
    },
    "node_modules/colors": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
      "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
      "dev": true,
      "engines": {
        "node": ">=0.1.90"
      }
    },
    "node_modules/combined-stream": {
      "version": "1.0.8",
      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
      "dev": true,
      "dependencies": {
        "delayed-stream": "~1.0.0"
      },
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/commander": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
      "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
      "dev": true,
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/commondir": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
      "dev": true
    },
    "node_modules/component-emitter": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
      "dev": true
    },
    "node_modules/compressible": {
      "version": "2.0.18",
      "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
      "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
      "dev": true,
      "dependencies": {
        "mime-db": ">= 1.43.0 < 2"
      },
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/compression": {
      "version": "1.7.4",
      "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
      "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
      "dev": true,
      "dependencies": {
        "accepts": "~1.3.5",
        "bytes": "3.0.0",
        "compressible": "~2.0.16",
        "debug": "2.6.9",
        "on-headers": "~1.0.2",
        "safe-buffer": "5.1.2",
        "vary": "~1.1.2"
      },
      "engines": {
        "node": ">= 0.8.0"
      }
    },
    "node_modules/compression/node_modules/bytes": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
      "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
      "dev": true,
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/compression/node_modules/debug": {
      "version": "2.6.9",
      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
      "dev": true,
      "dependencies": {
        "ms": "2.0.0"
      }
    },
    "node_modules/compression/node_modules/ms": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
      "dev": true
    },
    "node_modules/concat-map": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
      "dev": true
    },
    "node_modules/connect": {
      "version": "3.7.0",
      "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
      "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
      "dev": true,
      "dependencies": {
        "debug": "2.6.9",
        "finalhandler": "1.1.2",
        "parseurl": "~1.3.3",
        "utils-merge": "1.0.1"
      },
      "engines": {
        "node": ">= 0.10.0"
      }
    },
    "node_modules/connect-history-api-fallback": {
      "version": "1.6.0",
      "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
      "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
      "dev": true,
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/connect/node_modules/debug": {
      "version": "2.6.9",
      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
      "dev": true,
      "dependencies": {
        "ms": "2.0.0"
      }
    },
    "node_modules/connect/node_modules/ms": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
      "dev": true
    },
    "node_modules/console-control-strings": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
      "dev": true
    },
    "node_modules/content-disposition": {
      "version": "0.5.4",
      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
      "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
      "dev": true,
      "dependencies": {
        "safe-buffer": "5.2.1"
      },
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/content-disposition/node_modules/safe-buffer": {
      "version": "5.2.1",
      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
      "dev": true,
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ]
    },
    "node_modules/content-type": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/convert-source-map": {
      "version": "1.8.0",
      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
      "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
      "dev": true,
      "dependencies": {
        "safe-buffer": "~5.1.1"
      }
    },
    "node_modules/cookie": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
      "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/cookie-signature": {
      "version": "1.0.6",
      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
      "dev": true
    },
    "node_modules/copy-anything": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.3.tgz",
      "integrity": "sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ==",
      "dev": true,
      "dependencies": {
        "is-what": "^3.12.0"
      }
    },
    "node_modules/copy-descriptor": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/copy-webpack-plugin": {
      "version": "9.0.0",
      "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-9.0.0.tgz",
      "integrity": "sha512-k8UB2jLIb1Jip2nZbCz83T/XfhfjX6mB1yLJNYKrpYi7FQimfOoFv/0//iT6HV1K8FwUB5yUbCcnpLebJXJTug==",
      "dev": true,
      "dependencies": {
        "fast-glob": "^3.2.5",
        "glob-parent": "^6.0.0",
        "globby": "^11.0.3",
        "normalize-path": "^3.0.0",
        "p-limit": "^3.1.0",
        "schema-utils": "^3.0.0",
        "serialize-javascript": "^5.0.1"
      },
      "engines": {
        "node": ">= 12.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "webpack": "^5.1.0"
      }
    },
    "node_modules/copy-webpack-plugin/node_modules/ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
      "dev": true,
      "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"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/copy-webpack-plugin/node_modules/ajv-keywords": {
      "version": "3.5.2",
      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
      "dev": true,
      "peerDependencies": {
        "ajv": "^6.9.1"
      }
    },
    "node_modules/copy-webpack-plugin/node_modules/glob-parent": {
      "version": "6.0.2",
      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
      "dev": true,
      "dependencies": {
        "is-glob": "^4.0.3"
      },
      "engines": {
        "node": ">=10.13.0"
      }
    },
    "node_modules/copy-webpack-plugin/node_modules/json-schema-traverse": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
      "dev": true
    },
    "node_modules/copy-webpack-plugin/node_modules/schema-utils": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
      "dev": true,
      "dependencies": {
        "@types/json-schema": "^7.0.8",
        "ajv": "^6.12.5",
        "ajv-keywords": "^3.5.2"
      },
      "engines": {
        "node": ">= 10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      }
    },
    "node_modules/core-js": {
      "version": "3.15.1",
      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.1.tgz",
      "integrity": "sha512-h8VbZYnc9pDzueiS2610IULDkpFFPunHwIpl8yRwFahAEEdSpHlTy3h3z3rKq5h11CaUdBEeRViu9AYvbxiMeg==",
      "hasInstallScript": true,
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/core-js"
      }
    },
    "node_modules/core-js-compat": {
      "version": "3.20.3",
      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.3.tgz",
      "integrity": "sha512-c8M5h0IkNZ+I92QhIpuSijOxGAcj3lgpsWdkCqmUTZNwidujF4r3pi6x1DCN+Vcs5qTS2XWWMfWSuCqyupX8gw==",
      "dev": true,
      "dependencies": {
        "browserslist": "^4.19.1",
        "semver": "7.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/core-js"
      }
    },
    "node_modules/core-js-compat/node_modules/semver": {
      "version": "7.0.0",
      "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
      "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
      "dev": true,
      "bin": {
        "semver": "bin/semver.js"
      }
    },
    "node_modules/core-util-is": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
      "dev": true
    },
    "node_modules/cors": {
      "version": "2.8.5",
      "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
      "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
      "dev": true,
      "dependencies": {
        "object-assign": "^4",
        "vary": "^1"
      },
      "engines": {
        "node": ">= 0.10"
      }
    },
    "node_modules/cosmiconfig": {
      "version": "7.0.1",
      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz",
      "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==",
      "dev": true,
      "dependencies": {
        "@types/parse-json": "^4.0.0",
        "import-fresh": "^3.2.1",
        "parse-json": "^5.0.0",
        "path-type": "^4.0.0",
        "yaml": "^1.10.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/critters": {
      "version": "0.0.10",
      "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.10.tgz",
      "integrity": "sha512-p5VKhP1803+f+0Jq5P03w1SbiHtpAKm+1EpJHkiPxQPq0Vu9QLZHviJ02GRrWi0dlcJqrmzMWInbwp4d22RsGw==",
      "dev": true,
      "dependencies": {
        "chalk": "^4.1.0",
        "css": "^3.0.0",
        "parse5": "^6.0.1",
        "parse5-htmlparser2-tree-adapter": "^6.0.1",
        "pretty-bytes": "^5.3.0"
      }
    },
    "node_modules/critters/node_modules/ansi-styles": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
      "dev": true,
      "dependencies": {
        "color-convert": "^2.0.1"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
      }
    },
    "node_modules/critters/node_modules/chalk": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
      "dev": true,
      "dependencies": {
        "ansi-styles": "^4.1.0",
        "supports-color": "^7.1.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/chalk/chalk?sponsor=1"
      }
    },
    "node_modules/critters/node_modules/color-convert": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
      "dev": true,
      "dependencies": {
        "color-name": "~1.1.4"
      },
      "engines": {
        "node": ">=7.0.0"
      }
    },
    "node_modules/critters/node_modules/color-name": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
      "dev": true
    },
    "node_modules/critters/node_modules/has-flag": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/critters/node_modules/parse5": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
      "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
      "dev": true
    },
    "node_modules/critters/node_modules/supports-color": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
      "dev": true,
      "dependencies": {
        "has-flag": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/cross-spawn": {
      "version": "6.0.5",
      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
      "dev": true,
      "dependencies": {
        "nice-try": "^1.0.4",
        "path-key": "^2.0.1",
        "semver": "^5.5.0",
        "shebang-command": "^1.2.0",
        "which": "^1.2.9"
      },
      "engines": {
        "node": ">=4.8"
      }
    },
    "node_modules/cross-spawn/node_modules/semver": {
      "version": "5.7.1",
      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
      "dev": true,
      "bin": {
        "semver": "bin/semver"
      }
    },
    "node_modules/css": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz",
      "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==",
      "dev": true,
      "dependencies": {
        "inherits": "^2.0.4",
        "source-map": "^0.6.1",
        "source-map-resolve": "^0.6.0"
      }
    },
    "node_modules/css-blank-pseudo": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz",
      "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.5"
      },
      "bin": {
        "css-blank-pseudo": "cli.js"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/css-blank-pseudo/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/css-blank-pseudo/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/css-blank-pseudo/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/css-declaration-sorter": {
      "version": "6.1.4",
      "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.1.4.tgz",
      "integrity": "sha512-lpfkqS0fctcmZotJGhnxkIyJWvBXgpyi2wsFd4J8VB7wzyrT6Ch/3Q+FMNJpjK4gu1+GN5khOnpU2ZVKrLbhCw==",
      "dev": true,
      "dependencies": {
        "timsort": "^0.3.0"
      },
      "engines": {
        "node": ">= 10"
      },
      "peerDependencies": {
        "postcss": "^8.0.9"
      }
    },
    "node_modules/css-has-pseudo": {
      "version": "0.10.0",
      "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz",
      "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.6",
        "postcss-selector-parser": "^5.0.0-rc.4"
      },
      "bin": {
        "css-has-pseudo": "cli.js"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/css-has-pseudo/node_modules/cssesc": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
      "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
      "dev": true,
      "bin": {
        "cssesc": "bin/cssesc"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/css-has-pseudo/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/css-has-pseudo/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
      "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
      "dev": true,
      "dependencies": {
        "cssesc": "^2.0.0",
        "indexes-of": "^1.0.1",
        "uniq": "^1.0.1"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/css-has-pseudo/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/css-loader": {
      "version": "5.2.6",
      "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.6.tgz",
      "integrity": "sha512-0wyN5vXMQZu6BvjbrPdUJvkCzGEO24HC7IS7nW4llc6BBFC+zwR9CKtYGv63Puzsg10L/o12inMY5/2ByzfD6w==",
      "dev": true,
      "dependencies": {
        "icss-utils": "^5.1.0",
        "loader-utils": "^2.0.0",
        "postcss": "^8.2.15",
        "postcss-modules-extract-imports": "^3.0.0",
        "postcss-modules-local-by-default": "^4.0.0",
        "postcss-modules-scope": "^3.0.0",
        "postcss-modules-values": "^4.0.0",
        "postcss-value-parser": "^4.1.0",
        "schema-utils": "^3.0.0",
        "semver": "^7.3.5"
      },
      "engines": {
        "node": ">= 10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "webpack": "^4.27.0 || ^5.0.0"
      }
    },
    "node_modules/css-loader/node_modules/ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
      "dev": true,
      "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"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/css-loader/node_modules/ajv-keywords": {
      "version": "3.5.2",
      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
      "dev": true,
      "peerDependencies": {
        "ajv": "^6.9.1"
      }
    },
    "node_modules/css-loader/node_modules/json-schema-traverse": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
      "dev": true
    },
    "node_modules/css-loader/node_modules/schema-utils": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
      "dev": true,
      "dependencies": {
        "@types/json-schema": "^7.0.8",
        "ajv": "^6.12.5",
        "ajv-keywords": "^3.5.2"
      },
      "engines": {
        "node": ">= 10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      }
    },
    "node_modules/css-minimizer-webpack-plugin": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.0.1.tgz",
      "integrity": "sha512-RGFIv6iZWUPO2T1vE5+5pNCSs2H2xtHYRdfZPiiNH8Of6QOn9BeFnZSoHiQMkmsxOO/JkPe4BpKfs7slFIWcTA==",
      "dev": true,
      "dependencies": {
        "cssnano": "^5.0.0",
        "jest-worker": "^27.0.2",
        "p-limit": "^3.0.2",
        "postcss": "^8.2.9",
        "schema-utils": "^3.0.0",
        "serialize-javascript": "^5.0.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">= 12.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "webpack": "^5.0.0"
      },
      "peerDependenciesMeta": {
        "clean-css": {
          "optional": true
        },
        "csso": {
          "optional": true
        }
      }
    },
    "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
      "dev": true,
      "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"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": {
      "version": "3.5.2",
      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
      "dev": true,
      "peerDependencies": {
        "ajv": "^6.9.1"
      }
    },
    "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
      "dev": true
    },
    "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
      "dev": true,
      "dependencies": {
        "@types/json-schema": "^7.0.8",
        "ajv": "^6.12.5",
        "ajv-keywords": "^3.5.2"
      },
      "engines": {
        "node": ">= 10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      }
    },
    "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/css-parse": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz",
      "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=",
      "dev": true,
      "dependencies": {
        "css": "^2.0.0"
      }
    },
    "node_modules/css-parse/node_modules/css": {
      "version": "2.2.4",
      "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
      "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
      "dev": true,
      "dependencies": {
        "inherits": "^2.0.3",
        "source-map": "^0.6.1",
        "source-map-resolve": "^0.5.2",
        "urix": "^0.1.0"
      }
    },
    "node_modules/css-parse/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/css-parse/node_modules/source-map-resolve": {
      "version": "0.5.3",
      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
      "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
      "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
      "dev": true,
      "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"
      }
    },
    "node_modules/css-prefers-color-scheme": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz",
      "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.5"
      },
      "bin": {
        "css-prefers-color-scheme": "cli.js"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/css-prefers-color-scheme/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/css-prefers-color-scheme/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/css-prefers-color-scheme/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/css-select": {
      "version": "4.2.1",
      "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz",
      "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==",
      "dev": true,
      "dependencies": {
        "boolbase": "^1.0.0",
        "css-what": "^5.1.0",
        "domhandler": "^4.3.0",
        "domutils": "^2.8.0",
        "nth-check": "^2.0.1"
      },
      "funding": {
        "url": "https://github.com/sponsors/fb55"
      }
    },
    "node_modules/css-tree": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
      "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
      "dev": true,
      "dependencies": {
        "mdn-data": "2.0.14",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=8.0.0"
      }
    },
    "node_modules/css-tree/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/css-what": {
      "version": "5.1.0",
      "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz",
      "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==",
      "dev": true,
      "engines": {
        "node": ">= 6"
      },
      "funding": {
        "url": "https://github.com/sponsors/fb55"
      }
    },
    "node_modules/css/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/cssdb": {
      "version": "4.4.0",
      "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz",
      "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==",
      "dev": true
    },
    "node_modules/cssesc": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
      "dev": true,
      "bin": {
        "cssesc": "bin/cssesc"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/cssnano": {
      "version": "5.0.15",
      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.15.tgz",
      "integrity": "sha512-ppZsS7oPpi2sfiyV5+i+NbB/3GtQ+ab2Vs1azrZaXWujUSN4o+WdTxlCZIMcT9yLW3VO/5yX3vpyDaQ1nIn8CQ==",
      "dev": true,
      "dependencies": {
        "cssnano-preset-default": "^5.1.10",
        "lilconfig": "^2.0.3",
        "yaml": "^1.10.2"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/cssnano"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/cssnano-preset-default": {
      "version": "5.1.10",
      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.10.tgz",
      "integrity": "sha512-BcpSzUVygHMOnp9uG5rfPzTOCb0GAHQkqtUQx8j1oMNF9A1Q8hziOOhiM4bdICpmrBIU85BE64RD5XGYsVQZNA==",
      "dev": true,
      "dependencies": {
        "css-declaration-sorter": "^6.0.3",
        "cssnano-utils": "^3.0.0",
        "postcss-calc": "^8.2.0",
        "postcss-colormin": "^5.2.3",
        "postcss-convert-values": "^5.0.2",
        "postcss-discard-comments": "^5.0.1",
        "postcss-discard-duplicates": "^5.0.1",
        "postcss-discard-empty": "^5.0.1",
        "postcss-discard-overridden": "^5.0.2",
        "postcss-merge-longhand": "^5.0.4",
        "postcss-merge-rules": "^5.0.4",
        "postcss-minify-font-values": "^5.0.2",
        "postcss-minify-gradients": "^5.0.4",
        "postcss-minify-params": "^5.0.3",
        "postcss-minify-selectors": "^5.1.1",
        "postcss-normalize-charset": "^5.0.1",
        "postcss-normalize-display-values": "^5.0.2",
        "postcss-normalize-positions": "^5.0.2",
        "postcss-normalize-repeat-style": "^5.0.2",
        "postcss-normalize-string": "^5.0.2",
        "postcss-normalize-timing-functions": "^5.0.2",
        "postcss-normalize-unicode": "^5.0.2",
        "postcss-normalize-url": "^5.0.4",
        "postcss-normalize-whitespace": "^5.0.2",
        "postcss-ordered-values": "^5.0.3",
        "postcss-reduce-initial": "^5.0.2",
        "postcss-reduce-transforms": "^5.0.2",
        "postcss-svgo": "^5.0.3",
        "postcss-unique-selectors": "^5.0.2"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/cssnano-utils": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.0.0.tgz",
      "integrity": "sha512-Pzs7/BZ6OgT+tXXuF12DKR8SmSbzUeVYCtMBbS8lI0uAm3mrYmkyqCXXPsQESI6kmLfEVBppbdVY/el3hg3nAA==",
      "dev": true,
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/csso": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz",
      "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==",
      "dev": true,
      "dependencies": {
        "css-tree": "^1.1.2"
      },
      "engines": {
        "node": ">=8.0.0"
      }
    },
    "node_modules/custom-event": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
      "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=",
      "dev": true
    },
    "node_modules/dashdash": {
      "version": "1.14.1",
      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
      "dev": true,
      "dependencies": {
        "assert-plus": "^1.0.0"
      },
      "engines": {
        "node": ">=0.10"
      }
    },
    "node_modules/date-format": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz",
      "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==",
      "dev": true,
      "engines": {
        "node": ">=4.0"
      }
    },
    "node_modules/debug": {
      "version": "4.3.1",
      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
      "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
      "dev": true,
      "dependencies": {
        "ms": "2.1.2"
      },
      "engines": {
        "node": ">=6.0"
      },
      "peerDependenciesMeta": {
        "supports-color": {
          "optional": true
        }
      }
    },
    "node_modules/decamelize": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/decode-uri-component": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
      "dev": true,
      "engines": {
        "node": ">=0.10"
      }
    },
    "node_modules/deep-equal": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
      "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
      "dev": true,
      "dependencies": {
        "is-arguments": "^1.0.4",
        "is-date-object": "^1.0.1",
        "is-regex": "^1.0.4",
        "object-is": "^1.0.1",
        "object-keys": "^1.1.1",
        "regexp.prototype.flags": "^1.2.0"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/default-gateway": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
      "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==",
      "dev": true,
      "dependencies": {
        "execa": "^1.0.0",
        "ip-regex": "^2.1.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/defaults": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
      "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
      "dev": true,
      "dependencies": {
        "clone": "^1.0.2"
      }
    },
    "node_modules/define-lazy-prop": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
      "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/define-properties": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
      "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
      "dev": true,
      "dependencies": {
        "object-keys": "^1.0.12"
      },
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/define-property": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
      "dev": true,
      "dependencies": {
        "is-descriptor": "^1.0.2",
        "isobject": "^3.0.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/del": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz",
      "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==",
      "dev": true,
      "dependencies": {
        "@types/glob": "^7.1.1",
        "globby": "^6.1.0",
        "is-path-cwd": "^2.0.0",
        "is-path-in-cwd": "^2.0.0",
        "p-map": "^2.0.0",
        "pify": "^4.0.1",
        "rimraf": "^2.6.3"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/del/node_modules/array-union": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
      "dev": true,
      "dependencies": {
        "array-uniq": "^1.0.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/del/node_modules/globby": {
      "version": "6.1.0",
      "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
      "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
      "dev": true,
      "dependencies": {
        "array-union": "^1.0.1",
        "glob": "^7.0.3",
        "object-assign": "^4.0.1",
        "pify": "^2.0.0",
        "pinkie-promise": "^2.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/del/node_modules/globby/node_modules/pify": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/del/node_modules/p-map": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
      "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/del/node_modules/pify": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/del/node_modules/rimraf": {
      "version": "2.7.1",
      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
      "dev": true,
      "dependencies": {
        "glob": "^7.1.3"
      },
      "bin": {
        "rimraf": "bin.js"
      }
    },
    "node_modules/delayed-stream": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
      "dev": true,
      "engines": {
        "node": ">=0.4.0"
      }
    },
    "node_modules/delegates": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
      "dev": true
    },
    "node_modules/depd": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/dependency-graph": {
      "version": "0.11.0",
      "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz",
      "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==",
      "dev": true,
      "engines": {
        "node": ">= 0.6.0"
      }
    },
    "node_modules/destroy": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
      "dev": true
    },
    "node_modules/detect-node": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
      "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
      "dev": true
    },
    "node_modules/di": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
      "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=",
      "dev": true
    },
    "node_modules/dir-glob": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
      "dev": true,
      "dependencies": {
        "path-type": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/dns-equal": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
      "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=",
      "dev": true
    },
    "node_modules/dns-packet": {
      "version": "1.3.4",
      "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz",
      "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==",
      "dev": true,
      "dependencies": {
        "ip": "^1.1.0",
        "safe-buffer": "^5.0.1"
      }
    },
    "node_modules/dns-txt": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
      "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
      "dev": true,
      "dependencies": {
        "buffer-indexof": "^1.0.0"
      }
    },
    "node_modules/dom-serialize": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz",
      "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=",
      "dev": true,
      "dependencies": {
        "custom-event": "~1.0.0",
        "ent": "~2.2.0",
        "extend": "^3.0.0",
        "void-elements": "^2.0.0"
      }
    },
    "node_modules/dom-serializer": {
      "version": "1.3.2",
      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
      "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
      "dev": true,
      "dependencies": {
        "domelementtype": "^2.0.1",
        "domhandler": "^4.2.0",
        "entities": "^2.0.0"
      },
      "funding": {
        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
      }
    },
    "node_modules/domelementtype": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
      "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
      "dev": true,
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/fb55"
        }
      ]
    },
    "node_modules/domhandler": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz",
      "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==",
      "dev": true,
      "dependencies": {
        "domelementtype": "^2.2.0"
      },
      "engines": {
        "node": ">= 4"
      },
      "funding": {
        "url": "https://github.com/fb55/domhandler?sponsor=1"
      }
    },
    "node_modules/domutils": {
      "version": "2.8.0",
      "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
      "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
      "dev": true,
      "dependencies": {
        "dom-serializer": "^1.0.1",
        "domelementtype": "^2.2.0",
        "domhandler": "^4.2.0"
      },
      "funding": {
        "url": "https://github.com/fb55/domutils?sponsor=1"
      }
    },
    "node_modules/ecc-jsbn": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
      "dev": true,
      "dependencies": {
        "jsbn": "~0.1.0",
        "safer-buffer": "^2.1.0"
      }
    },
    "node_modules/ee-first": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
      "dev": true
    },
    "node_modules/electron-to-chromium": {
      "version": "1.4.46",
      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.46.tgz",
      "integrity": "sha512-UtV0xUA/dibCKKP2JMxOpDtXR74zABevuUEH4K0tvduFSIoxRVcYmQsbB51kXsFTX8MmOyWMt8tuZAlmDOqkrQ==",
      "dev": true
    },
    "node_modules/emoji-regex": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
      "dev": true
    },
    "node_modules/emojis-list": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
      "dev": true,
      "engines": {
        "node": ">= 4"
      }
    },
    "node_modules/encodeurl": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
      "dev": true,
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/encoding": {
      "version": "0.1.13",
      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
      "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
      "dev": true,
      "optional": true,
      "dependencies": {
        "iconv-lite": "^0.6.2"
      }
    },
    "node_modules/encoding/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==",
      "dev": true,
      "optional": true,
      "dependencies": {
        "safer-buffer": ">= 2.1.2 < 3.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/end-of-stream": {
      "version": "1.4.4",
      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
      "dev": true,
      "dependencies": {
        "once": "^1.4.0"
      }
    },
    "node_modules/engine.io": {
      "version": "6.1.1",
      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.1.tgz",
      "integrity": "sha512-AyMc20q8JUUdvKd46+thc9o7yCZ6iC6MoBCChG5Z1XmFMpp+2+y/oKvwpZTUJB0KCjxScw1dV9c2h5pjiYBLuQ==",
      "dev": true,
      "dependencies": {
        "@types/cookie": "^0.4.1",
        "@types/cors": "^2.8.12",
        "@types/node": ">=10.0.0",
        "accepts": "~1.3.4",
        "base64id": "2.0.0",
        "cookie": "~0.4.1",
        "cors": "~2.8.5",
        "debug": "~4.3.1",
        "engine.io-parser": "~5.0.0",
        "ws": "~8.2.3"
      },
      "engines": {
        "node": ">=10.0.0"
      }
    },
    "node_modules/engine.io-parser": {
      "version": "5.0.3",
      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz",
      "integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==",
      "dev": true,
      "dependencies": {
        "@socket.io/base64-arraybuffer": "~1.0.2"
      },
      "engines": {
        "node": ">=10.0.0"
      }
    },
    "node_modules/enhanced-resolve": {
      "version": "5.8.2",
      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz",
      "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==",
      "dev": true,
      "dependencies": {
        "graceful-fs": "^4.2.4",
        "tapable": "^2.2.0"
      },
      "engines": {
        "node": ">=10.13.0"
      }
    },
    "node_modules/ent": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz",
      "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=",
      "dev": true
    },
    "node_modules/entities": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
      "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
      "dev": true,
      "funding": {
        "url": "https://github.com/fb55/entities?sponsor=1"
      }
    },
    "node_modules/env-paths": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
      "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/err-code": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
      "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
      "dev": true
    },
    "node_modules/errno": {
      "version": "0.1.8",
      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
      "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
      "dev": true,
      "dependencies": {
        "prr": "~1.0.1"
      },
      "bin": {
        "errno": "cli.js"
      }
    },
    "node_modules/error-ex": {
      "version": "1.3.2",
      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
      "dev": true,
      "dependencies": {
        "is-arrayish": "^0.2.1"
      }
    },
    "node_modules/es-module-lexer": {
      "version": "0.7.1",
      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz",
      "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==",
      "dev": true
    },
    "node_modules/escalade": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/escape-html": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
      "dev": true
    },
    "node_modules/escape-string-regexp": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
      "dev": true,
      "engines": {
        "node": ">=0.8.0"
      }
    },
    "node_modules/eslint-scope": {
      "version": "5.1.1",
      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
      "dev": true,
      "dependencies": {
        "esrecurse": "^4.3.0",
        "estraverse": "^4.1.1"
      },
      "engines": {
        "node": ">=8.0.0"
      }
    },
    "node_modules/esrecurse": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
      "dev": true,
      "dependencies": {
        "estraverse": "^5.2.0"
      },
      "engines": {
        "node": ">=4.0"
      }
    },
    "node_modules/esrecurse/node_modules/estraverse": {
      "version": "5.3.0",
      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
      "dev": true,
      "engines": {
        "node": ">=4.0"
      }
    },
    "node_modules/estraverse": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
      "dev": true,
      "engines": {
        "node": ">=4.0"
      }
    },
    "node_modules/esutils": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/etag": {
      "version": "1.8.1",
      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/eventemitter3": {
      "version": "4.0.7",
      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
      "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
      "dev": true
    },
    "node_modules/events": {
      "version": "3.3.0",
      "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
      "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
      "dev": true,
      "engines": {
        "node": ">=0.8.x"
      }
    },
    "node_modules/eventsource": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz",
      "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==",
      "dev": true,
      "dependencies": {
        "original": "^1.0.0"
      },
      "engines": {
        "node": ">=0.12.0"
      }
    },
    "node_modules/execa": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
      "dev": true,
      "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"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/expand-brackets": {
      "version": "2.1.4",
      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
      "dev": true,
      "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"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/expand-brackets/node_modules/debug": {
      "version": "2.6.9",
      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
      "dev": true,
      "dependencies": {
        "ms": "2.0.0"
      }
    },
    "node_modules/expand-brackets/node_modules/define-property": {
      "version": "0.2.5",
      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
      "dev": true,
      "dependencies": {
        "is-descriptor": "^0.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/expand-brackets/node_modules/extend-shallow": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
      "dev": true,
      "dependencies": {
        "is-extendable": "^0.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/expand-brackets/node_modules/is-accessor-descriptor": {
      "version": "0.1.6",
      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/expand-brackets/node_modules/is-data-descriptor": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/expand-brackets/node_modules/is-descriptor": {
      "version": "0.1.6",
      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
      "dev": true,
      "dependencies": {
        "is-accessor-descriptor": "^0.1.6",
        "is-data-descriptor": "^0.1.4",
        "kind-of": "^5.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/expand-brackets/node_modules/is-extendable": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/expand-brackets/node_modules/kind-of": {
      "version": "5.1.0",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
      "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/expand-brackets/node_modules/ms": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
      "dev": true
    },
    "node_modules/express": {
      "version": "4.17.2",
      "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz",
      "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==",
      "dev": true,
      "dependencies": {
        "accepts": "~1.3.7",
        "array-flatten": "1.1.1",
        "body-parser": "1.19.1",
        "content-disposition": "0.5.4",
        "content-type": "~1.0.4",
        "cookie": "0.4.1",
        "cookie-signature": "1.0.6",
        "debug": "2.6.9",
        "depd": "~1.1.2",
        "encodeurl": "~1.0.2",
        "escape-html": "~1.0.3",
        "etag": "~1.8.1",
        "finalhandler": "~1.1.2",
        "fresh": "0.5.2",
        "merge-descriptors": "1.0.1",
        "methods": "~1.1.2",
        "on-finished": "~2.3.0",
        "parseurl": "~1.3.3",
        "path-to-regexp": "0.1.7",
        "proxy-addr": "~2.0.7",
        "qs": "6.9.6",
        "range-parser": "~1.2.1",
        "safe-buffer": "5.2.1",
        "send": "0.17.2",
        "serve-static": "1.14.2",
        "setprototypeof": "1.2.0",
        "statuses": "~1.5.0",
        "type-is": "~1.6.18",
        "utils-merge": "1.0.1",
        "vary": "~1.1.2"
      },
      "engines": {
        "node": ">= 0.10.0"
      }
    },
    "node_modules/express/node_modules/array-flatten": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
      "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
      "dev": true
    },
    "node_modules/express/node_modules/debug": {
      "version": "2.6.9",
      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
      "dev": true,
      "dependencies": {
        "ms": "2.0.0"
      }
    },
    "node_modules/express/node_modules/ms": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
      "dev": true
    },
    "node_modules/express/node_modules/safe-buffer": {
      "version": "5.2.1",
      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
      "dev": true,
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ]
    },
    "node_modules/extend": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
      "dev": true
    },
    "node_modules/extend-shallow": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
      "dev": true,
      "dependencies": {
        "assign-symbols": "^1.0.0",
        "is-extendable": "^1.0.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/external-editor": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
      "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
      "dev": true,
      "dependencies": {
        "chardet": "^0.7.0",
        "iconv-lite": "^0.4.24",
        "tmp": "^0.0.33"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/extglob": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
      "dev": true,
      "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"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/extglob/node_modules/define-property": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
      "dev": true,
      "dependencies": {
        "is-descriptor": "^1.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/extglob/node_modules/extend-shallow": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
      "dev": true,
      "dependencies": {
        "is-extendable": "^0.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/extglob/node_modules/is-extendable": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/extsprintf": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
      "dev": true,
      "engines": [
        "node >=0.6.0"
      ]
    },
    "node_modules/fast-deep-equal": {
      "version": "3.1.3",
      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
      "dev": true
    },
    "node_modules/fast-glob": {
      "version": "3.2.11",
      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
      "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
      "dev": true,
      "dependencies": {
        "@nodelib/fs.stat": "^2.0.2",
        "@nodelib/fs.walk": "^1.2.3",
        "glob-parent": "^5.1.2",
        "merge2": "^1.3.0",
        "micromatch": "^4.0.4"
      },
      "engines": {
        "node": ">=8.6.0"
      }
    },
    "node_modules/fast-json-stable-stringify": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
      "dev": true
    },
    "node_modules/fastq": {
      "version": "1.13.0",
      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
      "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
      "dev": true,
      "dependencies": {
        "reusify": "^1.0.4"
      }
    },
    "node_modules/faye-websocket": {
      "version": "0.11.4",
      "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
      "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
      "dev": true,
      "dependencies": {
        "websocket-driver": ">=0.5.1"
      },
      "engines": {
        "node": ">=0.8.0"
      }
    },
    "node_modules/figures": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
      "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
      "dev": true,
      "dependencies": {
        "escape-string-regexp": "^1.0.5"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/file-uri-to-path": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
      "dev": true,
      "optional": true
    },
    "node_modules/fill-range": {
      "version": "7.0.1",
      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
      "dev": true,
      "dependencies": {
        "to-regex-range": "^5.0.1"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/finalhandler": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
      "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
      "dev": true,
      "dependencies": {
        "debug": "2.6.9",
        "encodeurl": "~1.0.2",
        "escape-html": "~1.0.3",
        "on-finished": "~2.3.0",
        "parseurl": "~1.3.3",
        "statuses": "~1.5.0",
        "unpipe": "~1.0.0"
      },
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/finalhandler/node_modules/debug": {
      "version": "2.6.9",
      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
      "dev": true,
      "dependencies": {
        "ms": "2.0.0"
      }
    },
    "node_modules/finalhandler/node_modules/ms": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
      "dev": true
    },
    "node_modules/find-cache-dir": {
      "version": "3.3.1",
      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
      "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
      "dev": true,
      "dependencies": {
        "commondir": "^1.0.1",
        "make-dir": "^3.0.2",
        "pkg-dir": "^4.1.0"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
      }
    },
    "node_modules/find-up": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
      "dev": true,
      "dependencies": {
        "locate-path": "^5.0.0",
        "path-exists": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/flatted": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
      "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
      "dev": true
    },
    "node_modules/flatten": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz",
      "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==",
      "deprecated": "flatten is deprecated in favor of utility frameworks such as lodash.",
      "dev": true
    },
    "node_modules/follow-redirects": {
      "version": "1.14.7",
      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
      "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==",
      "dev": true,
      "funding": [
        {
          "type": "individual",
          "url": "https://github.com/sponsors/RubenVerborgh"
        }
      ],
      "engines": {
        "node": ">=4.0"
      },
      "peerDependenciesMeta": {
        "debug": {
          "optional": true
        }
      }
    },
    "node_modules/for-in": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/forever-agent": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
      "dev": true,
      "engines": {
        "node": "*"
      }
    },
    "node_modules/form-data": {
      "version": "2.3.3",
      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
      "dev": true,
      "dependencies": {
        "asynckit": "^0.4.0",
        "combined-stream": "^1.0.6",
        "mime-types": "^2.1.12"
      },
      "engines": {
        "node": ">= 0.12"
      }
    },
    "node_modules/forwarded": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
      "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/fragment-cache": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
      "dev": true,
      "dependencies": {
        "map-cache": "^0.2.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/fresh": {
      "version": "0.5.2",
      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/fs-extra": {
      "version": "8.1.0",
      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
      "dev": true,
      "dependencies": {
        "graceful-fs": "^4.2.0",
        "jsonfile": "^4.0.0",
        "universalify": "^0.1.0"
      },
      "engines": {
        "node": ">=6 <7 || >=8"
      }
    },
    "node_modules/fs-minipass": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
      "dev": true,
      "dependencies": {
        "minipass": "^3.0.0"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/fs-monkey": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz",
      "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==",
      "dev": true
    },
    "node_modules/fs.realpath": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
      "dev": true
    },
    "node_modules/fsevents": {
      "version": "2.3.2",
      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
      "dev": true,
      "hasInstallScript": true,
      "optional": true,
      "os": [
        "darwin"
      ],
      "engines": {
        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
      }
    },
    "node_modules/function-bind": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
      "dev": true
    },
    "node_modules/gauge": {
      "version": "2.7.4",
      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
      "dev": true,
      "dependencies": {
        "aproba": "^1.0.3",
        "console-control-strings": "^1.0.0",
        "has-unicode": "^2.0.0",
        "object-assign": "^4.1.0",
        "signal-exit": "^3.0.0",
        "string-width": "^1.0.1",
        "strip-ansi": "^3.0.1",
        "wide-align": "^1.1.0"
      }
    },
    "node_modules/gauge/node_modules/ansi-regex": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/gauge/node_modules/is-fullwidth-code-point": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
      "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
      "dev": true,
      "dependencies": {
        "number-is-nan": "^1.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/gauge/node_modules/string-width": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
      "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
      "dev": true,
      "dependencies": {
        "code-point-at": "^1.0.0",
        "is-fullwidth-code-point": "^1.0.0",
        "strip-ansi": "^3.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/gauge/node_modules/strip-ansi": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
      "dev": true,
      "dependencies": {
        "ansi-regex": "^2.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/gensync": {
      "version": "1.0.0-beta.2",
      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
      "dev": true,
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/get-caller-file": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
      "dev": true,
      "engines": {
        "node": "6.* || 8.* || >= 10.*"
      }
    },
    "node_modules/get-intrinsic": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
      "dev": true,
      "dependencies": {
        "function-bind": "^1.1.1",
        "has": "^1.0.3",
        "has-symbols": "^1.0.1"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/get-stream": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
      "dev": true,
      "dependencies": {
        "pump": "^3.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/get-value": {
      "version": "2.0.6",
      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/getpass": {
      "version": "0.1.7",
      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
      "dev": true,
      "dependencies": {
        "assert-plus": "^1.0.0"
      }
    },
    "node_modules/glob": {
      "version": "7.1.7",
      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
      "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
      "dev": true,
      "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"
      },
      "engines": {
        "node": "*"
      },
      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }
    },
    "node_modules/glob-parent": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
      "dev": true,
      "dependencies": {
        "is-glob": "^4.0.1"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/glob-to-regexp": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
      "dev": true
    },
    "node_modules/globals": {
      "version": "11.12.0",
      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/globby": {
      "version": "11.1.0",
      "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
      "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
      "dev": true,
      "dependencies": {
        "array-union": "^2.1.0",
        "dir-glob": "^3.0.1",
        "fast-glob": "^3.2.9",
        "ignore": "^5.2.0",
        "merge2": "^1.4.1",
        "slash": "^3.0.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/graceful-fs": {
      "version": "4.2.9",
      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
      "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==",
      "dev": true
    },
    "node_modules/handle-thing": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
      "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==",
      "dev": true
    },
    "node_modules/har-schema": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/har-validator": {
      "version": "5.1.5",
      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
      "deprecated": "this library is no longer supported",
      "dev": true,
      "dependencies": {
        "ajv": "^6.12.3",
        "har-schema": "^2.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/har-validator/node_modules/ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
      "dev": true,
      "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"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/har-validator/node_modules/json-schema-traverse": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
      "dev": true
    },
    "node_modules/has": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
      "dev": true,
      "dependencies": {
        "function-bind": "^1.1.1"
      },
      "engines": {
        "node": ">= 0.4.0"
      }
    },
    "node_modules/has-flag": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/has-symbols": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
      "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
      "dev": true,
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/has-tostringtag": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
      "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
      "dev": true,
      "dependencies": {
        "has-symbols": "^1.0.2"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/has-unicode": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
      "dev": true
    },
    "node_modules/has-value": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
      "dev": true,
      "dependencies": {
        "get-value": "^2.0.6",
        "has-values": "^1.0.0",
        "isobject": "^3.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/has-values": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
      "dev": true,
      "dependencies": {
        "is-number": "^3.0.0",
        "kind-of": "^4.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/has-values/node_modules/is-number": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/has-values/node_modules/is-number/node_modules/kind-of": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/has-values/node_modules/kind-of": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
      "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/hosted-git-info": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
      "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
      "dev": true,
      "dependencies": {
        "lru-cache": "^6.0.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/hpack.js": {
      "version": "2.1.6",
      "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
      "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
      "dev": true,
      "dependencies": {
        "inherits": "^2.0.1",
        "obuf": "^1.0.0",
        "readable-stream": "^2.0.1",
        "wbuf": "^1.1.0"
      }
    },
    "node_modules/hpack.js/node_modules/readable-stream": {
      "version": "2.3.7",
      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
      "dev": true,
      "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"
      }
    },
    "node_modules/hpack.js/node_modules/string_decoder": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
      "dev": true,
      "dependencies": {
        "safe-buffer": "~5.1.0"
      }
    },
    "node_modules/html-entities": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz",
      "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==",
      "dev": true
    },
    "node_modules/html-escaper": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
      "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
      "dev": true
    },
    "node_modules/http-cache-semantics": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
      "dev": true
    },
    "node_modules/http-deceiver": {
      "version": "1.2.7",
      "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
      "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
      "dev": true
    },
    "node_modules/http-errors": {
      "version": "1.8.1",
      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
      "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
      "dev": true,
      "dependencies": {
        "depd": "~1.1.2",
        "inherits": "2.0.4",
        "setprototypeof": "1.2.0",
        "statuses": ">= 1.5.0 < 2",
        "toidentifier": "1.0.1"
      },
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/http-parser-js": {
      "version": "0.5.5",
      "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz",
      "integrity": "sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==",
      "dev": true
    },
    "node_modules/http-proxy": {
      "version": "1.18.1",
      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
      "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
      "dev": true,
      "dependencies": {
        "eventemitter3": "^4.0.0",
        "follow-redirects": "^1.0.0",
        "requires-port": "^1.0.0"
      },
      "engines": {
        "node": ">=8.0.0"
      }
    },
    "node_modules/http-proxy-agent": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
      "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
      "dev": true,
      "dependencies": {
        "@tootallnate/once": "1",
        "agent-base": "6",
        "debug": "4"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/http-proxy-middleware": {
      "version": "0.19.1",
      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
      "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
      "dev": true,
      "dependencies": {
        "http-proxy": "^1.17.0",
        "is-glob": "^4.0.0",
        "lodash": "^4.17.11",
        "micromatch": "^3.1.10"
      },
      "engines": {
        "node": ">=4.0.0"
      }
    },
    "node_modules/http-proxy-middleware/node_modules/braces": {
      "version": "2.3.2",
      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
      "dev": true,
      "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"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/http-proxy-middleware/node_modules/braces/node_modules/extend-shallow": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
      "dev": true,
      "dependencies": {
        "is-extendable": "^0.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/http-proxy-middleware/node_modules/fill-range": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
      "dev": true,
      "dependencies": {
        "extend-shallow": "^2.0.1",
        "is-number": "^3.0.0",
        "repeat-string": "^1.6.1",
        "to-regex-range": "^2.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/http-proxy-middleware/node_modules/fill-range/node_modules/extend-shallow": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
      "dev": true,
      "dependencies": {
        "is-extendable": "^0.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/http-proxy-middleware/node_modules/is-extendable": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/http-proxy-middleware/node_modules/is-number": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/http-proxy-middleware/node_modules/is-number/node_modules/kind-of": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/http-proxy-middleware/node_modules/micromatch": {
      "version": "3.1.10",
      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
      "dev": true,
      "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"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/http-proxy-middleware/node_modules/to-regex-range": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
      "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
      "dev": true,
      "dependencies": {
        "is-number": "^3.0.0",
        "repeat-string": "^1.6.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/http-signature": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
      "dev": true,
      "dependencies": {
        "assert-plus": "^1.0.0",
        "jsprim": "^1.2.2",
        "sshpk": "^1.7.0"
      },
      "engines": {
        "node": ">=0.8",
        "npm": ">=1.3.7"
      }
    },
    "node_modules/https-proxy-agent": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
      "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
      "dev": true,
      "dependencies": {
        "agent-base": "6",
        "debug": "4"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/humanize-ms": {
      "version": "1.2.1",
      "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
      "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=",
      "dev": true,
      "dependencies": {
        "ms": "^2.0.0"
      }
    },
    "node_modules/iconv-lite": {
      "version": "0.4.24",
      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
      "dev": true,
      "dependencies": {
        "safer-buffer": ">= 2.1.2 < 3"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/icss-utils": {
      "version": "5.1.0",
      "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
      "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
      "dev": true,
      "engines": {
        "node": "^10 || ^12 || >= 14"
      },
      "peerDependencies": {
        "postcss": "^8.1.0"
      }
    },
    "node_modules/ieee754": {
      "version": "1.2.1",
      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
      "dev": true,
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ]
    },
    "node_modules/ignore": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
      "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
      "dev": true,
      "engines": {
        "node": ">= 4"
      }
    },
    "node_modules/ignore-walk": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz",
      "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==",
      "dev": true,
      "dependencies": {
        "minimatch": "^3.0.4"
      }
    },
    "node_modules/image-size": {
      "version": "0.5.5",
      "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
      "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
      "dev": true,
      "optional": true,
      "bin": {
        "image-size": "bin/image-size.js"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/import-fresh": {
      "version": "3.3.0",
      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
      "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
      "dev": true,
      "dependencies": {
        "parent-module": "^1.0.0",
        "resolve-from": "^4.0.0"
      },
      "engines": {
        "node": ">=6"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/import-local": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
      "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==",
      "dev": true,
      "dependencies": {
        "pkg-dir": "^3.0.0",
        "resolve-cwd": "^2.0.0"
      },
      "bin": {
        "import-local-fixture": "fixtures/cli.js"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/import-local/node_modules/find-up": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
      "dev": true,
      "dependencies": {
        "locate-path": "^3.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/import-local/node_modules/locate-path": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
      "dev": true,
      "dependencies": {
        "p-locate": "^3.0.0",
        "path-exists": "^3.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/import-local/node_modules/p-limit": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
      "dev": true,
      "dependencies": {
        "p-try": "^2.0.0"
      },
      "engines": {
        "node": ">=6"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/import-local/node_modules/p-locate": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
      "dev": true,
      "dependencies": {
        "p-limit": "^2.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/import-local/node_modules/path-exists": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/import-local/node_modules/pkg-dir": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
      "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
      "dev": true,
      "dependencies": {
        "find-up": "^3.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/imurmurhash": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
      "dev": true,
      "engines": {
        "node": ">=0.8.19"
      }
    },
    "node_modules/indent-string": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
      "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/indexes-of": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
      "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
      "dev": true
    },
    "node_modules/infer-owner": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
      "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
      "dev": true
    },
    "node_modules/inflight": {
      "version": "1.0.6",
      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
      "dev": true,
      "dependencies": {
        "once": "^1.3.0",
        "wrappy": "1"
      }
    },
    "node_modules/inherits": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
      "dev": true
    },
    "node_modules/ini": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
      "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
      "dev": true,
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/inquirer": {
      "version": "8.1.1",
      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.1.1.tgz",
      "integrity": "sha512-hUDjc3vBkh/uk1gPfMAD/7Z188Q8cvTGl0nxwaCdwSbzFh6ZKkZh+s2ozVxbE5G9ZNRyeY0+lgbAIOUFsFf98w==",
      "dev": true,
      "dependencies": {
        "ansi-escapes": "^4.2.1",
        "chalk": "^4.1.1",
        "cli-cursor": "^3.1.0",
        "cli-width": "^3.0.0",
        "external-editor": "^3.0.3",
        "figures": "^3.0.0",
        "lodash": "^4.17.21",
        "mute-stream": "0.0.8",
        "ora": "^5.3.0",
        "run-async": "^2.4.0",
        "rxjs": "^6.6.6",
        "string-width": "^4.1.0",
        "strip-ansi": "^6.0.0",
        "through": "^2.3.6"
      },
      "engines": {
        "node": ">=8.0.0"
      }
    },
    "node_modules/inquirer/node_modules/ansi-styles": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
      "dev": true,
      "dependencies": {
        "color-convert": "^2.0.1"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
      }
    },
    "node_modules/inquirer/node_modules/chalk": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
      "dev": true,
      "dependencies": {
        "ansi-styles": "^4.1.0",
        "supports-color": "^7.1.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/chalk/chalk?sponsor=1"
      }
    },
    "node_modules/inquirer/node_modules/color-convert": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
      "dev": true,
      "dependencies": {
        "color-name": "~1.1.4"
      },
      "engines": {
        "node": ">=7.0.0"
      }
    },
    "node_modules/inquirer/node_modules/color-name": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
      "dev": true
    },
    "node_modules/inquirer/node_modules/has-flag": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/inquirer/node_modules/supports-color": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
      "dev": true,
      "dependencies": {
        "has-flag": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/internal-ip": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz",
      "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==",
      "dev": true,
      "dependencies": {
        "default-gateway": "^4.2.0",
        "ipaddr.js": "^1.9.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/ip": {
      "version": "1.1.5",
      "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
      "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
      "dev": true
    },
    "node_modules/ip-regex": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
      "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/ipaddr.js": {
      "version": "1.9.1",
      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
      "dev": true,
      "engines": {
        "node": ">= 0.10"
      }
    },
    "node_modules/is-absolute-url": {
      "version": "3.0.3",
      "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz",
      "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/is-accessor-descriptor": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
      "dev": true,
      "dependencies": {
        "kind-of": "^6.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/is-arguments": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
      "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
      "dev": true,
      "dependencies": {
        "call-bind": "^1.0.2",
        "has-tostringtag": "^1.0.0"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/is-arrayish": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
      "dev": true
    },
    "node_modules/is-binary-path": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
      "dev": true,
      "dependencies": {
        "binary-extensions": "^2.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/is-buffer": {
      "version": "1.1.6",
      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
      "dev": true
    },
    "node_modules/is-core-module": {
      "version": "2.8.1",
      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
      "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==",
      "dev": true,
      "dependencies": {
        "has": "^1.0.3"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/is-data-descriptor": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
      "dev": true,
      "dependencies": {
        "kind-of": "^6.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/is-date-object": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
      "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
      "dev": true,
      "dependencies": {
        "has-tostringtag": "^1.0.0"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/is-descriptor": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
      "dev": true,
      "dependencies": {
        "is-accessor-descriptor": "^1.0.0",
        "is-data-descriptor": "^1.0.0",
        "kind-of": "^6.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/is-docker": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
      "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
      "dev": true,
      "bin": {
        "is-docker": "cli.js"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/is-extendable": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
      "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
      "dev": true,
      "dependencies": {
        "is-plain-object": "^2.0.4"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/is-extglob": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/is-fullwidth-code-point": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/is-glob": {
      "version": "4.0.3",
      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
      "dev": true,
      "dependencies": {
        "is-extglob": "^2.1.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/is-interactive": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
      "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/is-lambda": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
      "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=",
      "dev": true
    },
    "node_modules/is-number": {
      "version": "7.0.0",
      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
      "dev": true,
      "engines": {
        "node": ">=0.12.0"
      }
    },
    "node_modules/is-path-cwd": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
      "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/is-path-in-cwd": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz",
      "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==",
      "dev": true,
      "dependencies": {
        "is-path-inside": "^2.1.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/is-path-inside": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
      "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
      "dev": true,
      "dependencies": {
        "path-is-inside": "^1.0.2"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/is-plain-object": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
      "dev": true,
      "dependencies": {
        "isobject": "^3.0.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/is-regex": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
      "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
      "dev": true,
      "dependencies": {
        "call-bind": "^1.0.2",
        "has-tostringtag": "^1.0.0"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/is-stream": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/is-typedarray": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
      "dev": true
    },
    "node_modules/is-unicode-supported": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
      "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
      "dev": true,
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/is-what": {
      "version": "3.14.1",
      "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz",
      "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==",
      "dev": true
    },
    "node_modules/is-windows": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/is-wsl": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
      "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
      "dev": true,
      "dependencies": {
        "is-docker": "^2.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/isarray": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
      "dev": true
    },
    "node_modules/isbinaryfile": {
      "version": "4.0.8",
      "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz",
      "integrity": "sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==",
      "dev": true,
      "engines": {
        "node": ">= 8.0.0"
      },
      "funding": {
        "url": "https://github.com/sponsors/gjtorikian/"
      }
    },
    "node_modules/isexe": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
      "dev": true
    },
    "node_modules/isobject": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/isstream": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
      "dev": true
    },
    "node_modules/istanbul-lib-coverage": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
      "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/istanbul-lib-instrument": {
      "version": "4.0.3",
      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
      "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
      "dev": true,
      "dependencies": {
        "@babel/core": "^7.7.5",
        "@istanbuljs/schema": "^0.1.2",
        "istanbul-lib-coverage": "^3.0.0",
        "semver": "^6.3.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/istanbul-lib-instrument/node_modules/semver": {
      "version": "6.3.0",
      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
      "dev": true,
      "bin": {
        "semver": "bin/semver.js"
      }
    },
    "node_modules/istanbul-lib-report": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
      "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
      "dev": true,
      "dependencies": {
        "istanbul-lib-coverage": "^3.0.0",
        "make-dir": "^3.0.0",
        "supports-color": "^7.1.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/istanbul-lib-report/node_modules/has-flag": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/istanbul-lib-report/node_modules/supports-color": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
      "dev": true,
      "dependencies": {
        "has-flag": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/istanbul-lib-source-maps": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
      "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
      "dev": true,
      "dependencies": {
        "debug": "^4.1.1",
        "istanbul-lib-coverage": "^3.0.0",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/istanbul-lib-source-maps/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/istanbul-reports": {
      "version": "3.1.3",
      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz",
      "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==",
      "dev": true,
      "dependencies": {
        "html-escaper": "^2.0.0",
        "istanbul-lib-report": "^3.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/jasmine-core": {
      "version": "3.7.1",
      "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.7.1.tgz",
      "integrity": "sha512-DH3oYDS/AUvvr22+xUBW62m1Xoy7tUlY1tsxKEJvl5JeJ7q8zd1K5bUwiOxdH+erj6l2vAMM3hV25Xs9/WrmuQ==",
      "dev": true
    },
    "node_modules/jest-worker": {
      "version": "27.0.2",
      "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.2.tgz",
      "integrity": "sha512-EoBdilOTTyOgmHXtw/cPc+ZrCA0KJMrkXzkrPGNwLmnvvlN1nj7MPrxpT7m+otSv2e1TLaVffzDnE/LB14zJMg==",
      "dev": true,
      "dependencies": {
        "@types/node": "*",
        "merge-stream": "^2.0.0",
        "supports-color": "^8.0.0"
      },
      "engines": {
        "node": ">= 10.13.0"
      }
    },
    "node_modules/jest-worker/node_modules/has-flag": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/jest-worker/node_modules/supports-color": {
      "version": "8.1.1",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
      "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
      "dev": true,
      "dependencies": {
        "has-flag": "^4.0.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/chalk/supports-color?sponsor=1"
      }
    },
    "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==",
      "dev": true
    },
    "node_modules/jsbn": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
      "dev": true
    },
    "node_modules/jsesc": {
      "version": "2.5.2",
      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
      "dev": true,
      "bin": {
        "jsesc": "bin/jsesc"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/json-parse-better-errors": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
      "dev": true
    },
    "node_modules/json-parse-even-better-errors": {
      "version": "2.3.1",
      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
      "dev": true
    },
    "node_modules/json-schema": {
      "version": "0.4.0",
      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
      "dev": true
    },
    "node_modules/json-schema-traverse": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
      "dev": true
    },
    "node_modules/json-stringify-safe": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
      "dev": true
    },
    "node_modules/json3": {
      "version": "3.3.3",
      "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz",
      "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==",
      "dev": true
    },
    "node_modules/json5": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
      "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
      "dev": true,
      "dependencies": {
        "minimist": "^1.2.5"
      },
      "bin": {
        "json5": "lib/cli.js"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/jsonc-parser": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
      "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==",
      "dev": true
    },
    "node_modules/jsonfile": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
      "dev": true,
      "optionalDependencies": {
        "graceful-fs": "^4.1.6"
      }
    },
    "node_modules/jsonparse": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
      "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
      "dev": true,
      "engines": [
        "node >= 0.2.0"
      ]
    },
    "node_modules/jsprim": {
      "version": "1.4.2",
      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
      "dev": true,
      "dependencies": {
        "assert-plus": "1.0.0",
        "extsprintf": "1.3.0",
        "json-schema": "0.4.0",
        "verror": "1.10.0"
      },
      "engines": {
        "node": ">=0.6.0"
      }
    },
    "node_modules/karma": {
      "version": "6.3.11",
      "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.11.tgz",
      "integrity": "sha512-QGUh4yXgizzDNPLB5nWTvP+wysKexngbyLVWFOyikB661hpa2RZLf5anZQzqliWtAQuYVep0ot0D1U7UQKpsxQ==",
      "dev": true,
      "dependencies": {
        "body-parser": "^1.19.0",
        "braces": "^3.0.2",
        "chokidar": "^3.5.1",
        "colors": "1.4.0",
        "connect": "^3.7.0",
        "di": "^0.0.1",
        "dom-serialize": "^2.2.1",
        "glob": "^7.1.7",
        "graceful-fs": "^4.2.6",
        "http-proxy": "^1.18.1",
        "isbinaryfile": "^4.0.8",
        "lodash": "^4.17.21",
        "log4js": "^6.3.0",
        "mime": "^2.5.2",
        "minimatch": "^3.0.4",
        "qjobs": "^1.2.0",
        "range-parser": "^1.2.1",
        "rimraf": "^3.0.2",
        "socket.io": "^4.2.0",
        "source-map": "^0.6.1",
        "tmp": "^0.2.1",
        "ua-parser-js": "^0.7.30",
        "yargs": "^16.1.1"
      },
      "bin": {
        "karma": "bin/karma"
      },
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/karma-chrome-launcher": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz",
      "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==",
      "dev": true,
      "dependencies": {
        "which": "^1.2.1"
      }
    },
    "node_modules/karma-coverage": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.0.3.tgz",
      "integrity": "sha512-atDvLQqvPcLxhED0cmXYdsPMCQuh6Asa9FMZW1bhNqlVEhJoB9qyZ2BY1gu7D/rr5GLGb5QzYO4siQskxaWP/g==",
      "dev": true,
      "dependencies": {
        "istanbul-lib-coverage": "^3.0.0",
        "istanbul-lib-instrument": "^4.0.1",
        "istanbul-lib-report": "^3.0.0",
        "istanbul-lib-source-maps": "^4.0.0",
        "istanbul-reports": "^3.0.0",
        "minimatch": "^3.0.4"
      },
      "engines": {
        "node": ">=10.0.0"
      }
    },
    "node_modules/karma-jasmine": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-4.0.1.tgz",
      "integrity": "sha512-h8XDAhTiZjJKzfkoO1laMH+zfNlra+dEQHUAjpn5JV1zCPtOIVWGQjLBrqhnzQa/hrU2XrZwSyBa6XjEBzfXzw==",
      "dev": true,
      "dependencies": {
        "jasmine-core": "^3.6.0"
      },
      "engines": {
        "node": ">= 10"
      },
      "peerDependencies": {
        "karma": "*"
      }
    },
    "node_modules/karma-jasmine-html-reporter": {
      "version": "1.7.0",
      "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.7.0.tgz",
      "integrity": "sha512-pzum1TL7j90DTE86eFt48/s12hqwQuiD+e5aXx2Dc9wDEn2LfGq6RoAxEZZjFiN0RDSCOnosEKRZWxbQ+iMpQQ==",
      "dev": true,
      "peerDependencies": {
        "jasmine-core": ">=3.8",
        "karma": ">=0.9",
        "karma-jasmine": ">=1.1"
      }
    },
    "node_modules/karma-source-map-support": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz",
      "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==",
      "dev": true,
      "dependencies": {
        "source-map-support": "^0.5.5"
      }
    },
    "node_modules/karma/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/karma/node_modules/tmp": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
      "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
      "dev": true,
      "dependencies": {
        "rimraf": "^3.0.0"
      },
      "engines": {
        "node": ">=8.17.0"
      }
    },
    "node_modules/karma/node_modules/yargs": {
      "version": "16.2.0",
      "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
      "dev": true,
      "dependencies": {
        "cliui": "^7.0.2",
        "escalade": "^3.1.1",
        "get-caller-file": "^2.0.5",
        "require-directory": "^2.1.1",
        "string-width": "^4.2.0",
        "y18n": "^5.0.5",
        "yargs-parser": "^20.2.2"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/karma/node_modules/yargs-parser": {
      "version": "20.2.9",
      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
      "dev": true,
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/killable": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
      "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==",
      "dev": true
    },
    "node_modules/kind-of": {
      "version": "6.0.3",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/klona": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz",
      "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==",
      "dev": true,
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/less": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/less/-/less-4.1.1.tgz",
      "integrity": "sha512-w09o8tZFPThBscl5d0Ggp3RcrKIouBoQscnOMgFH3n5V3kN/CXGHNfCkRPtxJk6nKryDXaV9aHLK55RXuH4sAw==",
      "dev": true,
      "dependencies": {
        "copy-anything": "^2.0.1",
        "parse-node-version": "^1.0.1",
        "tslib": "^1.10.0"
      },
      "bin": {
        "lessc": "bin/lessc"
      },
      "engines": {
        "node": ">=6"
      },
      "optionalDependencies": {
        "errno": "^0.1.1",
        "graceful-fs": "^4.1.2",
        "image-size": "~0.5.0",
        "make-dir": "^2.1.0",
        "mime": "^1.4.1",
        "needle": "^2.5.2",
        "source-map": "~0.6.0"
      }
    },
    "node_modules/less-loader": {
      "version": "10.0.0",
      "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-10.0.0.tgz",
      "integrity": "sha512-JjioAkw9qyavL0BzMPUOHJa0a20fh+ipq/MNZH4OkU8qERsCMeZIWRE0FDBIx2O+cFguvY01vHh/lmBA9LyWDg==",
      "dev": true,
      "dependencies": {
        "klona": "^2.0.4"
      },
      "engines": {
        "node": ">= 12.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "less": "^3.5.0 || ^4.0.0",
        "webpack": "^5.0.0"
      }
    },
    "node_modules/less/node_modules/make-dir": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
      "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
      "dev": true,
      "optional": true,
      "dependencies": {
        "pify": "^4.0.1",
        "semver": "^5.6.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/less/node_modules/mime": {
      "version": "1.6.0",
      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
      "dev": true,
      "optional": true,
      "bin": {
        "mime": "cli.js"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/less/node_modules/pify": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
      "dev": true,
      "optional": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/less/node_modules/semver": {
      "version": "5.7.1",
      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
      "dev": true,
      "optional": true,
      "bin": {
        "semver": "bin/semver"
      }
    },
    "node_modules/less/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "optional": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/less/node_modules/tslib": {
      "version": "1.14.1",
      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
      "dev": true
    },
    "node_modules/license-webpack-plugin": {
      "version": "2.3.20",
      "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-2.3.20.tgz",
      "integrity": "sha512-AHVueg9clOKACSHkhmEI+PCC9x8+qsQVuKECZD3ETxETK5h/PCv5/MUzyG1gm8OMcip/s1tcNxqo9Qb7WhjGsg==",
      "dev": true,
      "dependencies": {
        "@types/webpack-sources": "^0.1.5",
        "webpack-sources": "^1.2.0"
      },
      "peerDependenciesMeta": {
        "webpack": {
          "optional": true
        }
      }
    },
    "node_modules/lilconfig": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz",
      "integrity": "sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==",
      "dev": true,
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/lines-and-columns": {
      "version": "1.2.4",
      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
      "dev": true
    },
    "node_modules/loader-runner": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz",
      "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==",
      "dev": true,
      "engines": {
        "node": ">=6.11.5"
      }
    },
    "node_modules/loader-utils": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
      "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
      "dev": true,
      "dependencies": {
        "big.js": "^5.2.2",
        "emojis-list": "^3.0.0",
        "json5": "^2.1.2"
      },
      "engines": {
        "node": ">=8.9.0"
      }
    },
    "node_modules/locate-path": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
      "dev": true,
      "dependencies": {
        "p-locate": "^4.1.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/lodash": {
      "version": "4.17.21",
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
      "dev": true
    },
    "node_modules/lodash.debounce": {
      "version": "4.0.8",
      "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
      "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
    },
    "node_modules/lodash.memoize": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
      "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
    },
    "node_modules/lodash.throttle": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
      "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
    },
    "node_modules/lodash.uniq": {
      "version": "4.5.0",
      "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
      "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
      "dev": true
    },
    "node_modules/log-symbols": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
      "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
      "dev": true,
      "dependencies": {
        "chalk": "^4.1.0",
        "is-unicode-supported": "^0.1.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/log-symbols/node_modules/ansi-styles": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
      "dev": true,
      "dependencies": {
        "color-convert": "^2.0.1"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
      }
    },
    "node_modules/log-symbols/node_modules/chalk": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
      "dev": true,
      "dependencies": {
        "ansi-styles": "^4.1.0",
        "supports-color": "^7.1.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/chalk/chalk?sponsor=1"
      }
    },
    "node_modules/log-symbols/node_modules/color-convert": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
      "dev": true,
      "dependencies": {
        "color-name": "~1.1.4"
      },
      "engines": {
        "node": ">=7.0.0"
      }
    },
    "node_modules/log-symbols/node_modules/color-name": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
      "dev": true
    },
    "node_modules/log-symbols/node_modules/has-flag": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/log-symbols/node_modules/supports-color": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
      "dev": true,
      "dependencies": {
        "has-flag": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/log4js": {
      "version": "6.3.0",
      "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz",
      "integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==",
      "dev": true,
      "dependencies": {
        "date-format": "^3.0.0",
        "debug": "^4.1.1",
        "flatted": "^2.0.1",
        "rfdc": "^1.1.4",
        "streamroller": "^2.2.4"
      },
      "engines": {
        "node": ">=8.0"
      }
    },
    "node_modules/loglevel": {
      "version": "1.8.0",
      "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz",
      "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==",
      "dev": true,
      "engines": {
        "node": ">= 0.6.0"
      },
      "funding": {
        "type": "tidelift",
        "url": "https://tidelift.com/funding/github/npm/loglevel"
      }
    },
    "node_modules/lru-cache": {
      "version": "6.0.0",
      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
      "dev": true,
      "dependencies": {
        "yallist": "^4.0.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/magic-string": {
      "version": "0.25.7",
      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
      "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
      "dev": true,
      "dependencies": {
        "sourcemap-codec": "^1.4.4"
      }
    },
    "node_modules/make-dir": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
      "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
      "dev": true,
      "dependencies": {
        "semver": "^6.0.0"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/make-dir/node_modules/semver": {
      "version": "6.3.0",
      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
      "dev": true,
      "bin": {
        "semver": "bin/semver.js"
      }
    },
    "node_modules/make-fetch-happen": {
      "version": "9.1.0",
      "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
      "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
      "dev": true,
      "dependencies": {
        "agentkeepalive": "^4.1.3",
        "cacache": "^15.2.0",
        "http-cache-semantics": "^4.1.0",
        "http-proxy-agent": "^4.0.1",
        "https-proxy-agent": "^5.0.0",
        "is-lambda": "^1.0.1",
        "lru-cache": "^6.0.0",
        "minipass": "^3.1.3",
        "minipass-collect": "^1.0.2",
        "minipass-fetch": "^1.3.2",
        "minipass-flush": "^1.0.5",
        "minipass-pipeline": "^1.2.4",
        "negotiator": "^0.6.2",
        "promise-retry": "^2.0.1",
        "socks-proxy-agent": "^6.0.0",
        "ssri": "^8.0.0"
      },
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/map-age-cleaner": {
      "version": "0.1.3",
      "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
      "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
      "dev": true,
      "dependencies": {
        "p-defer": "^1.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/map-cache": {
      "version": "0.2.2",
      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/map-visit": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
      "dev": true,
      "dependencies": {
        "object-visit": "^1.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/mdn-data": {
      "version": "2.0.14",
      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
      "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
      "dev": true
    },
    "node_modules/media-typer": {
      "version": "0.3.0",
      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/mem": {
      "version": "8.1.1",
      "resolved": "https://registry.npmjs.org/mem/-/mem-8.1.1.tgz",
      "integrity": "sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA==",
      "dev": true,
      "dependencies": {
        "map-age-cleaner": "^0.1.3",
        "mimic-fn": "^3.1.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sindresorhus/mem?sponsor=1"
      }
    },
    "node_modules/mem/node_modules/mimic-fn": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz",
      "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/memfs": {
      "version": "3.4.1",
      "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz",
      "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==",
      "dev": true,
      "dependencies": {
        "fs-monkey": "1.0.3"
      },
      "engines": {
        "node": ">= 4.0.0"
      }
    },
    "node_modules/memory-fs": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
      "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
      "dev": true,
      "dependencies": {
        "errno": "^0.1.3",
        "readable-stream": "^2.0.1"
      }
    },
    "node_modules/memory-fs/node_modules/readable-stream": {
      "version": "2.3.7",
      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
      "dev": true,
      "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"
      }
    },
    "node_modules/memory-fs/node_modules/string_decoder": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
      "dev": true,
      "dependencies": {
        "safe-buffer": "~5.1.0"
      }
    },
    "node_modules/merge-descriptors": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
      "dev": true
    },
    "node_modules/merge-source-map": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz",
      "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==",
      "dev": true,
      "dependencies": {
        "source-map": "^0.6.1"
      }
    },
    "node_modules/merge-source-map/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/merge-stream": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
      "dev": true
    },
    "node_modules/merge2": {
      "version": "1.4.1",
      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
      "dev": true,
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/methods": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/micromatch": {
      "version": "4.0.4",
      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
      "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
      "dev": true,
      "dependencies": {
        "braces": "^3.0.1",
        "picomatch": "^2.2.3"
      },
      "engines": {
        "node": ">=8.6"
      }
    },
    "node_modules/mime": {
      "version": "2.6.0",
      "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
      "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
      "dev": true,
      "bin": {
        "mime": "cli.js"
      },
      "engines": {
        "node": ">=4.0.0"
      }
    },
    "node_modules/mime-db": {
      "version": "1.51.0",
      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
      "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/mime-types": {
      "version": "2.1.34",
      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
      "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
      "dev": true,
      "dependencies": {
        "mime-db": "1.51.0"
      },
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/mimic-fn": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/mini-css-extract-plugin": {
      "version": "1.6.2",
      "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz",
      "integrity": "sha512-WhDvO3SjGm40oV5y26GjMJYjd2UMqrLAGKy5YS2/3QKJy2F7jgynuHTir/tgUUOiNQu5saXHdc8reo7YuhhT4Q==",
      "dev": true,
      "dependencies": {
        "loader-utils": "^2.0.0",
        "schema-utils": "^3.0.0",
        "webpack-sources": "^1.1.0"
      },
      "engines": {
        "node": ">= 10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "webpack": "^4.4.0 || ^5.0.0"
      }
    },
    "node_modules/mini-css-extract-plugin/node_modules/ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
      "dev": true,
      "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"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": {
      "version": "3.5.2",
      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
      "dev": true,
      "peerDependencies": {
        "ajv": "^6.9.1"
      }
    },
    "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
      "dev": true
    },
    "node_modules/mini-css-extract-plugin/node_modules/schema-utils": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
      "dev": true,
      "dependencies": {
        "@types/json-schema": "^7.0.8",
        "ajv": "^6.12.5",
        "ajv-keywords": "^3.5.2"
      },
      "engines": {
        "node": ">= 10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      }
    },
    "node_modules/minimalistic-assert": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
      "dev": true
    },
    "node_modules/minimatch": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
      "dev": true,
      "dependencies": {
        "brace-expansion": "^1.1.7"
      },
      "engines": {
        "node": "*"
      }
    },
    "node_modules/minimist": {
      "version": "1.2.5",
      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
      "dev": true
    },
    "node_modules/minipass": {
      "version": "3.1.6",
      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz",
      "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==",
      "dev": true,
      "dependencies": {
        "yallist": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/minipass-collect": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
      "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
      "dev": true,
      "dependencies": {
        "minipass": "^3.0.0"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/minipass-fetch": {
      "version": "1.4.1",
      "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
      "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
      "dev": true,
      "dependencies": {
        "minipass": "^3.1.0",
        "minipass-sized": "^1.0.3",
        "minizlib": "^2.0.0"
      },
      "engines": {
        "node": ">=8"
      },
      "optionalDependencies": {
        "encoding": "^0.1.12"
      }
    },
    "node_modules/minipass-flush": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
      "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
      "dev": true,
      "dependencies": {
        "minipass": "^3.0.0"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/minipass-json-stream": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz",
      "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==",
      "dev": true,
      "dependencies": {
        "jsonparse": "^1.3.1",
        "minipass": "^3.0.0"
      }
    },
    "node_modules/minipass-pipeline": {
      "version": "1.2.4",
      "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
      "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
      "dev": true,
      "dependencies": {
        "minipass": "^3.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/minipass-sized": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
      "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
      "dev": true,
      "dependencies": {
        "minipass": "^3.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/minizlib": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
      "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
      "dev": true,
      "dependencies": {
        "minipass": "^3.0.0",
        "yallist": "^4.0.0"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/mixin-deep": {
      "version": "1.3.2",
      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
      "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
      "dev": true,
      "dependencies": {
        "for-in": "^1.0.2",
        "is-extendable": "^1.0.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/mkdirp": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
      "dev": true,
      "bin": {
        "mkdirp": "bin/cmd.js"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/ms": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
      "dev": true
    },
    "node_modules/multicast-dns": {
      "version": "6.2.3",
      "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
      "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
      "dev": true,
      "dependencies": {
        "dns-packet": "^1.3.1",
        "thunky": "^1.0.2"
      },
      "bin": {
        "multicast-dns": "cli.js"
      }
    },
    "node_modules/multicast-dns-service-types": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
      "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
      "dev": true
    },
    "node_modules/mute-stream": {
      "version": "0.0.8",
      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
      "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
      "dev": true
    },
    "node_modules/nan": {
      "version": "2.15.0",
      "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
      "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
      "dev": true,
      "optional": true
    },
    "node_modules/nanoid": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
      "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
      "dev": true,
      "bin": {
        "nanoid": "bin/nanoid.cjs"
      },
      "engines": {
        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
      }
    },
    "node_modules/nanomatch": {
      "version": "1.2.13",
      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
      "dev": true,
      "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"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/needle": {
      "version": "2.9.1",
      "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz",
      "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==",
      "dev": true,
      "optional": true,
      "dependencies": {
        "debug": "^3.2.6",
        "iconv-lite": "^0.4.4",
        "sax": "^1.2.4"
      },
      "bin": {
        "needle": "bin/needle"
      },
      "engines": {
        "node": ">= 4.4.x"
      }
    },
    "node_modules/needle/node_modules/debug": {
      "version": "3.2.7",
      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
      "dev": true,
      "optional": true,
      "dependencies": {
        "ms": "^2.1.1"
      }
    },
    "node_modules/negotiator": {
      "version": "0.6.2",
      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/neo-async": {
      "version": "2.6.2",
      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
      "dev": true
    },
    "node_modules/nice-try": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
      "dev": true
    },
    "node_modules/node-forge": {
      "version": "0.10.0",
      "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
      "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==",
      "dev": true,
      "engines": {
        "node": ">= 6.0.0"
      }
    },
    "node_modules/node-gyp": {
      "version": "7.1.2",
      "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz",
      "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==",
      "dev": true,
      "dependencies": {
        "env-paths": "^2.2.0",
        "glob": "^7.1.4",
        "graceful-fs": "^4.2.3",
        "nopt": "^5.0.0",
        "npmlog": "^4.1.2",
        "request": "^2.88.2",
        "rimraf": "^3.0.2",
        "semver": "^7.3.2",
        "tar": "^6.0.2",
        "which": "^2.0.2"
      },
      "bin": {
        "node-gyp": "bin/node-gyp.js"
      },
      "engines": {
        "node": ">= 10.12.0"
      }
    },
    "node_modules/node-gyp/node_modules/which": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
      "dev": true,
      "dependencies": {
        "isexe": "^2.0.0"
      },
      "bin": {
        "node-which": "bin/node-which"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/node-releases": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz",
      "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==",
      "dev": true
    },
    "node_modules/nopt": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
      "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
      "dev": true,
      "dependencies": {
        "abbrev": "1"
      },
      "bin": {
        "nopt": "bin/nopt.js"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/normalize-path": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/normalize-range": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
      "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/normalize-url": {
      "version": "6.1.0",
      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
      "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
      "dev": true,
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/npm-bundled": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz",
      "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==",
      "dev": true,
      "dependencies": {
        "npm-normalize-package-bin": "^1.0.1"
      }
    },
    "node_modules/npm-install-checks": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-4.0.0.tgz",
      "integrity": "sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w==",
      "dev": true,
      "dependencies": {
        "semver": "^7.1.1"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/npm-normalize-package-bin": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz",
      "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==",
      "dev": true
    },
    "node_modules/npm-package-arg": {
      "version": "8.1.5",
      "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.5.tgz",
      "integrity": "sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q==",
      "dev": true,
      "dependencies": {
        "hosted-git-info": "^4.0.1",
        "semver": "^7.3.4",
        "validate-npm-package-name": "^3.0.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/npm-packlist": {
      "version": "2.2.2",
      "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-2.2.2.tgz",
      "integrity": "sha512-Jt01acDvJRhJGthnUJVF/w6gumWOZxO7IkpY/lsX9//zqQgnF7OJaxgQXcerd4uQOLu7W5bkb4mChL9mdfm+Zg==",
      "dev": true,
      "dependencies": {
        "glob": "^7.1.6",
        "ignore-walk": "^3.0.3",
        "npm-bundled": "^1.1.1",
        "npm-normalize-package-bin": "^1.0.1"
      },
      "bin": {
        "npm-packlist": "bin/index.js"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/npm-pick-manifest": {
      "version": "6.1.1",
      "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz",
      "integrity": "sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA==",
      "dev": true,
      "dependencies": {
        "npm-install-checks": "^4.0.0",
        "npm-normalize-package-bin": "^1.0.1",
        "npm-package-arg": "^8.1.2",
        "semver": "^7.3.4"
      }
    },
    "node_modules/npm-registry-fetch": {
      "version": "11.0.0",
      "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-11.0.0.tgz",
      "integrity": "sha512-jmlgSxoDNuhAtxUIG6pVwwtz840i994dL14FoNVZisrmZW5kWd63IUTNv1m/hyRSGSqWjCUp/YZlS1BJyNp9XA==",
      "dev": true,
      "dependencies": {
        "make-fetch-happen": "^9.0.1",
        "minipass": "^3.1.3",
        "minipass-fetch": "^1.3.0",
        "minipass-json-stream": "^1.0.1",
        "minizlib": "^2.0.0",
        "npm-package-arg": "^8.0.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/npm-run-path": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
      "dev": true,
      "dependencies": {
        "path-key": "^2.0.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/npmlog": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
      "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
      "dev": true,
      "dependencies": {
        "are-we-there-yet": "~1.1.2",
        "console-control-strings": "~1.1.0",
        "gauge": "~2.7.3",
        "set-blocking": "~2.0.0"
      }
    },
    "node_modules/nth-check": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
      "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
      "dev": true,
      "dependencies": {
        "boolbase": "^1.0.0"
      },
      "funding": {
        "url": "https://github.com/fb55/nth-check?sponsor=1"
      }
    },
    "node_modules/num2fraction": {
      "version": "1.2.2",
      "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
      "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
      "dev": true
    },
    "node_modules/number-is-nan": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/oauth-sign": {
      "version": "0.9.0",
      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
      "dev": true,
      "engines": {
        "node": "*"
      }
    },
    "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=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/object-copy": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
      "dev": true,
      "dependencies": {
        "copy-descriptor": "^0.1.0",
        "define-property": "^0.2.5",
        "kind-of": "^3.0.3"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/object-copy/node_modules/define-property": {
      "version": "0.2.5",
      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
      "dev": true,
      "dependencies": {
        "is-descriptor": "^0.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/object-copy/node_modules/is-accessor-descriptor": {
      "version": "0.1.6",
      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/object-copy/node_modules/is-data-descriptor": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/object-copy/node_modules/is-descriptor": {
      "version": "0.1.6",
      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
      "dev": true,
      "dependencies": {
        "is-accessor-descriptor": "^0.1.6",
        "is-data-descriptor": "^0.1.4",
        "kind-of": "^5.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": {
      "version": "5.1.0",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
      "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/object-copy/node_modules/kind-of": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/object-is": {
      "version": "1.1.5",
      "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
      "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
      "dev": true,
      "dependencies": {
        "call-bind": "^1.0.2",
        "define-properties": "^1.1.3"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/object-keys": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
      "dev": true,
      "engines": {
        "node": ">= 0.4"
      }
    },
    "node_modules/object-visit": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
      "dev": true,
      "dependencies": {
        "isobject": "^3.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/object.assign": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
      "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
      "dev": true,
      "dependencies": {
        "call-bind": "^1.0.0",
        "define-properties": "^1.1.3",
        "has-symbols": "^1.0.1",
        "object-keys": "^1.1.1"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/object.pick": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
      "dev": true,
      "dependencies": {
        "isobject": "^3.0.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/obuf": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
      "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
      "dev": true
    },
    "node_modules/on-finished": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
      "dev": true,
      "dependencies": {
        "ee-first": "1.1.1"
      },
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/on-headers": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
      "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
      "dev": true,
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/once": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
      "dev": true,
      "dependencies": {
        "wrappy": "1"
      }
    },
    "node_modules/onetime": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
      "dev": true,
      "dependencies": {
        "mimic-fn": "^2.1.0"
      },
      "engines": {
        "node": ">=6"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/open": {
      "version": "8.2.1",
      "resolved": "https://registry.npmjs.org/open/-/open-8.2.1.tgz",
      "integrity": "sha512-rXILpcQlkF/QuFez2BJDf3GsqpjGKbkUUToAIGo9A0Q6ZkoSGogZJulrUdwRkrAsoQvoZsrjCYt8+zblOk7JQQ==",
      "dev": true,
      "dependencies": {
        "define-lazy-prop": "^2.0.0",
        "is-docker": "^2.1.1",
        "is-wsl": "^2.2.0"
      },
      "engines": {
        "node": ">=12"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/opn": {
      "version": "5.5.0",
      "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
      "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==",
      "dev": true,
      "dependencies": {
        "is-wsl": "^1.1.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/opn/node_modules/is-wsl": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
      "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/ora": {
      "version": "5.4.1",
      "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
      "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
      "dev": true,
      "dependencies": {
        "bl": "^4.1.0",
        "chalk": "^4.1.0",
        "cli-cursor": "^3.1.0",
        "cli-spinners": "^2.5.0",
        "is-interactive": "^1.0.0",
        "is-unicode-supported": "^0.1.0",
        "log-symbols": "^4.1.0",
        "strip-ansi": "^6.0.0",
        "wcwidth": "^1.0.1"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/ora/node_modules/ansi-styles": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
      "dev": true,
      "dependencies": {
        "color-convert": "^2.0.1"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
      }
    },
    "node_modules/ora/node_modules/chalk": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
      "dev": true,
      "dependencies": {
        "ansi-styles": "^4.1.0",
        "supports-color": "^7.1.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/chalk/chalk?sponsor=1"
      }
    },
    "node_modules/ora/node_modules/color-convert": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
      "dev": true,
      "dependencies": {
        "color-name": "~1.1.4"
      },
      "engines": {
        "node": ">=7.0.0"
      }
    },
    "node_modules/ora/node_modules/color-name": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
      "dev": true
    },
    "node_modules/ora/node_modules/has-flag": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/ora/node_modules/supports-color": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
      "dev": true,
      "dependencies": {
        "has-flag": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/original": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
      "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
      "dev": true,
      "dependencies": {
        "url-parse": "^1.4.3"
      }
    },
    "node_modules/os-tmpdir": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/p-defer": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
      "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/p-finally": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/p-limit": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
      "dev": true,
      "dependencies": {
        "yocto-queue": "^0.1.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/p-locate": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
      "dev": true,
      "dependencies": {
        "p-limit": "^2.2.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/p-locate/node_modules/p-limit": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
      "dev": true,
      "dependencies": {
        "p-try": "^2.0.0"
      },
      "engines": {
        "node": ">=6"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/p-map": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
      "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
      "dev": true,
      "dependencies": {
        "aggregate-error": "^3.0.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/p-retry": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz",
      "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==",
      "dev": true,
      "dependencies": {
        "retry": "^0.12.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/p-try": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/pacote": {
      "version": "11.3.4",
      "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.3.4.tgz",
      "integrity": "sha512-RfahPCunM9GI7ryJV/zY0bWQiokZyLqaSNHXtbNSoLb7bwTvBbJBEyCJ01KWs4j1Gj7GmX8crYXQ1sNX6P2VKA==",
      "dev": true,
      "dependencies": {
        "@npmcli/git": "^2.0.1",
        "@npmcli/installed-package-contents": "^1.0.6",
        "@npmcli/promise-spawn": "^1.2.0",
        "@npmcli/run-script": "^1.8.2",
        "cacache": "^15.0.5",
        "chownr": "^2.0.0",
        "fs-minipass": "^2.1.0",
        "infer-owner": "^1.0.4",
        "minipass": "^3.1.3",
        "mkdirp": "^1.0.3",
        "npm-package-arg": "^8.0.1",
        "npm-packlist": "^2.1.4",
        "npm-pick-manifest": "^6.0.0",
        "npm-registry-fetch": "^11.0.0",
        "promise-retry": "^2.0.1",
        "read-package-json-fast": "^2.0.1",
        "rimraf": "^3.0.2",
        "ssri": "^8.0.1",
        "tar": "^6.1.0"
      },
      "bin": {
        "pacote": "lib/bin.js"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/parent-module": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
      "dev": true,
      "dependencies": {
        "callsites": "^3.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/parse-json": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
      "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
      "dev": true,
      "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"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/parse-node-version": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
      "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
      "dev": true,
      "engines": {
        "node": ">= 0.10"
      }
    },
    "node_modules/parse5": {
      "version": "5.1.1",
      "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
      "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
      "optional": true
    },
    "node_modules/parse5-html-rewriting-stream": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-6.0.1.tgz",
      "integrity": "sha512-vwLQzynJVEfUlURxgnf51yAJDQTtVpNyGD8tKi2Za7m+akukNHxCcUQMAa/mUGLhCeicFdpy7Tlvj8ZNKadprg==",
      "dev": true,
      "dependencies": {
        "parse5": "^6.0.1",
        "parse5-sax-parser": "^6.0.1"
      }
    },
    "node_modules/parse5-html-rewriting-stream/node_modules/parse5": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
      "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
      "dev": true
    },
    "node_modules/parse5-htmlparser2-tree-adapter": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
      "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
      "dev": true,
      "dependencies": {
        "parse5": "^6.0.1"
      }
    },
    "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
      "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
      "dev": true
    },
    "node_modules/parse5-sax-parser": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-6.0.1.tgz",
      "integrity": "sha512-kXX+5S81lgESA0LsDuGjAlBybImAChYRMT+/uKCEXFBFOeEhS52qUCydGhU3qLRD8D9DVjaUo821WK7DM4iCeg==",
      "dev": true,
      "dependencies": {
        "parse5": "^6.0.1"
      }
    },
    "node_modules/parse5-sax-parser/node_modules/parse5": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
      "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
      "dev": true
    },
    "node_modules/parseurl": {
      "version": "1.3.3",
      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
      "dev": true,
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/pascalcase": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/path-dirname": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
      "dev": true
    },
    "node_modules/path-exists": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/path-is-absolute": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/path-is-inside": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
      "dev": true
    },
    "node_modules/path-key": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/path-parse": {
      "version": "1.0.7",
      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
      "dev": true
    },
    "node_modules/path-to-regexp": {
      "version": "0.1.7",
      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
      "dev": true
    },
    "node_modules/path-type": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/performance-now": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
      "dev": true
    },
    "node_modules/picocolors": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
      "dev": true
    },
    "node_modules/picomatch": {
      "version": "2.3.1",
      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
      "dev": true,
      "engines": {
        "node": ">=8.6"
      },
      "funding": {
        "url": "https://github.com/sponsors/jonschlinkert"
      }
    },
    "node_modules/pify": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/pinkie": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/pinkie-promise": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
      "dev": true,
      "dependencies": {
        "pinkie": "^2.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/pkg-dir": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
      "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
      "dev": true,
      "dependencies": {
        "find-up": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/portfinder": {
      "version": "1.0.28",
      "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
      "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==",
      "dev": true,
      "dependencies": {
        "async": "^2.6.2",
        "debug": "^3.1.1",
        "mkdirp": "^0.5.5"
      },
      "engines": {
        "node": ">= 0.12.0"
      }
    },
    "node_modules/portfinder/node_modules/debug": {
      "version": "3.2.7",
      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
      "dev": true,
      "dependencies": {
        "ms": "^2.1.1"
      }
    },
    "node_modules/portfinder/node_modules/mkdirp": {
      "version": "0.5.5",
      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
      "dev": true,
      "dependencies": {
        "minimist": "^1.2.5"
      },
      "bin": {
        "mkdirp": "bin/cmd.js"
      }
    },
    "node_modules/posix-character-classes": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss": {
      "version": "8.3.5",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.5.tgz",
      "integrity": "sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA==",
      "dev": true,
      "dependencies": {
        "colorette": "^1.2.2",
        "nanoid": "^3.1.23",
        "source-map-js": "^0.6.2"
      },
      "engines": {
        "node": "^10 || ^12 || >=14"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-attribute-case-insensitive": {
      "version": "4.0.2",
      "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz",
      "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2",
        "postcss-selector-parser": "^6.0.2"
      }
    },
    "node_modules/postcss-attribute-case-insensitive/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-attribute-case-insensitive/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-attribute-case-insensitive/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-calc": {
      "version": "8.2.2",
      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.2.tgz",
      "integrity": "sha512-B5R0UeB4zLJvxNt1FVCaDZULdzsKLPc6FhjFJ+xwFiq7VG4i9cuaJLxVjNtExNK8ocm3n2o4unXXLiVX1SCqxA==",
      "dev": true,
      "dependencies": {
        "postcss-selector-parser": "^6.0.2",
        "postcss-value-parser": "^4.0.2"
      },
      "peerDependencies": {
        "postcss": "^8.2.2"
      }
    },
    "node_modules/postcss-color-functional-notation": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz",
      "integrity": "sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2",
        "postcss-values-parser": "^2.0.0"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-color-functional-notation/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-color-functional-notation/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-color-functional-notation/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-color-gray": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz",
      "integrity": "sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==",
      "dev": true,
      "dependencies": {
        "@csstools/convert-colors": "^1.4.0",
        "postcss": "^7.0.5",
        "postcss-values-parser": "^2.0.0"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-color-gray/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-color-gray/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-color-gray/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-color-hex-alpha": {
      "version": "5.0.3",
      "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz",
      "integrity": "sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.14",
        "postcss-values-parser": "^2.0.1"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-color-hex-alpha/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-color-hex-alpha/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-color-hex-alpha/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-color-mod-function": {
      "version": "3.0.3",
      "resolved": "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz",
      "integrity": "sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==",
      "dev": true,
      "dependencies": {
        "@csstools/convert-colors": "^1.4.0",
        "postcss": "^7.0.2",
        "postcss-values-parser": "^2.0.0"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-color-mod-function/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-color-mod-function/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-color-mod-function/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-color-rebeccapurple": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz",
      "integrity": "sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2",
        "postcss-values-parser": "^2.0.0"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-color-rebeccapurple/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-color-rebeccapurple/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-color-rebeccapurple/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-colormin": {
      "version": "5.2.3",
      "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.2.3.tgz",
      "integrity": "sha512-dra4xoAjub2wha6RUXAgadHEn2lGxbj8drhFcIGLOMn914Eu7DkPUurugDXgstwttCYkJtZ/+PkWRWdp3UHRIA==",
      "dev": true,
      "dependencies": {
        "browserslist": "^4.16.6",
        "caniuse-api": "^3.0.0",
        "colord": "^2.9.1",
        "postcss-value-parser": "^4.2.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-convert-values": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.2.tgz",
      "integrity": "sha512-KQ04E2yadmfa1LqXm7UIDwW1ftxU/QWZmz6NKnHnUvJ3LEYbbcX6i329f/ig+WnEByHegulocXrECaZGLpL8Zg==",
      "dev": true,
      "dependencies": {
        "postcss-value-parser": "^4.1.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-custom-media": {
      "version": "7.0.8",
      "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz",
      "integrity": "sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.14"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-custom-media/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-custom-media/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-custom-media/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-custom-properties": {
      "version": "8.0.11",
      "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz",
      "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.17",
        "postcss-values-parser": "^2.0.1"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-custom-properties/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-custom-properties/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-custom-properties/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-custom-selectors": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz",
      "integrity": "sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2",
        "postcss-selector-parser": "^5.0.0-rc.3"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-custom-selectors/node_modules/cssesc": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
      "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
      "dev": true,
      "bin": {
        "cssesc": "bin/cssesc"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/postcss-custom-selectors/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-custom-selectors/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
      "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
      "dev": true,
      "dependencies": {
        "cssesc": "^2.0.0",
        "indexes-of": "^1.0.1",
        "uniq": "^1.0.1"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/postcss-custom-selectors/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-dir-pseudo-class": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz",
      "integrity": "sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2",
        "postcss-selector-parser": "^5.0.0-rc.3"
      },
      "engines": {
        "node": ">=4.0.0"
      }
    },
    "node_modules/postcss-dir-pseudo-class/node_modules/cssesc": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
      "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
      "dev": true,
      "bin": {
        "cssesc": "bin/cssesc"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/postcss-dir-pseudo-class/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-dir-pseudo-class/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
      "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
      "dev": true,
      "dependencies": {
        "cssesc": "^2.0.0",
        "indexes-of": "^1.0.1",
        "uniq": "^1.0.1"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/postcss-dir-pseudo-class/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-discard-comments": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz",
      "integrity": "sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg==",
      "dev": true,
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-discard-duplicates": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz",
      "integrity": "sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA==",
      "dev": true,
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-discard-empty": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz",
      "integrity": "sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw==",
      "dev": true,
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-discard-overridden": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.2.tgz",
      "integrity": "sha512-+56BLP6NSSUuWUXjRgAQuho1p5xs/hU5Sw7+xt9S3JSg+7R6+WMGnJW7Hre/6tTuZ2xiXMB42ObkiZJ2hy/Pew==",
      "dev": true,
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-double-position-gradients": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz",
      "integrity": "sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.5",
        "postcss-values-parser": "^2.0.0"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-double-position-gradients/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-double-position-gradients/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-double-position-gradients/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-env-function": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz",
      "integrity": "sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2",
        "postcss-values-parser": "^2.0.0"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-env-function/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-env-function/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-env-function/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-focus-visible": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz",
      "integrity": "sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-focus-visible/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-focus-visible/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-focus-visible/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-focus-within": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz",
      "integrity": "sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-focus-within/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-focus-within/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-focus-within/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-font-variant": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz",
      "integrity": "sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2"
      }
    },
    "node_modules/postcss-font-variant/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-font-variant/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-font-variant/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-gap-properties": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz",
      "integrity": "sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-gap-properties/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-gap-properties/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-gap-properties/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-image-set-function": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz",
      "integrity": "sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2",
        "postcss-values-parser": "^2.0.0"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-image-set-function/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-image-set-function/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-image-set-function/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-import": {
      "version": "14.0.2",
      "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.0.2.tgz",
      "integrity": "sha512-BJ2pVK4KhUyMcqjuKs9RijV5tatNzNa73e/32aBVE/ejYPe37iH+6vAu9WvqUkB5OAYgLHzbSvzHnorybJCm9g==",
      "dev": true,
      "dependencies": {
        "postcss-value-parser": "^4.0.0",
        "read-cache": "^1.0.0",
        "resolve": "^1.1.7"
      },
      "engines": {
        "node": ">=10.0.0"
      },
      "peerDependencies": {
        "postcss": "^8.0.0"
      }
    },
    "node_modules/postcss-initial": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.4.tgz",
      "integrity": "sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2"
      }
    },
    "node_modules/postcss-initial/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-initial/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-initial/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-lab-function": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz",
      "integrity": "sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==",
      "dev": true,
      "dependencies": {
        "@csstools/convert-colors": "^1.4.0",
        "postcss": "^7.0.2",
        "postcss-values-parser": "^2.0.0"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-lab-function/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-lab-function/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-lab-function/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-loader": {
      "version": "6.1.0",
      "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.1.0.tgz",
      "integrity": "sha512-yA/cXBfACkthZNA2hQxOnaReVfQ6uLmvbEDQzNafpbK40URZJvP/28dL1DG174Gvz3ptkkHbbwDBCh+gXR94CA==",
      "dev": true,
      "dependencies": {
        "cosmiconfig": "^7.0.0",
        "klona": "^2.0.4",
        "semver": "^7.3.5"
      },
      "engines": {
        "node": ">= 12.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "postcss": "^7.0.0 || ^8.0.1",
        "webpack": "^5.0.0"
      }
    },
    "node_modules/postcss-logical": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz",
      "integrity": "sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-logical/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-logical/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-logical/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-media-minmax": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz",
      "integrity": "sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-media-minmax/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-media-minmax/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-media-minmax/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-merge-longhand": {
      "version": "5.0.4",
      "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.4.tgz",
      "integrity": "sha512-2lZrOVD+d81aoYkZDpWu6+3dTAAGkCKbV5DoRhnIR7KOULVrI/R7bcMjhrH9KTRy6iiHKqmtG+n/MMj1WmqHFw==",
      "dev": true,
      "dependencies": {
        "postcss-value-parser": "^4.1.0",
        "stylehacks": "^5.0.1"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-merge-rules": {
      "version": "5.0.4",
      "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.4.tgz",
      "integrity": "sha512-yOj7bW3NxlQxaERBB0lEY1sH5y+RzevjbdH4DBJurjKERNpknRByFNdNe+V72i5pIZL12woM9uGdS5xbSB+kDQ==",
      "dev": true,
      "dependencies": {
        "browserslist": "^4.16.6",
        "caniuse-api": "^3.0.0",
        "cssnano-utils": "^3.0.0",
        "postcss-selector-parser": "^6.0.5"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-minify-font-values": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.2.tgz",
      "integrity": "sha512-R6MJZryq28Cw0AmnyhXrM7naqJZZLoa1paBltIzh2wM7yb4D45TLur+eubTQ4jCmZU9SGeZdWsc5KcSoqTMeTg==",
      "dev": true,
      "dependencies": {
        "postcss-value-parser": "^4.2.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-minify-gradients": {
      "version": "5.0.4",
      "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.4.tgz",
      "integrity": "sha512-RVwZA7NC4R4J76u8X0Q0j+J7ItKUWAeBUJ8oEEZWmtv3Xoh19uNJaJwzNpsydQjk6PkuhRrK+YwwMf+c+68EYg==",
      "dev": true,
      "dependencies": {
        "colord": "^2.9.1",
        "cssnano-utils": "^3.0.0",
        "postcss-value-parser": "^4.2.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-minify-params": {
      "version": "5.0.3",
      "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.3.tgz",
      "integrity": "sha512-NY92FUikE+wralaiVexFd5gwb7oJTIDhgTNeIw89i1Ymsgt4RWiPXfz3bg7hDy4NL6gepcThJwOYNtZO/eNi7Q==",
      "dev": true,
      "dependencies": {
        "alphanum-sort": "^1.0.2",
        "browserslist": "^4.16.6",
        "cssnano-utils": "^3.0.0",
        "postcss-value-parser": "^4.2.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-minify-selectors": {
      "version": "5.1.1",
      "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.1.1.tgz",
      "integrity": "sha512-TOzqOPXt91O2luJInaVPiivh90a2SIK5Nf1Ea7yEIM/5w+XA5BGrZGUSW8aEx9pJ/oNj7ZJBhjvigSiBV+bC1Q==",
      "dev": true,
      "dependencies": {
        "alphanum-sort": "^1.0.2",
        "postcss-selector-parser": "^6.0.5"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-modules-extract-imports": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
      "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
      "dev": true,
      "engines": {
        "node": "^10 || ^12 || >= 14"
      },
      "peerDependencies": {
        "postcss": "^8.1.0"
      }
    },
    "node_modules/postcss-modules-local-by-default": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz",
      "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==",
      "dev": true,
      "dependencies": {
        "icss-utils": "^5.0.0",
        "postcss-selector-parser": "^6.0.2",
        "postcss-value-parser": "^4.1.0"
      },
      "engines": {
        "node": "^10 || ^12 || >= 14"
      },
      "peerDependencies": {
        "postcss": "^8.1.0"
      }
    },
    "node_modules/postcss-modules-scope": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz",
      "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==",
      "dev": true,
      "dependencies": {
        "postcss-selector-parser": "^6.0.4"
      },
      "engines": {
        "node": "^10 || ^12 || >= 14"
      },
      "peerDependencies": {
        "postcss": "^8.1.0"
      }
    },
    "node_modules/postcss-modules-values": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
      "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
      "dev": true,
      "dependencies": {
        "icss-utils": "^5.0.0"
      },
      "engines": {
        "node": "^10 || ^12 || >= 14"
      },
      "peerDependencies": {
        "postcss": "^8.1.0"
      }
    },
    "node_modules/postcss-nesting": {
      "version": "7.0.1",
      "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz",
      "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-nesting/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-nesting/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-nesting/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-normalize-charset": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz",
      "integrity": "sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg==",
      "dev": true,
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-normalize-display-values": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.2.tgz",
      "integrity": "sha512-RxXoJPUR0shSjkMMzgEZDjGPrgXUVYyWA/YwQRicb48H15OClPuaDR7tYokLAlGZ2tCSENEN5WxjgxSD5m4cUw==",
      "dev": true,
      "dependencies": {
        "postcss-value-parser": "^4.2.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-normalize-positions": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.2.tgz",
      "integrity": "sha512-tqghWFVDp2btqFg1gYob1etPNxXLNh3uVeWgZE2AQGh6b2F8AK2Gj36v5Vhyh+APwIzNjmt6jwZ9pTBP+/OM8g==",
      "dev": true,
      "dependencies": {
        "postcss-value-parser": "^4.2.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-normalize-repeat-style": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.2.tgz",
      "integrity": "sha512-/rIZn8X9bBzC7KvY4iKUhXUGW3MmbXwfPF23jC9wT9xTi7kAvgj8sEgwxjixBmoL6MVa4WOgxNz2hAR6wTK8tw==",
      "dev": true,
      "dependencies": {
        "postcss-value-parser": "^4.2.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-normalize-string": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.2.tgz",
      "integrity": "sha512-zaI1yzwL+a/FkIzUWMQoH25YwCYxi917J4pYm1nRXtdgiCdnlTkx5eRzqWEC64HtRa06WCJ9TIutpb6GmW4gFw==",
      "dev": true,
      "dependencies": {
        "postcss-value-parser": "^4.2.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-normalize-timing-functions": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.2.tgz",
      "integrity": "sha512-Ao0PP6MoYsRU1LxeVUW740ioknvdIUmfr6uAA3xWlQJ9s69/Tupy8qwhuKG3xWfl+KvLMAP9p2WXF9cwuk/7Bg==",
      "dev": true,
      "dependencies": {
        "postcss-value-parser": "^4.2.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-normalize-unicode": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.2.tgz",
      "integrity": "sha512-3y/V+vjZ19HNcTizeqwrbZSUsE69ZMRHfiiyLAJb7C7hJtYmM4Gsbajy7gKagu97E8q5rlS9k8FhojA8cpGhWw==",
      "dev": true,
      "dependencies": {
        "browserslist": "^4.16.6",
        "postcss-value-parser": "^4.2.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-normalize-url": {
      "version": "5.0.4",
      "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.4.tgz",
      "integrity": "sha512-cNj3RzK2pgQQyNp7dzq0dqpUpQ/wYtdDZM3DepPmFjCmYIfceuD9VIAcOdvrNetjIU65g1B4uwdP/Krf6AFdXg==",
      "dev": true,
      "dependencies": {
        "normalize-url": "^6.0.1",
        "postcss-value-parser": "^4.2.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-normalize-whitespace": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.2.tgz",
      "integrity": "sha512-CXBx+9fVlzSgbk0IXA/dcZn9lXixnQRndnsPC5ht3HxlQ1bVh77KQDL1GffJx1LTzzfae8ftMulsjYmO2yegxA==",
      "dev": true,
      "dependencies": {
        "postcss-value-parser": "^4.2.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-ordered-values": {
      "version": "5.0.3",
      "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.3.tgz",
      "integrity": "sha512-T9pDS+P9bWeFvqivXd5ACzQmrCmHjv3ZP+djn8E1UZY7iK79pFSm7i3WbKw2VSmFmdbMm8sQ12OPcNpzBo3Z2w==",
      "dev": true,
      "dependencies": {
        "cssnano-utils": "^3.0.0",
        "postcss-value-parser": "^4.2.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-overflow-shorthand": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz",
      "integrity": "sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-overflow-shorthand/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-overflow-shorthand/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-overflow-shorthand/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-page-break": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz",
      "integrity": "sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2"
      }
    },
    "node_modules/postcss-page-break/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-page-break/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-page-break/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-place": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz",
      "integrity": "sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2",
        "postcss-values-parser": "^2.0.0"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-place/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-place/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-place/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-preset-env": {
      "version": "6.7.0",
      "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz",
      "integrity": "sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==",
      "dev": true,
      "dependencies": {
        "autoprefixer": "^9.6.1",
        "browserslist": "^4.6.4",
        "caniuse-lite": "^1.0.30000981",
        "css-blank-pseudo": "^0.1.4",
        "css-has-pseudo": "^0.10.0",
        "css-prefers-color-scheme": "^3.1.1",
        "cssdb": "^4.4.0",
        "postcss": "^7.0.17",
        "postcss-attribute-case-insensitive": "^4.0.1",
        "postcss-color-functional-notation": "^2.0.1",
        "postcss-color-gray": "^5.0.0",
        "postcss-color-hex-alpha": "^5.0.3",
        "postcss-color-mod-function": "^3.0.3",
        "postcss-color-rebeccapurple": "^4.0.1",
        "postcss-custom-media": "^7.0.8",
        "postcss-custom-properties": "^8.0.11",
        "postcss-custom-selectors": "^5.1.2",
        "postcss-dir-pseudo-class": "^5.0.0",
        "postcss-double-position-gradients": "^1.0.0",
        "postcss-env-function": "^2.0.2",
        "postcss-focus-visible": "^4.0.0",
        "postcss-focus-within": "^3.0.0",
        "postcss-font-variant": "^4.0.0",
        "postcss-gap-properties": "^2.0.0",
        "postcss-image-set-function": "^3.0.1",
        "postcss-initial": "^3.0.0",
        "postcss-lab-function": "^2.0.1",
        "postcss-logical": "^3.0.0",
        "postcss-media-minmax": "^4.0.0",
        "postcss-nesting": "^7.0.0",
        "postcss-overflow-shorthand": "^2.0.0",
        "postcss-page-break": "^2.0.0",
        "postcss-place": "^4.0.1",
        "postcss-pseudo-class-any-link": "^6.0.0",
        "postcss-replace-overflow-wrap": "^3.0.0",
        "postcss-selector-matches": "^4.0.0",
        "postcss-selector-not": "^4.0.0"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-preset-env/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-preset-env/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-preset-env/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-pseudo-class-any-link": {
      "version": "6.0.0",
      "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz",
      "integrity": "sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2",
        "postcss-selector-parser": "^5.0.0-rc.3"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/postcss-pseudo-class-any-link/node_modules/cssesc": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
      "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
      "dev": true,
      "bin": {
        "cssesc": "bin/cssesc"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/postcss-pseudo-class-any-link/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-pseudo-class-any-link/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
      "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
      "dev": true,
      "dependencies": {
        "cssesc": "^2.0.0",
        "indexes-of": "^1.0.1",
        "uniq": "^1.0.1"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/postcss-pseudo-class-any-link/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-reduce-initial": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.2.tgz",
      "integrity": "sha512-v/kbAAQ+S1V5v9TJvbGkV98V2ERPdU6XvMcKMjqAlYiJ2NtsHGlKYLPjWWcXlaTKNxooId7BGxeraK8qXvzKtw==",
      "dev": true,
      "dependencies": {
        "browserslist": "^4.16.6",
        "caniuse-api": "^3.0.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-reduce-transforms": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.2.tgz",
      "integrity": "sha512-25HeDeFsgiPSUx69jJXZn8I06tMxLQJJNF5h7i9gsUg8iP4KOOJ8EX8fj3seeoLt3SLU2YDD6UPnDYVGUO7DEA==",
      "dev": true,
      "dependencies": {
        "postcss-value-parser": "^4.2.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-replace-overflow-wrap": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz",
      "integrity": "sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==",
      "dev": true,
      "dependencies": {
        "postcss": "^7.0.2"
      }
    },
    "node_modules/postcss-replace-overflow-wrap/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-replace-overflow-wrap/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-replace-overflow-wrap/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-selector-matches": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz",
      "integrity": "sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==",
      "dev": true,
      "dependencies": {
        "balanced-match": "^1.0.0",
        "postcss": "^7.0.2"
      }
    },
    "node_modules/postcss-selector-matches/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-selector-matches/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-selector-matches/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-selector-not": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz",
      "integrity": "sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ==",
      "dev": true,
      "dependencies": {
        "balanced-match": "^1.0.0",
        "postcss": "^7.0.2"
      }
    },
    "node_modules/postcss-selector-not/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/postcss-selector-not/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/postcss-selector-not/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/postcss-selector-parser": {
      "version": "6.0.8",
      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz",
      "integrity": "sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ==",
      "dev": true,
      "dependencies": {
        "cssesc": "^3.0.0",
        "util-deprecate": "^1.0.2"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/postcss-svgo": {
      "version": "5.0.3",
      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.3.tgz",
      "integrity": "sha512-41XZUA1wNDAZrQ3XgWREL/M2zSw8LJPvb5ZWivljBsUQAGoEKMYm6okHsTjJxKYI4M75RQEH4KYlEM52VwdXVA==",
      "dev": true,
      "dependencies": {
        "postcss-value-parser": "^4.1.0",
        "svgo": "^2.7.0"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-unique-selectors": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.2.tgz",
      "integrity": "sha512-w3zBVlrtZm7loQWRPVC0yjUwwpty7OM6DnEHkxcSQXO1bMS3RJ+JUS5LFMSDZHJcvGsRwhZinCWVqn8Kej4EDA==",
      "dev": true,
      "dependencies": {
        "alphanum-sort": "^1.0.2",
        "postcss-selector-parser": "^6.0.5"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/postcss-value-parser": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
      "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
      "dev": true
    },
    "node_modules/postcss-values-parser": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz",
      "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==",
      "dev": true,
      "dependencies": {
        "flatten": "^1.0.2",
        "indexes-of": "^1.0.1",
        "uniq": "^1.0.1"
      },
      "engines": {
        "node": ">=6.14.4"
      }
    },
    "node_modules/pretty-bytes": {
      "version": "5.6.0",
      "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
      "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
      "dev": true,
      "engines": {
        "node": ">=6"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/process-nextick-args": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
      "dev": true
    },
    "node_modules/promise-inflight": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
      "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
      "dev": true
    },
    "node_modules/promise-retry": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
      "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
      "dev": true,
      "dependencies": {
        "err-code": "^2.0.2",
        "retry": "^0.12.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/proxy-addr": {
      "version": "2.0.7",
      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
      "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
      "dev": true,
      "dependencies": {
        "forwarded": "0.2.0",
        "ipaddr.js": "1.9.1"
      },
      "engines": {
        "node": ">= 0.10"
      }
    },
    "node_modules/prr": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
      "dev": true
    },
    "node_modules/psl": {
      "version": "1.8.0",
      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
      "dev": true
    },
    "node_modules/pump": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
      "dev": true,
      "dependencies": {
        "end-of-stream": "^1.1.0",
        "once": "^1.3.1"
      }
    },
    "node_modules/punycode": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/qjobs": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
      "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
      "dev": true,
      "engines": {
        "node": ">=0.9"
      }
    },
    "node_modules/qs": {
      "version": "6.9.6",
      "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz",
      "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==",
      "dev": true,
      "engines": {
        "node": ">=0.6"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/querystring": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
      "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
      "dev": true,
      "engines": {
        "node": ">=0.4.x"
      }
    },
    "node_modules/querystringify": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
      "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
      "dev": true
    },
    "node_modules/queue-microtask": {
      "version": "1.2.3",
      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
      "dev": true,
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ]
    },
    "node_modules/randombytes": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
      "dev": true,
      "dependencies": {
        "safe-buffer": "^5.1.0"
      }
    },
    "node_modules/range-parser": {
      "version": "1.2.1",
      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/raw-body": {
      "version": "2.4.2",
      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz",
      "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==",
      "dev": true,
      "dependencies": {
        "bytes": "3.1.1",
        "http-errors": "1.8.1",
        "iconv-lite": "0.4.24",
        "unpipe": "1.0.0"
      },
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/raw-loader": {
      "version": "4.0.2",
      "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz",
      "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==",
      "dev": true,
      "dependencies": {
        "loader-utils": "^2.0.0",
        "schema-utils": "^3.0.0"
      },
      "engines": {
        "node": ">= 10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "webpack": "^4.0.0 || ^5.0.0"
      }
    },
    "node_modules/raw-loader/node_modules/ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
      "dev": true,
      "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"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/raw-loader/node_modules/ajv-keywords": {
      "version": "3.5.2",
      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
      "dev": true,
      "peerDependencies": {
        "ajv": "^6.9.1"
      }
    },
    "node_modules/raw-loader/node_modules/json-schema-traverse": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
      "dev": true
    },
    "node_modules/raw-loader/node_modules/schema-utils": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
      "dev": true,
      "dependencies": {
        "@types/json-schema": "^7.0.8",
        "ajv": "^6.12.5",
        "ajv-keywords": "^3.5.2"
      },
      "engines": {
        "node": ">= 10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      }
    },
    "node_modules/read-cache": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
      "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
      "dev": true,
      "dependencies": {
        "pify": "^2.3.0"
      }
    },
    "node_modules/read-package-json-fast": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz",
      "integrity": "sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ==",
      "dev": true,
      "dependencies": {
        "json-parse-even-better-errors": "^2.3.0",
        "npm-normalize-package-bin": "^1.0.1"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/readable-stream": {
      "version": "3.6.0",
      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
      "dev": true,
      "dependencies": {
        "inherits": "^2.0.3",
        "string_decoder": "^1.1.1",
        "util-deprecate": "^1.0.1"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/readdirp": {
      "version": "3.6.0",
      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
      "dev": true,
      "dependencies": {
        "picomatch": "^2.2.1"
      },
      "engines": {
        "node": ">=8.10.0"
      }
    },
    "node_modules/reflect-metadata": {
      "version": "0.1.13",
      "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
      "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==",
      "dev": true
    },
    "node_modules/regenerate": {
      "version": "1.4.2",
      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
      "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
      "dev": true
    },
    "node_modules/regenerate-unicode-properties": {
      "version": "9.0.0",
      "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz",
      "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==",
      "dev": true,
      "dependencies": {
        "regenerate": "^1.4.2"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/regenerator-runtime": {
      "version": "0.13.7",
      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
      "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
      "dev": true
    },
    "node_modules/regenerator-transform": {
      "version": "0.14.5",
      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz",
      "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==",
      "dev": true,
      "dependencies": {
        "@babel/runtime": "^7.8.4"
      }
    },
    "node_modules/regex-not": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
      "dev": true,
      "dependencies": {
        "extend-shallow": "^3.0.2",
        "safe-regex": "^1.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/regex-parser": {
      "version": "2.2.11",
      "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz",
      "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==",
      "dev": true
    },
    "node_modules/regexp.prototype.flags": {
      "version": "1.4.1",
      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz",
      "integrity": "sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ==",
      "dev": true,
      "dependencies": {
        "call-bind": "^1.0.2",
        "define-properties": "^1.1.3"
      },
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/regexpu-core": {
      "version": "4.8.0",
      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz",
      "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==",
      "dev": true,
      "dependencies": {
        "regenerate": "^1.4.2",
        "regenerate-unicode-properties": "^9.0.0",
        "regjsgen": "^0.5.2",
        "regjsparser": "^0.7.0",
        "unicode-match-property-ecmascript": "^2.0.0",
        "unicode-match-property-value-ecmascript": "^2.0.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/regjsgen": {
      "version": "0.5.2",
      "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
      "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==",
      "dev": true
    },
    "node_modules/regjsparser": {
      "version": "0.7.0",
      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz",
      "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==",
      "dev": true,
      "dependencies": {
        "jsesc": "~0.5.0"
      },
      "bin": {
        "regjsparser": "bin/parser"
      }
    },
    "node_modules/regjsparser/node_modules/jsesc": {
      "version": "0.5.0",
      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
      "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
      "dev": true,
      "bin": {
        "jsesc": "bin/jsesc"
      }
    },
    "node_modules/remove-trailing-separator": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
      "dev": true
    },
    "node_modules/repeat-element": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz",
      "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/repeat-string": {
      "version": "1.6.1",
      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
      "dev": true,
      "engines": {
        "node": ">=0.10"
      }
    },
    "node_modules/request": {
      "version": "2.88.2",
      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
      "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
      "dev": true,
      "dependencies": {
        "aws-sign2": "~0.7.0",
        "aws4": "^1.8.0",
        "caseless": "~0.12.0",
        "combined-stream": "~1.0.6",
        "extend": "~3.0.2",
        "forever-agent": "~0.6.1",
        "form-data": "~2.3.2",
        "har-validator": "~5.1.3",
        "http-signature": "~1.2.0",
        "is-typedarray": "~1.0.0",
        "isstream": "~0.1.2",
        "json-stringify-safe": "~5.0.1",
        "mime-types": "~2.1.19",
        "oauth-sign": "~0.9.0",
        "performance-now": "^2.1.0",
        "qs": "~6.5.2",
        "safe-buffer": "^5.1.2",
        "tough-cookie": "~2.5.0",
        "tunnel-agent": "^0.6.0",
        "uuid": "^3.3.2"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/request/node_modules/qs": {
      "version": "6.5.3",
      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
      "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
      "dev": true,
      "engines": {
        "node": ">=0.6"
      }
    },
    "node_modules/request/node_modules/uuid": {
      "version": "3.4.0",
      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
      "deprecated": "Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.",
      "dev": true,
      "bin": {
        "uuid": "bin/uuid"
      }
    },
    "node_modules/require-directory": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/require-from-string": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/require-main-filename": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
      "dev": true
    },
    "node_modules/requires-port": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
      "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
      "dev": true
    },
    "node_modules/resolve": {
      "version": "1.20.0",
      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
      "dev": true,
      "dependencies": {
        "is-core-module": "^2.2.0",
        "path-parse": "^1.0.6"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/resolve-cwd": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
      "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
      "dev": true,
      "dependencies": {
        "resolve-from": "^3.0.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/resolve-cwd/node_modules/resolve-from": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
      "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/resolve-from": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/resolve-url": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
      "deprecated": "https://github.com/lydell/resolve-url#deprecated",
      "dev": true
    },
    "node_modules/resolve-url-loader": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz",
      "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==",
      "dev": true,
      "dependencies": {
        "adjust-sourcemap-loader": "^4.0.0",
        "convert-source-map": "^1.7.0",
        "loader-utils": "^2.0.0",
        "postcss": "^7.0.35",
        "source-map": "0.6.1"
      },
      "engines": {
        "node": ">=8.9"
      },
      "peerDependencies": {
        "rework": "1.0.1",
        "rework-visit": "1.0.0"
      },
      "peerDependenciesMeta": {
        "rework": {
          "optional": true
        },
        "rework-visit": {
          "optional": true
        }
      }
    },
    "node_modules/resolve-url-loader/node_modules/picocolors": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
      "dev": true
    },
    "node_modules/resolve-url-loader/node_modules/postcss": {
      "version": "7.0.39",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
      "dev": true,
      "dependencies": {
        "picocolors": "^0.2.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=6.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/postcss/"
      }
    },
    "node_modules/resolve-url-loader/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/restore-cursor": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
      "dev": true,
      "dependencies": {
        "onetime": "^5.1.0",
        "signal-exit": "^3.0.2"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/ret": {
      "version": "0.1.15",
      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
      "dev": true,
      "engines": {
        "node": ">=0.12"
      }
    },
    "node_modules/retry": {
      "version": "0.12.0",
      "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
      "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
      "dev": true,
      "engines": {
        "node": ">= 4"
      }
    },
    "node_modules/reusify": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
      "dev": true,
      "engines": {
        "iojs": ">=1.0.0",
        "node": ">=0.10.0"
      }
    },
    "node_modules/rfdc": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
      "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
      "dev": true
    },
    "node_modules/rimraf": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
      "dev": true,
      "dependencies": {
        "glob": "^7.1.3"
      },
      "bin": {
        "rimraf": "bin.js"
      },
      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }
    },
    "node_modules/run-async": {
      "version": "2.4.1",
      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
      "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
      "dev": true,
      "engines": {
        "node": ">=0.12.0"
      }
    },
    "node_modules/run-parallel": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
      "dev": true,
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ],
      "dependencies": {
        "queue-microtask": "^1.2.2"
      }
    },
    "node_modules/rxjs": {
      "version": "6.6.7",
      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
      "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
      "dependencies": {
        "tslib": "^1.9.0"
      },
      "engines": {
        "npm": ">=2.0.0"
      }
    },
    "node_modules/rxjs/node_modules/tslib": {
      "version": "1.14.1",
      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
    },
    "node_modules/safe-buffer": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
      "dev": true
    },
    "node_modules/safe-regex": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
      "dev": true,
      "dependencies": {
        "ret": "~0.1.10"
      }
    },
    "node_modules/safer-buffer": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
      "dev": true
    },
    "node_modules/sass": {
      "version": "1.35.1",
      "resolved": "https://registry.npmjs.org/sass/-/sass-1.35.1.tgz",
      "integrity": "sha512-oCisuQJstxMcacOPmxLNiLlj4cUyN2+8xJnG7VanRoh2GOLr9RqkvI4AxA4a6LHVg/rsu+PmxXeGhrdSF9jCiQ==",
      "dev": true,
      "dependencies": {
        "chokidar": ">=3.0.0 <4.0.0"
      },
      "bin": {
        "sass": "sass.js"
      },
      "engines": {
        "node": ">=8.9.0"
      }
    },
    "node_modules/sass-loader": {
      "version": "12.1.0",
      "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.1.0.tgz",
      "integrity": "sha512-FVJZ9kxVRYNZTIe2xhw93n3xJNYZADr+q69/s98l9nTCrWASo+DR2Ot0s5xTKQDDEosUkatsGeHxcH4QBp5bSg==",
      "dev": true,
      "dependencies": {
        "klona": "^2.0.4",
        "neo-async": "^2.6.2"
      },
      "engines": {
        "node": ">= 12.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "fibers": ">= 3.1.0",
        "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0",
        "sass": "^1.3.0",
        "webpack": "^5.0.0"
      },
      "peerDependenciesMeta": {
        "fibers": {
          "optional": true
        },
        "node-sass": {
          "optional": true
        },
        "sass": {
          "optional": true
        }
      }
    },
    "node_modules/sax": {
      "version": "1.2.4",
      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
      "dev": true
    },
    "node_modules/schema-utils": {
      "version": "2.7.1",
      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
      "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
      "dev": true,
      "dependencies": {
        "@types/json-schema": "^7.0.5",
        "ajv": "^6.12.4",
        "ajv-keywords": "^3.5.2"
      },
      "engines": {
        "node": ">= 8.9.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      }
    },
    "node_modules/schema-utils/node_modules/ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
      "dev": true,
      "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"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/schema-utils/node_modules/ajv-keywords": {
      "version": "3.5.2",
      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
      "dev": true,
      "peerDependencies": {
        "ajv": "^6.9.1"
      }
    },
    "node_modules/schema-utils/node_modules/json-schema-traverse": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
      "dev": true
    },
    "node_modules/select-hose": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
      "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=",
      "dev": true
    },
    "node_modules/selfsigned": {
      "version": "1.10.14",
      "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.14.tgz",
      "integrity": "sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA==",
      "dev": true,
      "dependencies": {
        "node-forge": "^0.10.0"
      }
    },
    "node_modules/semver": {
      "version": "7.3.5",
      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
      "dev": true,
      "dependencies": {
        "lru-cache": "^6.0.0"
      },
      "bin": {
        "semver": "bin/semver.js"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/send": {
      "version": "0.17.2",
      "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz",
      "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==",
      "dev": true,
      "dependencies": {
        "debug": "2.6.9",
        "depd": "~1.1.2",
        "destroy": "~1.0.4",
        "encodeurl": "~1.0.2",
        "escape-html": "~1.0.3",
        "etag": "~1.8.1",
        "fresh": "0.5.2",
        "http-errors": "1.8.1",
        "mime": "1.6.0",
        "ms": "2.1.3",
        "on-finished": "~2.3.0",
        "range-parser": "~1.2.1",
        "statuses": "~1.5.0"
      },
      "engines": {
        "node": ">= 0.8.0"
      }
    },
    "node_modules/send/node_modules/debug": {
      "version": "2.6.9",
      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
      "dev": true,
      "dependencies": {
        "ms": "2.0.0"
      }
    },
    "node_modules/send/node_modules/debug/node_modules/ms": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
      "dev": true
    },
    "node_modules/send/node_modules/mime": {
      "version": "1.6.0",
      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
      "dev": true,
      "bin": {
        "mime": "cli.js"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/send/node_modules/ms": {
      "version": "2.1.3",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
      "dev": true
    },
    "node_modules/serialize-javascript": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
      "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
      "dev": true,
      "dependencies": {
        "randombytes": "^2.1.0"
      }
    },
    "node_modules/serve-index": {
      "version": "1.9.1",
      "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
      "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
      "dev": true,
      "dependencies": {
        "accepts": "~1.3.4",
        "batch": "0.6.1",
        "debug": "2.6.9",
        "escape-html": "~1.0.3",
        "http-errors": "~1.6.2",
        "mime-types": "~2.1.17",
        "parseurl": "~1.3.2"
      },
      "engines": {
        "node": ">= 0.8.0"
      }
    },
    "node_modules/serve-index/node_modules/debug": {
      "version": "2.6.9",
      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
      "dev": true,
      "dependencies": {
        "ms": "2.0.0"
      }
    },
    "node_modules/serve-index/node_modules/http-errors": {
      "version": "1.6.3",
      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
      "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
      "dev": true,
      "dependencies": {
        "depd": "~1.1.2",
        "inherits": "2.0.3",
        "setprototypeof": "1.1.0",
        "statuses": ">= 1.4.0 < 2"
      },
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/serve-index/node_modules/inherits": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
      "dev": true
    },
    "node_modules/serve-index/node_modules/ms": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
      "dev": true
    },
    "node_modules/serve-index/node_modules/setprototypeof": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
      "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
      "dev": true
    },
    "node_modules/serve-static": {
      "version": "1.14.2",
      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz",
      "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==",
      "dev": true,
      "dependencies": {
        "encodeurl": "~1.0.2",
        "escape-html": "~1.0.3",
        "parseurl": "~1.3.3",
        "send": "0.17.2"
      },
      "engines": {
        "node": ">= 0.8.0"
      }
    },
    "node_modules/set-blocking": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
      "dev": true
    },
    "node_modules/set-value": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
      "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
      "dev": true,
      "dependencies": {
        "extend-shallow": "^2.0.1",
        "is-extendable": "^0.1.1",
        "is-plain-object": "^2.0.3",
        "split-string": "^3.0.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/set-value/node_modules/extend-shallow": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
      "dev": true,
      "dependencies": {
        "is-extendable": "^0.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/set-value/node_modules/is-extendable": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/setprototypeof": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
      "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
      "dev": true
    },
    "node_modules/shallow-clone": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
      "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
      "dev": true,
      "dependencies": {
        "kind-of": "^6.0.2"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/shebang-command": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
      "dev": true,
      "dependencies": {
        "shebang-regex": "^1.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/shebang-regex": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/signal-exit": {
      "version": "3.0.6",
      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz",
      "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==",
      "dev": true
    },
    "node_modules/simplebar": {
      "version": "5.3.6",
      "resolved": "https://registry.npmjs.org/simplebar/-/simplebar-5.3.6.tgz",
      "integrity": "sha512-FJUMbV+hNDd/m+1/fvD41TXKd5mSdlI5zgBygkaQIV3SffNbcLhSbJT6ufTs8ZNRLJ6i+qc/KCFMqWmvlGWMhA==",
      "dependencies": {
        "@juggle/resize-observer": "^3.3.1",
        "can-use-dom": "^0.1.0",
        "core-js": "^3.0.1",
        "lodash.debounce": "^4.0.8",
        "lodash.memoize": "^4.1.2",
        "lodash.throttle": "^4.1.1"
      }
    },
    "node_modules/simplebar-angular": {
      "version": "2.3.6",
      "resolved": "https://registry.npmjs.org/simplebar-angular/-/simplebar-angular-2.3.6.tgz",
      "integrity": "sha512-chSUdCYCLOdajbCA73oL/OU+H/YFNGGdAYkcYx76YDY81C3sj3vMePjuW8cPgZZHwSCGI+opcl6xoBsCK56fJA==",
      "dependencies": {
        "simplebar": "^5.3.6",
        "tslib": "^1.9.0"
      },
      "peerDependencies": {
        "@angular/common": "^8.1.3",
        "@angular/core": "^8.1.3"
      }
    },
    "node_modules/simplebar-angular/node_modules/tslib": {
      "version": "1.14.1",
      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
    },
    "node_modules/slash": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
      "dev": true,
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/smart-buffer": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
      "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
      "dev": true,
      "engines": {
        "node": ">= 6.0.0",
        "npm": ">= 3.0.0"
      }
    },
    "node_modules/snapdragon": {
      "version": "0.8.2",
      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
      "dev": true,
      "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"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon-node": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
      "dev": true,
      "dependencies": {
        "define-property": "^1.0.0",
        "isobject": "^3.0.0",
        "snapdragon-util": "^3.0.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon-node/node_modules/define-property": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
      "dev": true,
      "dependencies": {
        "is-descriptor": "^1.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon-util": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.2.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon-util/node_modules/kind-of": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon/node_modules/debug": {
      "version": "2.6.9",
      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
      "dev": true,
      "dependencies": {
        "ms": "2.0.0"
      }
    },
    "node_modules/snapdragon/node_modules/define-property": {
      "version": "0.2.5",
      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
      "dev": true,
      "dependencies": {
        "is-descriptor": "^0.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon/node_modules/extend-shallow": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
      "dev": true,
      "dependencies": {
        "is-extendable": "^0.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon/node_modules/is-accessor-descriptor": {
      "version": "0.1.6",
      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon/node_modules/is-data-descriptor": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon/node_modules/is-descriptor": {
      "version": "0.1.6",
      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
      "dev": true,
      "dependencies": {
        "is-accessor-descriptor": "^0.1.6",
        "is-data-descriptor": "^0.1.4",
        "kind-of": "^5.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon/node_modules/is-extendable": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon/node_modules/kind-of": {
      "version": "5.1.0",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
      "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon/node_modules/ms": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
      "dev": true
    },
    "node_modules/snapdragon/node_modules/source-map": {
      "version": "0.5.7",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/snapdragon/node_modules/source-map-resolve": {
      "version": "0.5.3",
      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
      "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
      "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
      "dev": true,
      "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"
      }
    },
    "node_modules/socket.io": {
      "version": "4.4.1",
      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.1.tgz",
      "integrity": "sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg==",
      "dev": true,
      "dependencies": {
        "accepts": "~1.3.4",
        "base64id": "~2.0.0",
        "debug": "~4.3.2",
        "engine.io": "~6.1.0",
        "socket.io-adapter": "~2.3.3",
        "socket.io-parser": "~4.0.4"
      },
      "engines": {
        "node": ">=10.0.0"
      }
    },
    "node_modules/socket.io-adapter": {
      "version": "2.3.3",
      "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz",
      "integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==",
      "dev": true
    },
    "node_modules/socket.io-parser": {
      "version": "4.0.4",
      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
      "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
      "dev": true,
      "dependencies": {
        "@types/component-emitter": "^1.2.10",
        "component-emitter": "~1.3.0",
        "debug": "~4.3.1"
      },
      "engines": {
        "node": ">=10.0.0"
      }
    },
    "node_modules/socket.io/node_modules/debug": {
      "version": "4.3.3",
      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
      "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
      "dev": true,
      "dependencies": {
        "ms": "2.1.2"
      },
      "engines": {
        "node": ">=6.0"
      },
      "peerDependenciesMeta": {
        "supports-color": {
          "optional": true
        }
      }
    },
    "node_modules/sockjs": {
      "version": "0.3.24",
      "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
      "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==",
      "dev": true,
      "dependencies": {
        "faye-websocket": "^0.11.3",
        "uuid": "^8.3.2",
        "websocket-driver": "^0.7.4"
      }
    },
    "node_modules/sockjs-client": {
      "version": "1.5.2",
      "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.2.tgz",
      "integrity": "sha512-ZzRxPBISQE7RpzlH4tKJMQbHM9pabHluk0WBaxAQ+wm/UieeBVBou0p4wVnSQGN9QmpAZygQ0cDIypWuqOFmFQ==",
      "dev": true,
      "dependencies": {
        "debug": "^3.2.6",
        "eventsource": "^1.0.7",
        "faye-websocket": "^0.11.3",
        "inherits": "^2.0.4",
        "json3": "^3.3.3",
        "url-parse": "^1.5.3"
      }
    },
    "node_modules/sockjs-client/node_modules/debug": {
      "version": "3.2.7",
      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
      "dev": true,
      "dependencies": {
        "ms": "^2.1.1"
      }
    },
    "node_modules/socks": {
      "version": "2.6.1",
      "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz",
      "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==",
      "dev": true,
      "dependencies": {
        "ip": "^1.1.5",
        "smart-buffer": "^4.1.0"
      },
      "engines": {
        "node": ">= 10.13.0",
        "npm": ">= 3.0.0"
      }
    },
    "node_modules/socks-proxy-agent": {
      "version": "6.1.1",
      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz",
      "integrity": "sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==",
      "dev": true,
      "dependencies": {
        "agent-base": "^6.0.2",
        "debug": "^4.3.1",
        "socks": "^2.6.1"
      },
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/source-list-map": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
      "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
      "dev": true
    },
    "node_modules/source-map": {
      "version": "0.7.3",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
      "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
      "dev": true,
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/source-map-js": {
      "version": "0.6.2",
      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz",
      "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/source-map-loader": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.0.tgz",
      "integrity": "sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw==",
      "dev": true,
      "dependencies": {
        "abab": "^2.0.5",
        "iconv-lite": "^0.6.2",
        "source-map-js": "^0.6.2"
      },
      "engines": {
        "node": ">= 12.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "webpack": "^5.0.0"
      }
    },
    "node_modules/source-map-loader/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==",
      "dev": true,
      "dependencies": {
        "safer-buffer": ">= 2.1.2 < 3.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/source-map-resolve": {
      "version": "0.6.0",
      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz",
      "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==",
      "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
      "dev": true,
      "dependencies": {
        "atob": "^2.1.2",
        "decode-uri-component": "^0.2.0"
      }
    },
    "node_modules/source-map-support": {
      "version": "0.5.19",
      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
      "dev": true,
      "dependencies": {
        "buffer-from": "^1.0.0",
        "source-map": "^0.6.0"
      }
    },
    "node_modules/source-map-support/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/source-map-url": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
      "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
      "deprecated": "See https://github.com/lydell/source-map-url#deprecated",
      "dev": true
    },
    "node_modules/sourcemap-codec": {
      "version": "1.4.8",
      "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
      "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
      "dev": true
    },
    "node_modules/spdy": {
      "version": "4.0.2",
      "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
      "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==",
      "dev": true,
      "dependencies": {
        "debug": "^4.1.0",
        "handle-thing": "^2.0.0",
        "http-deceiver": "^1.2.7",
        "select-hose": "^2.0.0",
        "spdy-transport": "^3.0.0"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/spdy-transport": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz",
      "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
      "dev": true,
      "dependencies": {
        "debug": "^4.1.0",
        "detect-node": "^2.0.4",
        "hpack.js": "^2.1.6",
        "obuf": "^1.1.2",
        "readable-stream": "^3.0.6",
        "wbuf": "^1.7.3"
      }
    },
    "node_modules/split-string": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
      "dev": true,
      "dependencies": {
        "extend-shallow": "^3.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/sshpk": {
      "version": "1.17.0",
      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
      "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
      "dev": true,
      "dependencies": {
        "asn1": "~0.2.3",
        "assert-plus": "^1.0.0",
        "bcrypt-pbkdf": "^1.0.0",
        "dashdash": "^1.12.0",
        "ecc-jsbn": "~0.1.1",
        "getpass": "^0.1.1",
        "jsbn": "~0.1.0",
        "safer-buffer": "^2.0.2",
        "tweetnacl": "~0.14.0"
      },
      "bin": {
        "sshpk-conv": "bin/sshpk-conv",
        "sshpk-sign": "bin/sshpk-sign",
        "sshpk-verify": "bin/sshpk-verify"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/ssri": {
      "version": "8.0.1",
      "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
      "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
      "dev": true,
      "dependencies": {
        "minipass": "^3.1.1"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/stable": {
      "version": "0.1.8",
      "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
      "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
      "dev": true
    },
    "node_modules/static-extend": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
      "dev": true,
      "dependencies": {
        "define-property": "^0.2.5",
        "object-copy": "^0.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/static-extend/node_modules/define-property": {
      "version": "0.2.5",
      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
      "dev": true,
      "dependencies": {
        "is-descriptor": "^0.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/static-extend/node_modules/is-accessor-descriptor": {
      "version": "0.1.6",
      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/static-extend/node_modules/is-data-descriptor": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/static-extend/node_modules/is-descriptor": {
      "version": "0.1.6",
      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
      "dev": true,
      "dependencies": {
        "is-accessor-descriptor": "^0.1.6",
        "is-data-descriptor": "^0.1.4",
        "kind-of": "^5.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/static-extend/node_modules/kind-of": {
      "version": "5.1.0",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
      "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/statuses": {
      "version": "1.5.0",
      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
      "dev": true,
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/streamroller": {
      "version": "2.2.4",
      "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz",
      "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==",
      "dev": true,
      "dependencies": {
        "date-format": "^2.1.0",
        "debug": "^4.1.1",
        "fs-extra": "^8.1.0"
      },
      "engines": {
        "node": ">=8.0"
      }
    },
    "node_modules/streamroller/node_modules/date-format": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz",
      "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==",
      "dev": true,
      "engines": {
        "node": ">=4.0"
      }
    },
    "node_modules/string_decoder": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
      "dev": true,
      "dependencies": {
        "safe-buffer": "~5.2.0"
      }
    },
    "node_modules/string_decoder/node_modules/safe-buffer": {
      "version": "5.2.1",
      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
      "dev": true,
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ]
    },
    "node_modules/string-width": {
      "version": "4.2.3",
      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
      "dev": true,
      "dependencies": {
        "emoji-regex": "^8.0.0",
        "is-fullwidth-code-point": "^3.0.0",
        "strip-ansi": "^6.0.1"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/strip-ansi": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
      "dev": true,
      "dependencies": {
        "ansi-regex": "^5.0.1"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/strip-eof": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/style-loader": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz",
      "integrity": "sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==",
      "dev": true,
      "dependencies": {
        "loader-utils": "^2.0.0",
        "schema-utils": "^3.0.0"
      },
      "engines": {
        "node": ">= 10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "webpack": "^4.0.0 || ^5.0.0"
      }
    },
    "node_modules/style-loader/node_modules/ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
      "dev": true,
      "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"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/style-loader/node_modules/ajv-keywords": {
      "version": "3.5.2",
      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
      "dev": true,
      "peerDependencies": {
        "ajv": "^6.9.1"
      }
    },
    "node_modules/style-loader/node_modules/json-schema-traverse": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
      "dev": true
    },
    "node_modules/style-loader/node_modules/schema-utils": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
      "dev": true,
      "dependencies": {
        "@types/json-schema": "^7.0.8",
        "ajv": "^6.12.5",
        "ajv-keywords": "^3.5.2"
      },
      "engines": {
        "node": ">= 10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      }
    },
    "node_modules/stylehacks": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.1.tgz",
      "integrity": "sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA==",
      "dev": true,
      "dependencies": {
        "browserslist": "^4.16.0",
        "postcss-selector-parser": "^6.0.4"
      },
      "engines": {
        "node": "^10 || ^12 || >=14.0"
      },
      "peerDependencies": {
        "postcss": "^8.2.15"
      }
    },
    "node_modules/stylus": {
      "version": "0.54.8",
      "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.8.tgz",
      "integrity": "sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==",
      "dev": true,
      "dependencies": {
        "css-parse": "~2.0.0",
        "debug": "~3.1.0",
        "glob": "^7.1.6",
        "mkdirp": "~1.0.4",
        "safer-buffer": "^2.1.2",
        "sax": "~1.2.4",
        "semver": "^6.3.0",
        "source-map": "^0.7.3"
      },
      "bin": {
        "stylus": "bin/stylus"
      },
      "engines": {
        "node": "*"
      }
    },
    "node_modules/stylus-loader": {
      "version": "6.1.0",
      "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-6.1.0.tgz",
      "integrity": "sha512-qKO34QCsOtSJrXxQQmXsPeaVHh6hMumBAFIoJTcsSr2VzrA6o/CW9HCGR8spCjzJhN8oKQHdj/Ytx0wwXyElkw==",
      "dev": true,
      "dependencies": {
        "fast-glob": "^3.2.5",
        "klona": "^2.0.4",
        "normalize-path": "^3.0.0"
      },
      "engines": {
        "node": ">= 12.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "stylus": ">=0.52.4",
        "webpack": "^5.0.0"
      }
    },
    "node_modules/stylus/node_modules/debug": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
      "dev": true,
      "dependencies": {
        "ms": "2.0.0"
      }
    },
    "node_modules/stylus/node_modules/ms": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
      "dev": true
    },
    "node_modules/stylus/node_modules/semver": {
      "version": "6.3.0",
      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
      "dev": true,
      "bin": {
        "semver": "bin/semver.js"
      }
    },
    "node_modules/supports-color": {
      "version": "5.5.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
      "dev": true,
      "dependencies": {
        "has-flag": "^3.0.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/svgo": {
      "version": "2.8.0",
      "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
      "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==",
      "dev": true,
      "dependencies": {
        "@trysound/sax": "0.2.0",
        "commander": "^7.2.0",
        "css-select": "^4.1.3",
        "css-tree": "^1.1.3",
        "csso": "^4.2.0",
        "picocolors": "^1.0.0",
        "stable": "^0.1.8"
      },
      "bin": {
        "svgo": "bin/svgo"
      },
      "engines": {
        "node": ">=10.13.0"
      }
    },
    "node_modules/symbol-observable": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz",
      "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==",
      "dev": true,
      "engines": {
        "node": ">=0.10"
      }
    },
    "node_modules/tapable": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
      "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/tar": {
      "version": "6.1.11",
      "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
      "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
      "dev": true,
      "dependencies": {
        "chownr": "^2.0.0",
        "fs-minipass": "^2.0.0",
        "minipass": "^3.0.0",
        "minizlib": "^2.1.1",
        "mkdirp": "^1.0.3",
        "yallist": "^4.0.0"
      },
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/terser": {
      "version": "5.7.0",
      "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.0.tgz",
      "integrity": "sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g==",
      "dev": true,
      "dependencies": {
        "commander": "^2.20.0",
        "source-map": "~0.7.2",
        "source-map-support": "~0.5.19"
      },
      "bin": {
        "terser": "bin/terser"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/terser-webpack-plugin": {
      "version": "5.1.3",
      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.3.tgz",
      "integrity": "sha512-cxGbMqr6+A2hrIB5ehFIF+F/iST5ZOxvOmy9zih9ySbP1C2oEWQSOUS+2SNBTjzx5xLKO4xnod9eywdfq1Nb9A==",
      "dev": true,
      "dependencies": {
        "jest-worker": "^27.0.2",
        "p-limit": "^3.1.0",
        "schema-utils": "^3.0.0",
        "serialize-javascript": "^5.0.1",
        "source-map": "^0.6.1",
        "terser": "^5.7.0"
      },
      "engines": {
        "node": ">= 10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "webpack": "^5.1.0"
      }
    },
    "node_modules/terser-webpack-plugin/node_modules/ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
      "dev": true,
      "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"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": {
      "version": "3.5.2",
      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
      "dev": true,
      "peerDependencies": {
        "ajv": "^6.9.1"
      }
    },
    "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
      "dev": true
    },
    "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
      "dev": true,
      "dependencies": {
        "@types/json-schema": "^7.0.8",
        "ajv": "^6.12.5",
        "ajv-keywords": "^3.5.2"
      },
      "engines": {
        "node": ">= 10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      }
    },
    "node_modules/terser-webpack-plugin/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/terser/node_modules/commander": {
      "version": "2.20.3",
      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
      "dev": true
    },
    "node_modules/text-table": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
      "dev": true
    },
    "node_modules/through": {
      "version": "2.3.8",
      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
      "dev": true
    },
    "node_modules/thunky": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
      "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
      "dev": true
    },
    "node_modules/timsort": {
      "version": "0.3.0",
      "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
      "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
      "dev": true
    },
    "node_modules/tmp": {
      "version": "0.0.33",
      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
      "dev": true,
      "dependencies": {
        "os-tmpdir": "~1.0.2"
      },
      "engines": {
        "node": ">=0.6.0"
      }
    },
    "node_modules/to-fast-properties": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
      "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/to-object-path": {
      "version": "0.3.0",
      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/to-object-path/node_modules/kind-of": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/to-regex": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
      "dev": true,
      "dependencies": {
        "define-property": "^2.0.2",
        "extend-shallow": "^3.0.2",
        "regex-not": "^1.0.2",
        "safe-regex": "^1.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/to-regex-range": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
      "dev": true,
      "dependencies": {
        "is-number": "^7.0.0"
      },
      "engines": {
        "node": ">=8.0"
      }
    },
    "node_modules/toidentifier": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
      "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
      "dev": true,
      "engines": {
        "node": ">=0.6"
      }
    },
    "node_modules/tough-cookie": {
      "version": "2.5.0",
      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
      "dev": true,
      "dependencies": {
        "psl": "^1.1.28",
        "punycode": "^2.1.1"
      },
      "engines": {
        "node": ">=0.8"
      }
    },
    "node_modules/tree-kill": {
      "version": "1.2.2",
      "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
      "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
      "dev": true,
      "bin": {
        "tree-kill": "cli.js"
      }
    },
    "node_modules/tslib": {
      "version": "2.3.1",
      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
      "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
    },
    "node_modules/tunnel-agent": {
      "version": "0.6.0",
      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
      "dev": true,
      "dependencies": {
        "safe-buffer": "^5.0.1"
      },
      "engines": {
        "node": "*"
      }
    },
    "node_modules/tweetnacl": {
      "version": "0.14.5",
      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
      "dev": true
    },
    "node_modules/type-fest": {
      "version": "0.21.3",
      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
      "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
      "dev": true,
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/type-is": {
      "version": "1.6.18",
      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
      "dev": true,
      "dependencies": {
        "media-typer": "0.3.0",
        "mime-types": "~2.1.24"
      },
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/typescript": {
      "version": "4.3.5",
      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
      "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
      "dev": true,
      "bin": {
        "tsc": "bin/tsc",
        "tsserver": "bin/tsserver"
      },
      "engines": {
        "node": ">=4.2.0"
      }
    },
    "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==",
      "dev": true,
      "funding": [
        {
          "type": "opencollective",
          "url": "https://opencollective.com/ua-parser-js"
        },
        {
          "type": "paypal",
          "url": "https://paypal.me/faisalman"
        }
      ],
      "engines": {
        "node": "*"
      }
    },
    "node_modules/unicode-canonical-property-names-ecmascript": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
      "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/unicode-match-property-ecmascript": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
      "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
      "dev": true,
      "dependencies": {
        "unicode-canonical-property-names-ecmascript": "^2.0.0",
        "unicode-property-aliases-ecmascript": "^2.0.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/unicode-match-property-value-ecmascript": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz",
      "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/unicode-property-aliases-ecmascript": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz",
      "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/union-value": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
      "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
      "dev": true,
      "dependencies": {
        "arr-union": "^3.1.0",
        "get-value": "^2.0.6",
        "is-extendable": "^0.1.1",
        "set-value": "^2.0.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/union-value/node_modules/is-extendable": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/uniq": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
      "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
      "dev": true
    },
    "node_modules/unique-filename": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
      "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
      "dev": true,
      "dependencies": {
        "unique-slug": "^2.0.0"
      }
    },
    "node_modules/unique-slug": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
      "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
      "dev": true,
      "dependencies": {
        "imurmurhash": "^0.1.4"
      }
    },
    "node_modules/universalify": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
      "dev": true,
      "engines": {
        "node": ">= 4.0.0"
      }
    },
    "node_modules/unpipe": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
      "dev": true,
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/unset-value": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
      "dev": true,
      "dependencies": {
        "has-value": "^0.3.1",
        "isobject": "^3.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/unset-value/node_modules/has-value": {
      "version": "0.3.1",
      "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
      "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
      "dev": true,
      "dependencies": {
        "get-value": "^2.0.3",
        "has-values": "^0.1.4",
        "isobject": "^2.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
      "dev": true,
      "dependencies": {
        "isarray": "1.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/unset-value/node_modules/has-values": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
      "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/upath": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
      "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
      "dev": true,
      "engines": {
        "node": ">=4",
        "yarn": "*"
      }
    },
    "node_modules/uri-js": {
      "version": "4.4.1",
      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
      "dev": true,
      "dependencies": {
        "punycode": "^2.1.0"
      }
    },
    "node_modules/urix": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
      "deprecated": "Please see https://github.com/lydell/urix#deprecated",
      "dev": true
    },
    "node_modules/url": {
      "version": "0.11.0",
      "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
      "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
      "dev": true,
      "dependencies": {
        "punycode": "1.3.2",
        "querystring": "0.2.0"
      }
    },
    "node_modules/url-parse": {
      "version": "1.5.4",
      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.4.tgz",
      "integrity": "sha512-ITeAByWWoqutFClc/lRZnFplgXgEZr3WJ6XngMM/N9DMIm4K8zXPCZ1Jdu0rERwO84w1WC5wkle2ubwTA4NTBg==",
      "dev": true,
      "dependencies": {
        "querystringify": "^2.1.1",
        "requires-port": "^1.0.0"
      }
    },
    "node_modules/url/node_modules/punycode": {
      "version": "1.3.2",
      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
      "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
      "dev": true
    },
    "node_modules/use": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/util-deprecate": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
      "dev": true
    },
    "node_modules/utils-merge": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
      "dev": true,
      "engines": {
        "node": ">= 0.4.0"
      }
    },
    "node_modules/uuid": {
      "version": "8.3.2",
      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
      "dev": true,
      "bin": {
        "uuid": "dist/bin/uuid"
      }
    },
    "node_modules/validate-npm-package-name": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz",
      "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=",
      "dev": true,
      "dependencies": {
        "builtins": "^1.0.3"
      }
    },
    "node_modules/vary": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
      "dev": true,
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/verror": {
      "version": "1.10.0",
      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
      "dev": true,
      "engines": [
        "node >=0.6.0"
      ],
      "dependencies": {
        "assert-plus": "^1.0.0",
        "core-util-is": "1.0.2",
        "extsprintf": "^1.2.0"
      }
    },
    "node_modules/void-elements": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
      "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/watchpack": {
      "version": "2.3.1",
      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz",
      "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==",
      "dev": true,
      "dependencies": {
        "glob-to-regexp": "^0.4.1",
        "graceful-fs": "^4.1.2"
      },
      "engines": {
        "node": ">=10.13.0"
      }
    },
    "node_modules/wbuf": {
      "version": "1.7.3",
      "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
      "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
      "dev": true,
      "dependencies": {
        "minimalistic-assert": "^1.0.0"
      }
    },
    "node_modules/wcwidth": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
      "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
      "dev": true,
      "dependencies": {
        "defaults": "^1.0.3"
      }
    },
    "node_modules/webpack": {
      "version": "5.44.0",
      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.44.0.tgz",
      "integrity": "sha512-I1S1w4QLoKmH19pX6YhYN0NiSXaWY8Ou00oA+aMcr9IUGeF5azns+IKBkfoAAG9Bu5zOIzZt/mN35OffBya8AQ==",
      "dev": true,
      "dependencies": {
        "@types/eslint-scope": "^3.7.0",
        "@types/estree": "^0.0.50",
        "@webassemblyjs/ast": "1.11.1",
        "@webassemblyjs/wasm-edit": "1.11.1",
        "@webassemblyjs/wasm-parser": "1.11.1",
        "acorn": "^8.4.1",
        "browserslist": "^4.14.5",
        "chrome-trace-event": "^1.0.2",
        "enhanced-resolve": "^5.8.0",
        "es-module-lexer": "^0.7.1",
        "eslint-scope": "5.1.1",
        "events": "^3.2.0",
        "glob-to-regexp": "^0.4.1",
        "graceful-fs": "^4.2.4",
        "json-parse-better-errors": "^1.0.2",
        "loader-runner": "^4.2.0",
        "mime-types": "^2.1.27",
        "neo-async": "^2.6.2",
        "schema-utils": "^3.0.0",
        "tapable": "^2.1.1",
        "terser-webpack-plugin": "^5.1.3",
        "watchpack": "^2.2.0",
        "webpack-sources": "^2.3.0"
      },
      "bin": {
        "webpack": "bin/webpack.js"
      },
      "engines": {
        "node": ">=10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependenciesMeta": {
        "webpack-cli": {
          "optional": true
        }
      }
    },
    "node_modules/webpack-dev-middleware": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.0.0.tgz",
      "integrity": "sha512-9zng2Z60pm6A98YoRcA0wSxw1EYn7B7y5owX/Tckyt9KGyULTkLtiavjaXlWqOMkM0YtqGgL3PvMOFgyFLq8vw==",
      "dev": true,
      "dependencies": {
        "colorette": "^1.2.2",
        "mem": "^8.1.1",
        "memfs": "^3.2.2",
        "mime-types": "^2.1.31",
        "range-parser": "^1.2.1",
        "schema-utils": "^3.0.0"
      },
      "engines": {
        "node": ">= 12.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "webpack": "^4.0.0 || ^5.0.0"
      }
    },
    "node_modules/webpack-dev-middleware/node_modules/ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
      "dev": true,
      "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"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": {
      "version": "3.5.2",
      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
      "dev": true,
      "peerDependencies": {
        "ajv": "^6.9.1"
      }
    },
    "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
      "dev": true
    },
    "node_modules/webpack-dev-middleware/node_modules/schema-utils": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
      "dev": true,
      "dependencies": {
        "@types/json-schema": "^7.0.8",
        "ajv": "^6.12.5",
        "ajv-keywords": "^3.5.2"
      },
      "engines": {
        "node": ">= 10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      }
    },
    "node_modules/webpack-dev-server": {
      "version": "3.11.2",
      "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz",
      "integrity": "sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ==",
      "dev": true,
      "dependencies": {
        "ansi-html": "0.0.7",
        "bonjour": "^3.5.0",
        "chokidar": "^2.1.8",
        "compression": "^1.7.4",
        "connect-history-api-fallback": "^1.6.0",
        "debug": "^4.1.1",
        "del": "^4.1.1",
        "express": "^4.17.1",
        "html-entities": "^1.3.1",
        "http-proxy-middleware": "0.19.1",
        "import-local": "^2.0.0",
        "internal-ip": "^4.3.0",
        "ip": "^1.1.5",
        "is-absolute-url": "^3.0.3",
        "killable": "^1.0.1",
        "loglevel": "^1.6.8",
        "opn": "^5.5.0",
        "p-retry": "^3.0.1",
        "portfinder": "^1.0.26",
        "schema-utils": "^1.0.0",
        "selfsigned": "^1.10.8",
        "semver": "^6.3.0",
        "serve-index": "^1.9.1",
        "sockjs": "^0.3.21",
        "sockjs-client": "^1.5.0",
        "spdy": "^4.0.2",
        "strip-ansi": "^3.0.1",
        "supports-color": "^6.1.0",
        "url": "^0.11.0",
        "webpack-dev-middleware": "^3.7.2",
        "webpack-log": "^2.0.0",
        "ws": "^6.2.1",
        "yargs": "^13.3.2"
      },
      "bin": {
        "webpack-dev-server": "bin/webpack-dev-server.js"
      },
      "engines": {
        "node": ">= 6.11.5"
      },
      "peerDependencies": {
        "webpack": "^4.0.0 || ^5.0.0"
      },
      "peerDependenciesMeta": {
        "webpack-cli": {
          "optional": true
        }
      }
    },
    "node_modules/webpack-dev-server/node_modules/ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
      "dev": true,
      "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"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/webpack-dev-server/node_modules/ajv-keywords": {
      "version": "3.5.2",
      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
      "dev": true,
      "peerDependencies": {
        "ajv": "^6.9.1"
      }
    },
    "node_modules/webpack-dev-server/node_modules/ansi-regex": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/anymatch": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
      "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
      "dev": true,
      "dependencies": {
        "micromatch": "^3.1.4",
        "normalize-path": "^2.1.1"
      }
    },
    "node_modules/webpack-dev-server/node_modules/anymatch/node_modules/normalize-path": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
      "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
      "dev": true,
      "dependencies": {
        "remove-trailing-separator": "^1.0.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/binary-extensions": {
      "version": "1.13.1",
      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
      "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/braces": {
      "version": "2.3.2",
      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
      "dev": true,
      "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"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/braces/node_modules/extend-shallow": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
      "dev": true,
      "dependencies": {
        "is-extendable": "^0.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/chokidar": {
      "version": "2.1.8",
      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
      "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
      "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.",
      "dev": true,
      "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"
      }
    },
    "node_modules/webpack-dev-server/node_modules/cliui": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
      "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
      "dev": true,
      "dependencies": {
        "string-width": "^3.1.0",
        "strip-ansi": "^5.2.0",
        "wrap-ansi": "^5.1.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/cliui/node_modules/ansi-regex": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/webpack-dev-server/node_modules/cliui/node_modules/strip-ansi": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
      "dev": true,
      "dependencies": {
        "ansi-regex": "^4.1.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/webpack-dev-server/node_modules/emoji-regex": {
      "version": "7.0.3",
      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
      "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
      "dev": true
    },
    "node_modules/webpack-dev-server/node_modules/fill-range": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
      "dev": true,
      "dependencies": {
        "extend-shallow": "^2.0.1",
        "is-number": "^3.0.0",
        "repeat-string": "^1.6.1",
        "to-regex-range": "^2.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/fill-range/node_modules/extend-shallow": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
      "dev": true,
      "dependencies": {
        "is-extendable": "^0.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/find-up": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
      "dev": true,
      "dependencies": {
        "locate-path": "^3.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/webpack-dev-server/node_modules/fsevents": {
      "version": "1.2.13",
      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
      "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
      "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.",
      "dev": true,
      "hasInstallScript": true,
      "optional": true,
      "os": [
        "darwin"
      ],
      "dependencies": {
        "bindings": "^1.5.0",
        "nan": "^2.12.1"
      },
      "engines": {
        "node": ">= 4.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/glob-parent": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
      "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
      "dev": true,
      "dependencies": {
        "is-glob": "^3.1.0",
        "path-dirname": "^1.0.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/glob-parent/node_modules/is-glob": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
      "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
      "dev": true,
      "dependencies": {
        "is-extglob": "^2.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/is-binary-path": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
      "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
      "dev": true,
      "dependencies": {
        "binary-extensions": "^1.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/is-extendable": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/is-fullwidth-code-point": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/webpack-dev-server/node_modules/is-number": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
      "dev": true,
      "dependencies": {
        "kind-of": "^3.0.2"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/is-number/node_modules/kind-of": {
      "version": "3.2.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
      "dev": true,
      "dependencies": {
        "is-buffer": "^1.1.5"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/json-schema-traverse": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
      "dev": true
    },
    "node_modules/webpack-dev-server/node_modules/locate-path": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
      "dev": true,
      "dependencies": {
        "p-locate": "^3.0.0",
        "path-exists": "^3.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/webpack-dev-server/node_modules/micromatch": {
      "version": "3.1.10",
      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
      "dev": true,
      "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"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/mkdirp": {
      "version": "0.5.5",
      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
      "dev": true,
      "dependencies": {
        "minimist": "^1.2.5"
      },
      "bin": {
        "mkdirp": "bin/cmd.js"
      }
    },
    "node_modules/webpack-dev-server/node_modules/p-limit": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
      "dev": true,
      "dependencies": {
        "p-try": "^2.0.0"
      },
      "engines": {
        "node": ">=6"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/webpack-dev-server/node_modules/p-locate": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
      "dev": true,
      "dependencies": {
        "p-limit": "^2.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/webpack-dev-server/node_modules/path-exists": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/webpack-dev-server/node_modules/readable-stream": {
      "version": "2.3.7",
      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
      "dev": true,
      "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"
      }
    },
    "node_modules/webpack-dev-server/node_modules/readdirp": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
      "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
      "dev": true,
      "dependencies": {
        "graceful-fs": "^4.1.11",
        "micromatch": "^3.1.10",
        "readable-stream": "^2.0.2"
      },
      "engines": {
        "node": ">=0.10"
      }
    },
    "node_modules/webpack-dev-server/node_modules/schema-utils": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
      "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
      "dev": true,
      "dependencies": {
        "ajv": "^6.1.0",
        "ajv-errors": "^1.0.0",
        "ajv-keywords": "^3.1.0"
      },
      "engines": {
        "node": ">= 4"
      }
    },
    "node_modules/webpack-dev-server/node_modules/semver": {
      "version": "6.3.0",
      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
      "dev": true,
      "bin": {
        "semver": "bin/semver.js"
      }
    },
    "node_modules/webpack-dev-server/node_modules/string_decoder": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
      "dev": true,
      "dependencies": {
        "safe-buffer": "~5.1.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/string-width": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
      "dev": true,
      "dependencies": {
        "emoji-regex": "^7.0.1",
        "is-fullwidth-code-point": "^2.0.0",
        "strip-ansi": "^5.1.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/webpack-dev-server/node_modules/string-width/node_modules/ansi-regex": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/webpack-dev-server/node_modules/string-width/node_modules/strip-ansi": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
      "dev": true,
      "dependencies": {
        "ansi-regex": "^4.1.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/webpack-dev-server/node_modules/strip-ansi": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
      "dev": true,
      "dependencies": {
        "ansi-regex": "^2.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/supports-color": {
      "version": "6.1.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
      "dev": true,
      "dependencies": {
        "has-flag": "^3.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/webpack-dev-server/node_modules/to-regex-range": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
      "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
      "dev": true,
      "dependencies": {
        "is-number": "^3.0.0",
        "repeat-string": "^1.6.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/webpack-dev-middleware": {
      "version": "3.7.3",
      "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz",
      "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==",
      "dev": true,
      "dependencies": {
        "memory-fs": "^0.4.1",
        "mime": "^2.4.4",
        "mkdirp": "^0.5.1",
        "range-parser": "^1.2.1",
        "webpack-log": "^2.0.0"
      },
      "engines": {
        "node": ">= 6"
      },
      "peerDependencies": {
        "webpack": "^4.0.0 || ^5.0.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/wrap-ansi": {
      "version": "5.1.0",
      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
      "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
      "dev": true,
      "dependencies": {
        "ansi-styles": "^3.2.0",
        "string-width": "^3.0.0",
        "strip-ansi": "^5.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/webpack-dev-server/node_modules/wrap-ansi/node_modules/ansi-regex": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/webpack-dev-server/node_modules/wrap-ansi/node_modules/strip-ansi": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
      "dev": true,
      "dependencies": {
        "ansi-regex": "^4.1.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/webpack-dev-server/node_modules/ws": {
      "version": "6.2.2",
      "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
      "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
      "dev": true,
      "dependencies": {
        "async-limiter": "~1.0.0"
      }
    },
    "node_modules/webpack-dev-server/node_modules/y18n": {
      "version": "4.0.3",
      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
      "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
      "dev": true
    },
    "node_modules/webpack-dev-server/node_modules/yargs": {
      "version": "13.3.2",
      "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
      "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
      "dev": true,
      "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"
      }
    },
    "node_modules/webpack-dev-server/node_modules/yargs-parser": {
      "version": "13.1.2",
      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
      "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
      "dev": true,
      "dependencies": {
        "camelcase": "^5.0.0",
        "decamelize": "^1.2.0"
      }
    },
    "node_modules/webpack-log": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
      "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
      "dev": true,
      "dependencies": {
        "ansi-colors": "^3.0.0",
        "uuid": "^3.3.2"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/webpack-log/node_modules/ansi-colors": {
      "version": "3.2.4",
      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
      "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==",
      "dev": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/webpack-log/node_modules/uuid": {
      "version": "3.4.0",
      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
      "deprecated": "Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.",
      "dev": true,
      "bin": {
        "uuid": "bin/uuid"
      }
    },
    "node_modules/webpack-merge": {
      "version": "5.8.0",
      "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz",
      "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==",
      "dev": true,
      "dependencies": {
        "clone-deep": "^4.0.1",
        "wildcard": "^2.0.0"
      },
      "engines": {
        "node": ">=10.0.0"
      }
    },
    "node_modules/webpack-sources": {
      "version": "1.4.3",
      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
      "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
      "dev": true,
      "dependencies": {
        "source-list-map": "^2.0.0",
        "source-map": "~0.6.1"
      }
    },
    "node_modules/webpack-sources/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack-subresource-integrity": {
      "version": "1.5.2",
      "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.5.2.tgz",
      "integrity": "sha512-GBWYBoyalbo5YClwWop9qe6Zclp8CIXYGIz12OPclJhIrSplDxs1Ls1JDMH8xBPPrg1T6ISaTW9Y6zOrwEiAzw==",
      "dev": true,
      "dependencies": {
        "webpack-sources": "^1.3.0"
      },
      "engines": {
        "node": ">=4"
      },
      "peerDependencies": {
        "html-webpack-plugin": ">= 2.21.0 < 5",
        "webpack": ">= 1.12.11 < 6"
      },
      "peerDependenciesMeta": {
        "html-webpack-plugin": {
          "optional": true
        }
      }
    },
    "node_modules/webpack/node_modules/ajv": {
      "version": "6.12.6",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
      "dev": true,
      "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"
      },
      "funding": {
        "type": "github",
        "url": "https://github.com/sponsors/epoberezkin"
      }
    },
    "node_modules/webpack/node_modules/ajv-keywords": {
      "version": "3.5.2",
      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
      "dev": true,
      "peerDependencies": {
        "ajv": "^6.9.1"
      }
    },
    "node_modules/webpack/node_modules/json-schema-traverse": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
      "dev": true
    },
    "node_modules/webpack/node_modules/schema-utils": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
      "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
      "dev": true,
      "dependencies": {
        "@types/json-schema": "^7.0.8",
        "ajv": "^6.12.5",
        "ajv-keywords": "^3.5.2"
      },
      "engines": {
        "node": ">= 10.13.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      }
    },
    "node_modules/webpack/node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/webpack/node_modules/webpack-sources": {
      "version": "2.3.1",
      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz",
      "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==",
      "dev": true,
      "dependencies": {
        "source-list-map": "^2.0.1",
        "source-map": "^0.6.1"
      },
      "engines": {
        "node": ">=10.13.0"
      }
    },
    "node_modules/websocket-driver": {
      "version": "0.7.4",
      "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
      "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
      "dev": true,
      "dependencies": {
        "http-parser-js": ">=0.5.1",
        "safe-buffer": ">=5.1.0",
        "websocket-extensions": ">=0.1.1"
      },
      "engines": {
        "node": ">=0.8.0"
      }
    },
    "node_modules/websocket-extensions": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
      "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
      "dev": true,
      "engines": {
        "node": ">=0.8.0"
      }
    },
    "node_modules/which": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
      "dev": true,
      "dependencies": {
        "isexe": "^2.0.0"
      },
      "bin": {
        "which": "bin/which"
      }
    },
    "node_modules/which-module": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
      "dev": true
    },
    "node_modules/wide-align": {
      "version": "1.1.5",
      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
      "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
      "dev": true,
      "dependencies": {
        "string-width": "^1.0.2 || 2 || 3 || 4"
      }
    },
    "node_modules/wildcard": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz",
      "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
      "dev": true
    },
    "node_modules/wrap-ansi": {
      "version": "7.0.0",
      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
      "dev": true,
      "dependencies": {
        "ansi-styles": "^4.0.0",
        "string-width": "^4.1.0",
        "strip-ansi": "^6.0.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
      }
    },
    "node_modules/wrap-ansi/node_modules/ansi-styles": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
      "dev": true,
      "dependencies": {
        "color-convert": "^2.0.1"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
      }
    },
    "node_modules/wrap-ansi/node_modules/color-convert": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
      "dev": true,
      "dependencies": {
        "color-name": "~1.1.4"
      },
      "engines": {
        "node": ">=7.0.0"
      }
    },
    "node_modules/wrap-ansi/node_modules/color-name": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
      "dev": true
    },
    "node_modules/wrappy": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
      "dev": true
    },
    "node_modules/ws": {
      "version": "8.2.3",
      "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
      "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
      "dev": true,
      "engines": {
        "node": ">=10.0.0"
      },
      "peerDependencies": {
        "bufferutil": "^4.0.1",
        "utf-8-validate": "^5.0.2"
      },
      "peerDependenciesMeta": {
        "bufferutil": {
          "optional": true
        },
        "utf-8-validate": {
          "optional": true
        }
      }
    },
    "node_modules/y18n": {
      "version": "5.0.8",
      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
      "dev": true,
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/yallist": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
      "dev": true
    },
    "node_modules/yaml": {
      "version": "1.10.2",
      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
      "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
      "dev": true,
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/yargs": {
      "version": "17.3.1",
      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz",
      "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==",
      "dev": true,
      "dependencies": {
        "cliui": "^7.0.2",
        "escalade": "^3.1.1",
        "get-caller-file": "^2.0.5",
        "require-directory": "^2.1.1",
        "string-width": "^4.2.3",
        "y18n": "^5.0.5",
        "yargs-parser": "^21.0.0"
      },
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/yargs-parser": {
      "version": "21.0.0",
      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz",
      "integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==",
      "dev": true,
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/yocto-queue": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
      "dev": true,
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/zone.js": {
      "version": "0.11.4",
      "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.11.4.tgz",
      "integrity": "sha512-DDh2Ab+A/B+9mJyajPjHFPWfYU1H+pdun4wnnk0OcQTNjem1XQSZ2CDW+rfZEUDjv5M19SBqAkjZi0x5wuB5Qw==",
      "dependencies": {
        "tslib": "^2.0.0"
      }
    }
  },
  "dependencies": {
    "@angular-devkit/architect": {
      "version": "0.1201.4",
      "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1201.4.tgz",
      "integrity": "sha512-hGO5NrZxV8Z7sILwokt7H+1sMf+5tJS9PJszvYlIBSzG0LBkOwwLQDb4MD42ATXFru57SXNqMZDVKoi1kTgxAw==",
      "dev": true,
      "requires": {
        "@angular-devkit/core": "12.1.4",
        "rxjs": "6.6.7"
      }
    },
    "@angular-devkit/build-angular": {
      "version": "12.1.4",
      "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-12.1.4.tgz",
      "integrity": "sha512-9kMdnaU2dr8o7gJpuBsEHLUpa6huF8uZQEd1+jhKfByEY/xTQo8qztvmbhFhrSfDvdYRygNHItpt3pYEoCEOig==",
      "dev": true,
      "requires": {
        "@angular-devkit/architect": "0.1201.4",
        "@angular-devkit/build-optimizer": "0.1201.4",
        "@angular-devkit/build-webpack": "0.1201.4",
        "@angular-devkit/core": "12.1.4",
        "@babel/core": "7.14.6",
        "@babel/generator": "7.14.5",
        "@babel/helper-annotate-as-pure": "7.14.5",
        "@babel/plugin-proposal-async-generator-functions": "7.14.7",
        "@babel/plugin-transform-async-to-generator": "7.14.5",
        "@babel/plugin-transform-runtime": "7.14.5",
        "@babel/preset-env": "7.14.7",
        "@babel/runtime": "7.14.6",
        "@babel/template": "7.14.5",
        "@discoveryjs/json-ext": "0.5.3",
        "@jsdevtools/coverage-istanbul-loader": "3.0.5",
        "@ngtools/webpack": "12.1.4",
        "ansi-colors": "4.1.1",
        "babel-loader": "8.2.2",
        "browserslist": "^4.9.1",
        "cacache": "15.2.0",
        "caniuse-lite": "^1.0.30001032",
        "circular-dependency-plugin": "5.2.2",
        "copy-webpack-plugin": "9.0.0",
        "core-js": "3.15.1",
        "critters": "0.0.10",
        "css-loader": "5.2.6",
        "css-minimizer-webpack-plugin": "3.0.1",
        "find-cache-dir": "3.3.1",
        "glob": "7.1.7",
        "https-proxy-agent": "5.0.0",
        "inquirer": "8.1.1",
        "jest-worker": "27.0.2",
        "karma-source-map-support": "1.4.0",
        "less": "4.1.1",
        "less-loader": "10.0.0",
        "license-webpack-plugin": "2.3.20",
        "loader-utils": "2.0.0",
        "mini-css-extract-plugin": "1.6.2",
        "minimatch": "3.0.4",
        "open": "8.2.1",
        "ora": "5.4.1",
        "parse5-html-rewriting-stream": "6.0.1",
        "postcss": "8.3.5",
        "postcss-import": "14.0.2",
        "postcss-loader": "6.1.0",
        "postcss-preset-env": "6.7.0",
        "raw-loader": "4.0.2",
        "regenerator-runtime": "0.13.7",
        "resolve-url-loader": "4.0.0",
        "rxjs": "6.6.7",
        "sass": "1.35.1",
        "sass-loader": "12.1.0",
        "semver": "7.3.5",
        "source-map": "0.7.3",
        "source-map-loader": "3.0.0",
        "source-map-support": "0.5.19",
        "style-loader": "2.0.0",
        "stylus": "0.54.8",
        "stylus-loader": "6.1.0",
        "terser": "5.7.0",
        "terser-webpack-plugin": "5.1.3",
        "text-table": "0.2.0",
        "tree-kill": "1.2.2",
        "tslib": "2.3.0",
        "webpack": "5.44.0",
        "webpack-dev-middleware": "5.0.0",
        "webpack-dev-server": "3.11.2",
        "webpack-merge": "5.8.0",
        "webpack-subresource-integrity": "1.5.2"
      },
      "dependencies": {
        "tslib": {
          "version": "2.3.0",
          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
          "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
          "dev": true
        }
      }
    },
    "@angular-devkit/build-optimizer": {
      "version": "0.1201.4",
      "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.1201.4.tgz",
      "integrity": "sha512-Hq+mDUe4xIyq4939JZaUkptsM89WnZOk8Qel6mS0T/bxMX/qs+nuGD5o+xDKkuayogbiTrLmyZBib0/90eSXEA==",
      "dev": true,
      "requires": {
        "source-map": "0.7.3",
        "tslib": "2.3.0",
        "typescript": "4.3.4"
      },
      "dependencies": {
        "tslib": {
          "version": "2.3.0",
          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
          "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
          "dev": true
        },
        "typescript": {
          "version": "4.3.4",
          "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz",
          "integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==",
          "dev": true
        }
      }
    },
    "@angular-devkit/build-webpack": {
      "version": "0.1201.4",
      "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1201.4.tgz",
      "integrity": "sha512-eMmbyHyWJZMQ1tfwVdja/iAk/eXJFYrF8b27gDV9gGI7MGB3KJ93AhkbPbcvlw4Hhx4+6M11GfeXzbwH0q9pnQ==",
      "dev": true,
      "requires": {
        "@angular-devkit/architect": "0.1201.4",
        "rxjs": "6.6.7"
      }
    },
    "@angular-devkit/core": {
      "version": "12.1.4",
      "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-12.1.4.tgz",
      "integrity": "sha512-KOzGD8JbP/7EeUwPiU5x+fo3ZEQ5R4IVW5WoH92PaO3mdpqXC7UL2MWLct8PUe9il9nqJMvrBMldSSvP9PCT2w==",
      "dev": true,
      "requires": {
        "ajv": "8.6.0",
        "ajv-formats": "2.1.0",
        "fast-json-stable-stringify": "2.1.0",
        "magic-string": "0.25.7",
        "rxjs": "6.6.7",
        "source-map": "0.7.3"
      }
    },
    "@angular-devkit/schematics": {
      "version": "12.1.4",
      "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-12.1.4.tgz",
      "integrity": "sha512-yD3y3pK/K5piOgvALFoCCiPp4H8emNa3yZL+vlpEpewVLpF1MM55LeTxc0PI5s0uqtOGVnvcbA5wYgMm3YsUEA==",
      "dev": true,
      "requires": {
        "@angular-devkit/core": "12.1.4",
        "ora": "5.4.1",
        "rxjs": "6.6.7"
      }
    },
    "@angular/animations": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-12.1.5.tgz",
      "integrity": "sha512-t17n8RuzkY7lYawmI01WuNWf70ttvEPknmS3sh7q2IAsBdRiLQCBmh6Hw5q0SBaQNoRWNIcUWKBwl4EmyXOtrA==",
      "requires": {
        "tslib": "^2.2.0"
      }
    },
    "@angular/cdk": {
      "version": "12.2.13",
      "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-12.2.13.tgz",
      "integrity": "sha512-zSKRhECyFqhingIeyRInIyTvYErt4gWo+x5DQr0b7YLUbU8DZSwWnG4w76Ke2s4U8T7ry1jpJBHoX/e8YBpGMg==",
      "requires": {
        "parse5": "^5.0.0",
        "tslib": "^2.2.0"
      }
    },
    "@angular/cli": {
      "version": "12.1.4",
      "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-12.1.4.tgz",
      "integrity": "sha512-LpyhyqWe3bFcuH3MrXeYoIPI1htjwG1b5ehETfq4qsMvNmuFON6QI+F7EWEpX7lItVQc2bES+ogasTZsZue/uw==",
      "dev": true,
      "requires": {
        "@angular-devkit/architect": "0.1201.4",
        "@angular-devkit/core": "12.1.4",
        "@angular-devkit/schematics": "12.1.4",
        "@schematics/angular": "12.1.4",
        "@yarnpkg/lockfile": "1.1.0",
        "ansi-colors": "4.1.1",
        "debug": "4.3.1",
        "ini": "2.0.0",
        "inquirer": "8.1.1",
        "jsonc-parser": "3.0.0",
        "npm-package-arg": "8.1.5",
        "npm-pick-manifest": "6.1.1",
        "open": "8.2.1",
        "ora": "5.4.1",
        "pacote": "11.3.4",
        "resolve": "1.20.0",
        "semver": "7.3.5",
        "symbol-observable": "4.0.0",
        "uuid": "8.3.2"
      }
    },
    "@angular/common": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/common/-/common-12.1.5.tgz",
      "integrity": "sha512-xs33eMhV79S85nbH5FVmujKY3OoczloW9oOGRe5tCzxsDDv85hadrB8Mbm3qI5WQ99DNk8M2+P0MW6uiyCAWkQ==",
      "requires": {
        "tslib": "^2.2.0"
      }
    },
    "@angular/compiler": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-12.1.5.tgz",
      "integrity": "sha512-MBrNCuTFmBiTy+sqmBYRqfBHPBJeONvRWOxHepn/CMtjHJiTZ+PHG61Chu2ySxLBuOZxAGaP4GMcqIc15G742g==",
      "requires": {
        "tslib": "^2.2.0"
      }
    },
    "@angular/compiler-cli": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-12.1.5.tgz",
      "integrity": "sha512-5YqZ5heKS3G5t3Fg9L26UedNnum8F9yjNDgUq0qvYR2b6nEDOLYgUxuUSRtg6IGDglSgbxpkgkGNd/SHF9Iu8A==",
      "dev": true,
      "requires": {
        "@babel/core": "^7.8.6",
        "@babel/types": "^7.8.6",
        "canonical-path": "1.0.0",
        "chokidar": "^3.0.0",
        "convert-source-map": "^1.5.1",
        "dependency-graph": "^0.11.0",
        "magic-string": "^0.25.0",
        "minimist": "^1.2.0",
        "reflect-metadata": "^0.1.2",
        "semver": "^7.0.0",
        "source-map": "^0.6.1",
        "sourcemap-codec": "^1.4.8",
        "tslib": "^2.2.0",
        "yargs": "^17.0.0"
      },
      "dependencies": {
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "@angular/core": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/core/-/core-12.1.5.tgz",
      "integrity": "sha512-okXnhAPxfblAWSe5M/IqrSATi+ul83a9o9PWOTFR/XCVcbx+neE2IwIr1dIDKBKj91b1CFalLS+uOSkN05PNkA==",
      "requires": {
        "tslib": "^2.2.0"
      }
    },
    "@angular/forms": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-12.1.5.tgz",
      "integrity": "sha512-ABfBRCZYVbR5MUkMNrYU/ovCjXtCedk0h4phzCimGl6hBcpbumT9z/3m0TsY9sQnLq0BaCfKNklnHwCuO9mSSg==",
      "requires": {
        "tslib": "^2.2.0"
      }
    },
    "@angular/material": {
      "version": "12.2.13",
      "resolved": "https://registry.npmjs.org/@angular/material/-/material-12.2.13.tgz",
      "integrity": "sha512-6g2GyN4qp2D+DqY2AwrQuPB3cd9gybvQVXvNRbTPXEulHr+LgGei00ySdFHFp6RvdGSMZ4i3LM1Fq3VkFxhCfQ==",
      "requires": {
        "tslib": "^2.2.0"
      }
    },
    "@angular/platform-browser": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-12.1.5.tgz",
      "integrity": "sha512-UNlmvCY8cS1/WojCJtgf/EMMN8qdPV1IQa6vZ6/ChQiS38YlH+aQEOCcxtSSfMFmWjaz7j67u55vSlkvA4rApQ==",
      "requires": {
        "tslib": "^2.2.0"
      }
    },
    "@angular/platform-browser-dynamic": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-12.1.5.tgz",
      "integrity": "sha512-4Anc2pRGRnBHzSeWMYOaEs6hUYw09N/WsOg1lHevZ8abwXyo80xOKiZa+kfgFkst0XaY8DzuDQFnj7opcEVdCQ==",
      "requires": {
        "tslib": "^2.2.0"
      }
    },
    "@angular/router": {
      "version": "12.1.5",
      "resolved": "https://registry.npmjs.org/@angular/router/-/router-12.1.5.tgz",
      "integrity": "sha512-ZZFLcaenVFKCyaxD3mU4cuV4RNFwCEN6JLWmkOFkwIt01RVJcvPaPxiv4pfQf5hnk2HeSciMA0J+UIzSu5YKMA==",
      "requires": {
        "tslib": "^2.2.0"
      }
    },
    "@babel/code-frame": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz",
      "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==",
      "dev": true,
      "requires": {
        "@babel/highlight": "^7.16.7"
      }
    },
    "@babel/compat-data": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz",
      "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==",
      "dev": true
    },
    "@babel/core": {
      "version": "7.14.6",
      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz",
      "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==",
      "dev": true,
      "requires": {
        "@babel/code-frame": "^7.14.5",
        "@babel/generator": "^7.14.5",
        "@babel/helper-compilation-targets": "^7.14.5",
        "@babel/helper-module-transforms": "^7.14.5",
        "@babel/helpers": "^7.14.6",
        "@babel/parser": "^7.14.6",
        "@babel/template": "^7.14.5",
        "@babel/traverse": "^7.14.5",
        "@babel/types": "^7.14.5",
        "convert-source-map": "^1.7.0",
        "debug": "^4.1.0",
        "gensync": "^1.0.0-beta.2",
        "json5": "^2.1.2",
        "semver": "^6.3.0",
        "source-map": "^0.5.0"
      },
      "dependencies": {
        "semver": {
          "version": "6.3.0",
          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
          "dev": true
        },
        "source-map": {
          "version": "0.5.7",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
          "dev": true
        }
      }
    },
    "@babel/generator": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
      "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
      "dev": true,
      "requires": {
        "@babel/types": "^7.14.5",
        "jsesc": "^2.5.1",
        "source-map": "^0.5.0"
      },
      "dependencies": {
        "source-map": {
          "version": "0.5.7",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
          "dev": true
        }
      }
    },
    "@babel/helper-annotate-as-pure": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz",
      "integrity": "sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==",
      "dev": true,
      "requires": {
        "@babel/types": "^7.14.5"
      }
    },
    "@babel/helper-builder-binary-assignment-operator-visitor": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz",
      "integrity": "sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA==",
      "dev": true,
      "requires": {
        "@babel/helper-explode-assignable-expression": "^7.16.7",
        "@babel/types": "^7.16.7"
      }
    },
    "@babel/helper-compilation-targets": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz",
      "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==",
      "dev": true,
      "requires": {
        "@babel/compat-data": "^7.16.4",
        "@babel/helper-validator-option": "^7.16.7",
        "browserslist": "^4.17.5",
        "semver": "^6.3.0"
      },
      "dependencies": {
        "semver": {
          "version": "6.3.0",
          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
          "dev": true
        }
      }
    },
    "@babel/helper-create-class-features-plugin": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.7.tgz",
      "integrity": "sha512-kIFozAvVfK05DM4EVQYKK+zteWvY85BFdGBRQBytRyY3y+6PX0DkDOn/CZ3lEuczCfrCxEzwt0YtP/87YPTWSw==",
      "dev": true,
      "requires": {
        "@babel/helper-annotate-as-pure": "^7.16.7",
        "@babel/helper-environment-visitor": "^7.16.7",
        "@babel/helper-function-name": "^7.16.7",
        "@babel/helper-member-expression-to-functions": "^7.16.7",
        "@babel/helper-optimise-call-expression": "^7.16.7",
        "@babel/helper-replace-supers": "^7.16.7",
        "@babel/helper-split-export-declaration": "^7.16.7"
      },
      "dependencies": {
        "@babel/helper-annotate-as-pure": {
          "version": "7.16.7",
          "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz",
          "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==",
          "dev": true,
          "requires": {
            "@babel/types": "^7.16.7"
          }
        }
      }
    },
    "@babel/helper-create-regexp-features-plugin": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz",
      "integrity": "sha512-fk5A6ymfp+O5+p2yCkXAu5Kyj6v0xh0RBeNcAkYUMDvvAAoxvSKXn+Jb37t/yWFiQVDFK1ELpUTD8/aLhCPu+g==",
      "dev": true,
      "requires": {
        "@babel/helper-annotate-as-pure": "^7.16.7",
        "regexpu-core": "^4.7.1"
      },
      "dependencies": {
        "@babel/helper-annotate-as-pure": {
          "version": "7.16.7",
          "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz",
          "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==",
          "dev": true,
          "requires": {
            "@babel/types": "^7.16.7"
          }
        }
      }
    },
    "@babel/helper-define-polyfill-provider": {
      "version": "0.2.4",
      "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.4.tgz",
      "integrity": "sha512-OrpPZ97s+aPi6h2n1OXzdhVis1SGSsMU2aMHgLcOKfsp4/v1NWpx3CWT3lBj5eeBq9cDkPkh+YCfdF7O12uNDQ==",
      "dev": true,
      "requires": {
        "@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"
      },
      "dependencies": {
        "semver": {
          "version": "6.3.0",
          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
          "dev": true
        }
      }
    },
    "@babel/helper-environment-visitor": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz",
      "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==",
      "dev": true,
      "requires": {
        "@babel/types": "^7.16.7"
      }
    },
    "@babel/helper-explode-assignable-expression": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz",
      "integrity": "sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==",
      "dev": true,
      "requires": {
        "@babel/types": "^7.16.7"
      }
    },
    "@babel/helper-function-name": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz",
      "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==",
      "dev": true,
      "requires": {
        "@babel/helper-get-function-arity": "^7.16.7",
        "@babel/template": "^7.16.7",
        "@babel/types": "^7.16.7"
      },
      "dependencies": {
        "@babel/template": {
          "version": "7.16.7",
          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz",
          "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==",
          "dev": true,
          "requires": {
            "@babel/code-frame": "^7.16.7",
            "@babel/parser": "^7.16.7",
            "@babel/types": "^7.16.7"
          }
        }
      }
    },
    "@babel/helper-get-function-arity": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz",
      "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==",
      "dev": true,
      "requires": {
        "@babel/types": "^7.16.7"
      }
    },
    "@babel/helper-hoist-variables": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz",
      "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==",
      "dev": true,
      "requires": {
        "@babel/types": "^7.16.7"
      }
    },
    "@babel/helper-member-expression-to-functions": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz",
      "integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==",
      "dev": true,
      "requires": {
        "@babel/types": "^7.16.7"
      }
    },
    "@babel/helper-module-imports": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz",
      "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==",
      "dev": true,
      "requires": {
        "@babel/types": "^7.16.7"
      }
    },
    "@babel/helper-module-transforms": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz",
      "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==",
      "dev": true,
      "requires": {
        "@babel/helper-environment-visitor": "^7.16.7",
        "@babel/helper-module-imports": "^7.16.7",
        "@babel/helper-simple-access": "^7.16.7",
        "@babel/helper-split-export-declaration": "^7.16.7",
        "@babel/helper-validator-identifier": "^7.16.7",
        "@babel/template": "^7.16.7",
        "@babel/traverse": "^7.16.7",
        "@babel/types": "^7.16.7"
      },
      "dependencies": {
        "@babel/template": {
          "version": "7.16.7",
          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz",
          "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==",
          "dev": true,
          "requires": {
            "@babel/code-frame": "^7.16.7",
            "@babel/parser": "^7.16.7",
            "@babel/types": "^7.16.7"
          }
        }
      }
    },
    "@babel/helper-optimise-call-expression": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz",
      "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==",
      "dev": true,
      "requires": {
        "@babel/types": "^7.16.7"
      }
    },
    "@babel/helper-plugin-utils": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz",
      "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==",
      "dev": true
    },
    "@babel/helper-remap-async-to-generator": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz",
      "integrity": "sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw==",
      "dev": true,
      "requires": {
        "@babel/helper-annotate-as-pure": "^7.16.7",
        "@babel/helper-wrap-function": "^7.16.8",
        "@babel/types": "^7.16.8"
      },
      "dependencies": {
        "@babel/helper-annotate-as-pure": {
          "version": "7.16.7",
          "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz",
          "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==",
          "dev": true,
          "requires": {
            "@babel/types": "^7.16.7"
          }
        }
      }
    },
    "@babel/helper-replace-supers": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz",
      "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==",
      "dev": true,
      "requires": {
        "@babel/helper-environment-visitor": "^7.16.7",
        "@babel/helper-member-expression-to-functions": "^7.16.7",
        "@babel/helper-optimise-call-expression": "^7.16.7",
        "@babel/traverse": "^7.16.7",
        "@babel/types": "^7.16.7"
      }
    },
    "@babel/helper-simple-access": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz",
      "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==",
      "dev": true,
      "requires": {
        "@babel/types": "^7.16.7"
      }
    },
    "@babel/helper-skip-transparent-expression-wrappers": {
      "version": "7.16.0",
      "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz",
      "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==",
      "dev": true,
      "requires": {
        "@babel/types": "^7.16.0"
      }
    },
    "@babel/helper-split-export-declaration": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz",
      "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==",
      "dev": true,
      "requires": {
        "@babel/types": "^7.16.7"
      }
    },
    "@babel/helper-validator-identifier": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz",
      "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==",
      "dev": true
    },
    "@babel/helper-validator-option": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz",
      "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==",
      "dev": true
    },
    "@babel/helper-wrap-function": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz",
      "integrity": "sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw==",
      "dev": true,
      "requires": {
        "@babel/helper-function-name": "^7.16.7",
        "@babel/template": "^7.16.7",
        "@babel/traverse": "^7.16.8",
        "@babel/types": "^7.16.8"
      },
      "dependencies": {
        "@babel/template": {
          "version": "7.16.7",
          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz",
          "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==",
          "dev": true,
          "requires": {
            "@babel/code-frame": "^7.16.7",
            "@babel/parser": "^7.16.7",
            "@babel/types": "^7.16.7"
          }
        }
      }
    },
    "@babel/helpers": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz",
      "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==",
      "dev": true,
      "requires": {
        "@babel/template": "^7.16.7",
        "@babel/traverse": "^7.16.7",
        "@babel/types": "^7.16.7"
      },
      "dependencies": {
        "@babel/template": {
          "version": "7.16.7",
          "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz",
          "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==",
          "dev": true,
          "requires": {
            "@babel/code-frame": "^7.16.7",
            "@babel/parser": "^7.16.7",
            "@babel/types": "^7.16.7"
          }
        }
      }
    },
    "@babel/highlight": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz",
      "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==",
      "dev": true,
      "requires": {
        "@babel/helper-validator-identifier": "^7.16.7",
        "chalk": "^2.0.0",
        "js-tokens": "^4.0.0"
      }
    },
    "@babel/parser": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.8.tgz",
      "integrity": "sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw==",
      "dev": true
    },
    "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz",
      "integrity": "sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0",
        "@babel/plugin-proposal-optional-chaining": "^7.16.7"
      }
    },
    "@babel/plugin-proposal-async-generator-functions": {
      "version": "7.14.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz",
      "integrity": "sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.14.5",
        "@babel/helper-remap-async-to-generator": "^7.14.5",
        "@babel/plugin-syntax-async-generators": "^7.8.4"
      }
    },
    "@babel/plugin-proposal-class-properties": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz",
      "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==",
      "dev": true,
      "requires": {
        "@babel/helper-create-class-features-plugin": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-proposal-class-static-block": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.7.tgz",
      "integrity": "sha512-dgqJJrcZoG/4CkMopzhPJjGxsIe9A8RlkQLnL/Vhhx8AA9ZuaRwGSlscSh42hazc7WSrya/IK7mTeoF0DP9tEw==",
      "dev": true,
      "requires": {
        "@babel/helper-create-class-features-plugin": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-class-static-block": "^7.14.5"
      }
    },
    "@babel/plugin-proposal-dynamic-import": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz",
      "integrity": "sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-dynamic-import": "^7.8.3"
      }
    },
    "@babel/plugin-proposal-export-namespace-from": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz",
      "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
      }
    },
    "@babel/plugin-proposal-json-strings": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz",
      "integrity": "sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-json-strings": "^7.8.3"
      }
    },
    "@babel/plugin-proposal-logical-assignment-operators": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz",
      "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
      }
    },
    "@babel/plugin-proposal-nullish-coalescing-operator": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz",
      "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
      }
    },
    "@babel/plugin-proposal-numeric-separator": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz",
      "integrity": "sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-numeric-separator": "^7.10.4"
      }
    },
    "@babel/plugin-proposal-object-rest-spread": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.7.tgz",
      "integrity": "sha512-3O0Y4+dw94HA86qSg9IHfyPktgR7q3gpNVAeiKQd+8jBKFaU5NQS1Yatgo4wY+UFNuLjvxcSmzcsHqrhgTyBUA==",
      "dev": true,
      "requires": {
        "@babel/compat-data": "^7.16.4",
        "@babel/helper-compilation-targets": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
        "@babel/plugin-transform-parameters": "^7.16.7"
      }
    },
    "@babel/plugin-proposal-optional-catch-binding": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz",
      "integrity": "sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
      }
    },
    "@babel/plugin-proposal-optional-chaining": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz",
      "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0",
        "@babel/plugin-syntax-optional-chaining": "^7.8.3"
      }
    },
    "@babel/plugin-proposal-private-methods": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.7.tgz",
      "integrity": "sha512-7twV3pzhrRxSwHeIvFE6coPgvo+exNDOiGUMg39o2LiLo1Y+4aKpfkcLGcg1UHonzorCt7SNXnoMyCnnIOA8Sw==",
      "dev": true,
      "requires": {
        "@babel/helper-create-class-features-plugin": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-proposal-private-property-in-object": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz",
      "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==",
      "dev": true,
      "requires": {
        "@babel/helper-annotate-as-pure": "^7.16.7",
        "@babel/helper-create-class-features-plugin": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
      },
      "dependencies": {
        "@babel/helper-annotate-as-pure": {
          "version": "7.16.7",
          "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz",
          "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==",
          "dev": true,
          "requires": {
            "@babel/types": "^7.16.7"
          }
        }
      }
    },
    "@babel/plugin-proposal-unicode-property-regex": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz",
      "integrity": "sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==",
      "dev": true,
      "requires": {
        "@babel/helper-create-regexp-features-plugin": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-syntax-async-generators": {
      "version": "7.8.4",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
      "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.8.0"
      }
    },
    "@babel/plugin-syntax-class-properties": {
      "version": "7.12.13",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
      "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.12.13"
      }
    },
    "@babel/plugin-syntax-class-static-block": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
      "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.14.5"
      }
    },
    "@babel/plugin-syntax-dynamic-import": {
      "version": "7.8.3",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
      "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.8.0"
      }
    },
    "@babel/plugin-syntax-export-namespace-from": {
      "version": "7.8.3",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
      "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.8.3"
      }
    },
    "@babel/plugin-syntax-json-strings": {
      "version": "7.8.3",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
      "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.8.0"
      }
    },
    "@babel/plugin-syntax-logical-assignment-operators": {
      "version": "7.10.4",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
      "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.10.4"
      }
    },
    "@babel/plugin-syntax-nullish-coalescing-operator": {
      "version": "7.8.3",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
      "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.8.0"
      }
    },
    "@babel/plugin-syntax-numeric-separator": {
      "version": "7.10.4",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
      "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.10.4"
      }
    },
    "@babel/plugin-syntax-object-rest-spread": {
      "version": "7.8.3",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
      "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.8.0"
      }
    },
    "@babel/plugin-syntax-optional-catch-binding": {
      "version": "7.8.3",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
      "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.8.0"
      }
    },
    "@babel/plugin-syntax-optional-chaining": {
      "version": "7.8.3",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
      "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.8.0"
      }
    },
    "@babel/plugin-syntax-private-property-in-object": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
      "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.14.5"
      }
    },
    "@babel/plugin-syntax-top-level-await": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
      "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.14.5"
      }
    },
    "@babel/plugin-transform-arrow-functions": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz",
      "integrity": "sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-async-to-generator": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz",
      "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==",
      "dev": true,
      "requires": {
        "@babel/helper-module-imports": "^7.14.5",
        "@babel/helper-plugin-utils": "^7.14.5",
        "@babel/helper-remap-async-to-generator": "^7.14.5"
      }
    },
    "@babel/plugin-transform-block-scoped-functions": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz",
      "integrity": "sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-block-scoping": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz",
      "integrity": "sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-classes": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz",
      "integrity": "sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==",
      "dev": true,
      "requires": {
        "@babel/helper-annotate-as-pure": "^7.16.7",
        "@babel/helper-environment-visitor": "^7.16.7",
        "@babel/helper-function-name": "^7.16.7",
        "@babel/helper-optimise-call-expression": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/helper-replace-supers": "^7.16.7",
        "@babel/helper-split-export-declaration": "^7.16.7",
        "globals": "^11.1.0"
      },
      "dependencies": {
        "@babel/helper-annotate-as-pure": {
          "version": "7.16.7",
          "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz",
          "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==",
          "dev": true,
          "requires": {
            "@babel/types": "^7.16.7"
          }
        }
      }
    },
    "@babel/plugin-transform-computed-properties": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz",
      "integrity": "sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-destructuring": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz",
      "integrity": "sha512-VqAwhTHBnu5xBVDCvrvqJbtLUa++qZaWC0Fgr2mqokBlulZARGyIvZDoqbPlPaKImQ9dKAcCzbv+ul//uqu70A==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-dotall-regex": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz",
      "integrity": "sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==",
      "dev": true,
      "requires": {
        "@babel/helper-create-regexp-features-plugin": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-duplicate-keys": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz",
      "integrity": "sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-exponentiation-operator": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz",
      "integrity": "sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA==",
      "dev": true,
      "requires": {
        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-for-of": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz",
      "integrity": "sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-function-name": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz",
      "integrity": "sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA==",
      "dev": true,
      "requires": {
        "@babel/helper-compilation-targets": "^7.16.7",
        "@babel/helper-function-name": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-literals": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz",
      "integrity": "sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-member-expression-literals": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz",
      "integrity": "sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-modules-amd": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz",
      "integrity": "sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==",
      "dev": true,
      "requires": {
        "@babel/helper-module-transforms": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7",
        "babel-plugin-dynamic-import-node": "^2.3.3"
      }
    },
    "@babel/plugin-transform-modules-commonjs": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz",
      "integrity": "sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==",
      "dev": true,
      "requires": {
        "@babel/helper-module-transforms": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/helper-simple-access": "^7.16.7",
        "babel-plugin-dynamic-import-node": "^2.3.3"
      }
    },
    "@babel/plugin-transform-modules-systemjs": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz",
      "integrity": "sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw==",
      "dev": true,
      "requires": {
        "@babel/helper-hoist-variables": "^7.16.7",
        "@babel/helper-module-transforms": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/helper-validator-identifier": "^7.16.7",
        "babel-plugin-dynamic-import-node": "^2.3.3"
      }
    },
    "@babel/plugin-transform-modules-umd": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz",
      "integrity": "sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==",
      "dev": true,
      "requires": {
        "@babel/helper-module-transforms": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-named-capturing-groups-regex": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz",
      "integrity": "sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==",
      "dev": true,
      "requires": {
        "@babel/helper-create-regexp-features-plugin": "^7.16.7"
      }
    },
    "@babel/plugin-transform-new-target": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz",
      "integrity": "sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-object-super": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz",
      "integrity": "sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/helper-replace-supers": "^7.16.7"
      }
    },
    "@babel/plugin-transform-parameters": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz",
      "integrity": "sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-property-literals": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz",
      "integrity": "sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-regenerator": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz",
      "integrity": "sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==",
      "dev": true,
      "requires": {
        "regenerator-transform": "^0.14.2"
      }
    },
    "@babel/plugin-transform-reserved-words": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz",
      "integrity": "sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-runtime": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.5.tgz",
      "integrity": "sha512-fPMBhh1AV8ZyneiCIA+wYYUH1arzlXR1UMcApjvchDhfKxhy2r2lReJv8uHEyihi4IFIGlr1Pdx7S5fkESDQsg==",
      "dev": true,
      "requires": {
        "@babel/helper-module-imports": "^7.14.5",
        "@babel/helper-plugin-utils": "^7.14.5",
        "babel-plugin-polyfill-corejs2": "^0.2.2",
        "babel-plugin-polyfill-corejs3": "^0.2.2",
        "babel-plugin-polyfill-regenerator": "^0.2.2",
        "semver": "^6.3.0"
      },
      "dependencies": {
        "semver": {
          "version": "6.3.0",
          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
          "dev": true
        }
      }
    },
    "@babel/plugin-transform-shorthand-properties": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz",
      "integrity": "sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-spread": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz",
      "integrity": "sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7",
        "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0"
      }
    },
    "@babel/plugin-transform-sticky-regex": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz",
      "integrity": "sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-template-literals": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz",
      "integrity": "sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-typeof-symbol": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz",
      "integrity": "sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-unicode-escapes": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz",
      "integrity": "sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q==",
      "dev": true,
      "requires": {
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/plugin-transform-unicode-regex": {
      "version": "7.16.7",
      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz",
      "integrity": "sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q==",
      "dev": true,
      "requires": {
        "@babel/helper-create-regexp-features-plugin": "^7.16.7",
        "@babel/helper-plugin-utils": "^7.16.7"
      }
    },
    "@babel/preset-env": {
      "version": "7.14.7",
      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.7.tgz",
      "integrity": "sha512-itOGqCKLsSUl0Y+1nSfhbuuOlTs0MJk2Iv7iSH+XT/mR8U1zRLO7NjWlYXB47yhK4J/7j+HYty/EhFZDYKa/VA==",
      "dev": true,
      "requires": {
        "@babel/compat-data": "^7.14.7",
        "@babel/helper-compilation-targets": "^7.14.5",
        "@babel/helper-plugin-utils": "^7.14.5",
        "@babel/helper-validator-option": "^7.14.5",
        "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.14.5",
        "@babel/plugin-proposal-async-generator-functions": "^7.14.7",
        "@babel/plugin-proposal-class-properties": "^7.14.5",
        "@babel/plugin-proposal-class-static-block": "^7.14.5",
        "@babel/plugin-proposal-dynamic-import": "^7.14.5",
        "@babel/plugin-proposal-export-namespace-from": "^7.14.5",
        "@babel/plugin-proposal-json-strings": "^7.14.5",
        "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5",
        "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5",
        "@babel/plugin-proposal-numeric-separator": "^7.14.5",
        "@babel/plugin-proposal-object-rest-spread": "^7.14.7",
        "@babel/plugin-proposal-optional-catch-binding": "^7.14.5",
        "@babel/plugin-proposal-optional-chaining": "^7.14.5",
        "@babel/plugin-proposal-private-methods": "^7.14.5",
        "@babel/plugin-proposal-private-property-in-object": "^7.14.5",
        "@babel/plugin-proposal-unicode-property-regex": "^7.14.5",
        "@babel/plugin-syntax-async-generators": "^7.8.4",
        "@babel/plugin-syntax-class-properties": "^7.12.13",
        "@babel/plugin-syntax-class-static-block": "^7.14.5",
        "@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-private-property-in-object": "^7.14.5",
        "@babel/plugin-syntax-top-level-await": "^7.14.5",
        "@babel/plugin-transform-arrow-functions": "^7.14.5",
        "@babel/plugin-transform-async-to-generator": "^7.14.5",
        "@babel/plugin-transform-block-scoped-functions": "^7.14.5",
        "@babel/plugin-transform-block-scoping": "^7.14.5",
        "@babel/plugin-transform-classes": "^7.14.5",
        "@babel/plugin-transform-computed-properties": "^7.14.5",
        "@babel/plugin-transform-destructuring": "^7.14.7",
        "@babel/plugin-transform-dotall-regex": "^7.14.5",
        "@babel/plugin-transform-duplicate-keys": "^7.14.5",
        "@babel/plugin-transform-exponentiation-operator": "^7.14.5",
        "@babel/plugin-transform-for-of": "^7.14.5",
        "@babel/plugin-transform-function-name": "^7.14.5",
        "@babel/plugin-transform-literals": "^7.14.5",
        "@babel/plugin-transform-member-expression-literals": "^7.14.5",
        "@babel/plugin-transform-modules-amd": "^7.14.5",
        "@babel/plugin-transform-modules-commonjs": "^7.14.5",
        "@babel/plugin-transform-modules-systemjs": "^7.14.5",
        "@babel/plugin-transform-modules-umd": "^7.14.5",
        "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.7",
        "@babel/plugin-transform-new-target": "^7.14.5",
        "@babel/plugin-transform-object-super": "^7.14.5",
        "@babel/plugin-transform-parameters": "^7.14.5",
        "@babel/plugin-transform-property-literals": "^7.14.5",
        "@babel/plugin-transform-regenerator": "^7.14.5",
        "@babel/plugin-transform-reserved-words": "^7.14.5",
        "@babel/plugin-transform-shorthand-properties": "^7.14.5",
        "@babel/plugin-transform-spread": "^7.14.6",
        "@babel/plugin-transform-sticky-regex": "^7.14.5",
        "@babel/plugin-transform-template-literals": "^7.14.5",
        "@babel/plugin-transform-typeof-symbol": "^7.14.5",
        "@babel/plugin-transform-unicode-escapes": "^7.14.5",
        "@babel/plugin-transform-unicode-regex": "^7.14.5",
        "@babel/preset-modules": "^0.1.4",
        "@babel/types": "^7.14.5",
        "babel-plugin-polyfill-corejs2": "^0.2.2",
        "babel-plugin-polyfill-corejs3": "^0.2.2",
        "babel-plugin-polyfill-regenerator": "^0.2.2",
        "core-js-compat": "^3.15.0",
        "semver": "^6.3.0"
      },
      "dependencies": {
        "semver": {
          "version": "6.3.0",
          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
          "dev": true
        }
      }
    },
    "@babel/preset-modules": {
      "version": "0.1.5",
      "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz",
      "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==",
      "dev": true,
      "requires": {
        "@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/runtime": {
      "version": "7.14.6",
      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz",
      "integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==",
      "dev": true,
      "requires": {
        "regenerator-runtime": "^0.13.4"
      }
    },
    "@babel/template": {
      "version": "7.14.5",
      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
      "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
      "dev": true,
      "requires": {
        "@babel/code-frame": "^7.14.5",
        "@babel/parser": "^7.14.5",
        "@babel/types": "^7.14.5"
      }
    },
    "@babel/traverse": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.8.tgz",
      "integrity": "sha512-xe+H7JlvKsDQwXRsBhSnq1/+9c+LlQcCK3Tn/l5sbx02HYns/cn7ibp9+RV1sIUqu7hKg91NWsgHurO9dowITQ==",
      "dev": true,
      "requires": {
        "@babel/code-frame": "^7.16.7",
        "@babel/generator": "^7.16.8",
        "@babel/helper-environment-visitor": "^7.16.7",
        "@babel/helper-function-name": "^7.16.7",
        "@babel/helper-hoist-variables": "^7.16.7",
        "@babel/helper-split-export-declaration": "^7.16.7",
        "@babel/parser": "^7.16.8",
        "@babel/types": "^7.16.8",
        "debug": "^4.1.0",
        "globals": "^11.1.0"
      },
      "dependencies": {
        "@babel/generator": {
          "version": "7.16.8",
          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz",
          "integrity": "sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==",
          "dev": true,
          "requires": {
            "@babel/types": "^7.16.8",
            "jsesc": "^2.5.1",
            "source-map": "^0.5.0"
          }
        },
        "source-map": {
          "version": "0.5.7",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
          "dev": true
        }
      }
    },
    "@babel/types": {
      "version": "7.16.8",
      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz",
      "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==",
      "dev": true,
      "requires": {
        "@babel/helper-validator-identifier": "^7.16.7",
        "to-fast-properties": "^2.0.0"
      }
    },
    "@csstools/convert-colors": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz",
      "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==",
      "dev": true
    },
    "@discoveryjs/json-ext": {
      "version": "0.5.3",
      "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz",
      "integrity": "sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==",
      "dev": true
    },
    "@istanbuljs/schema": {
      "version": "0.1.3",
      "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
      "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
      "dev": true
    },
    "@jsdevtools/coverage-istanbul-loader": {
      "version": "3.0.5",
      "resolved": "https://registry.npmjs.org/@jsdevtools/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.5.tgz",
      "integrity": "sha512-EUCPEkaRPvmHjWAAZkWMT7JDzpw7FKB00WTISaiXsbNOd5hCHg77XLA8sLYLFDo1zepYLo2w7GstN8YBqRXZfA==",
      "dev": true,
      "requires": {
        "convert-source-map": "^1.7.0",
        "istanbul-lib-instrument": "^4.0.3",
        "loader-utils": "^2.0.0",
        "merge-source-map": "^1.1.0",
        "schema-utils": "^2.7.0"
      }
    },
    "@juggle/resize-observer": {
      "version": "3.3.1",
      "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.3.1.tgz",
      "integrity": "sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw=="
    },
    "@ngtools/webpack": {
      "version": "12.1.4",
      "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-12.1.4.tgz",
      "integrity": "sha512-hXc8dTnRfDB7o1Pd7a07aw0rjGmVLXU28+cTHQJliosgD3obcjfZ4QPA0k97vlQMtqVJawuShRfyiUKrpsJf8Q==",
      "dev": true,
      "requires": {
        "enhanced-resolve": "5.8.2"
      }
    },
    "@nodelib/fs.scandir": {
      "version": "2.1.5",
      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
      "dev": true,
      "requires": {
        "@nodelib/fs.stat": "2.0.5",
        "run-parallel": "^1.1.9"
      }
    },
    "@nodelib/fs.stat": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
      "dev": true
    },
    "@nodelib/fs.walk": {
      "version": "1.2.8",
      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
      "dev": true,
      "requires": {
        "@nodelib/fs.scandir": "2.1.5",
        "fastq": "^1.6.0"
      }
    },
    "@npmcli/git": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-2.1.0.tgz",
      "integrity": "sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw==",
      "dev": true,
      "requires": {
        "@npmcli/promise-spawn": "^1.3.2",
        "lru-cache": "^6.0.0",
        "mkdirp": "^1.0.4",
        "npm-pick-manifest": "^6.1.1",
        "promise-inflight": "^1.0.1",
        "promise-retry": "^2.0.1",
        "semver": "^7.3.5",
        "which": "^2.0.2"
      },
      "dependencies": {
        "which": {
          "version": "2.0.2",
          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
          "dev": true,
          "requires": {
            "isexe": "^2.0.0"
          }
        }
      }
    },
    "@npmcli/installed-package-contents": {
      "version": "1.0.7",
      "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz",
      "integrity": "sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==",
      "dev": true,
      "requires": {
        "npm-bundled": "^1.1.1",
        "npm-normalize-package-bin": "^1.0.1"
      }
    },
    "@npmcli/move-file": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
      "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
      "dev": true,
      "requires": {
        "mkdirp": "^1.0.4",
        "rimraf": "^3.0.2"
      }
    },
    "@npmcli/node-gyp": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz",
      "integrity": "sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA==",
      "dev": true
    },
    "@npmcli/promise-spawn": {
      "version": "1.3.2",
      "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz",
      "integrity": "sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg==",
      "dev": true,
      "requires": {
        "infer-owner": "^1.0.4"
      }
    },
    "@npmcli/run-script": {
      "version": "1.8.6",
      "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-1.8.6.tgz",
      "integrity": "sha512-e42bVZnC6VluBZBAFEr3YrdqSspG3bgilyg4nSLBJ7TRGNCzxHa92XAHxQBLYg0BmgwO4b2mf3h/l5EkEWRn3g==",
      "dev": true,
      "requires": {
        "@npmcli/node-gyp": "^1.0.2",
        "@npmcli/promise-spawn": "^1.3.2",
        "node-gyp": "^7.1.0",
        "read-package-json-fast": "^2.0.1"
      }
    },
    "@schematics/angular": {
      "version": "12.1.4",
      "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-12.1.4.tgz",
      "integrity": "sha512-xGqgGI6GWk4EFdKis8FmSESxoLgjnLQbaRE1t1KZCkSKJzqkOj0R9wiDrtZfcrbPxIkLL+3fAk2ThwwPznT6yw==",
      "dev": true,
      "requires": {
        "@angular-devkit/core": "12.1.4",
        "@angular-devkit/schematics": "12.1.4",
        "jsonc-parser": "3.0.0"
      }
    },
    "@socket.io/base64-arraybuffer": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
      "integrity": "sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==",
      "dev": true
    },
    "@tootallnate/once": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
      "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
      "dev": true
    },
    "@trysound/sax": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
      "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
      "dev": true
    },
    "@types/component-emitter": {
      "version": "1.2.11",
      "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz",
      "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==",
      "dev": true
    },
    "@types/cookie": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
      "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==",
      "dev": true
    },
    "@types/cors": {
      "version": "2.8.12",
      "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
      "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==",
      "dev": true
    },
    "@types/eslint": {
      "version": "8.2.2",
      "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.2.tgz",
      "integrity": "sha512-nQxgB8/Sg+QKhnV8e0WzPpxjIGT3tuJDDzybkDi8ItE/IgTlHo07U0shaIjzhcvQxlq9SDRE42lsJ23uvEgJ2A==",
      "dev": true,
      "requires": {
        "@types/estree": "*",
        "@types/json-schema": "*"
      }
    },
    "@types/eslint-scope": {
      "version": "3.7.3",
      "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz",
      "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==",
      "dev": true,
      "requires": {
        "@types/eslint": "*",
        "@types/estree": "*"
      }
    },
    "@types/estree": {
      "version": "0.0.50",
      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
      "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==",
      "dev": true
    },
    "@types/glob": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
      "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
      "dev": true,
      "requires": {
        "@types/minimatch": "*",
        "@types/node": "*"
      }
    },
    "@types/jasmine": {
      "version": "3.6.11",
      "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-3.6.11.tgz",
      "integrity": "sha512-S6pvzQDvMZHrkBz2Mcn/8Du7cpr76PlRJBAoHnSDNbulULsH5dp0Gns+WRyNX5LHejz/ljxK4/vIHK/caHt6SQ==",
      "dev": true
    },
    "@types/json-schema": {
      "version": "7.0.9",
      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
      "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
      "dev": true
    },
    "@types/minimatch": {
      "version": "3.0.5",
      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
      "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==",
      "dev": true
    },
    "@types/node": {
      "version": "12.20.42",
      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.42.tgz",
      "integrity": "sha512-aI3/oo5DzyiI5R/xAhxxRzfZlWlsbbqdgxfTPkqu/Zt+23GXiJvMCyPJT4+xKSXOnLqoL8jJYMLTwvK2M3a5hw==",
      "dev": true
    },
    "@types/parse-json": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
      "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
      "dev": true
    },
    "@types/source-list-map": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
      "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==",
      "dev": true
    },
    "@types/webpack-sources": {
      "version": "0.1.9",
      "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.9.tgz",
      "integrity": "sha512-bvzMnzqoK16PQIC8AYHNdW45eREJQMd6WG/msQWX5V2+vZmODCOPb4TJcbgRljTZZTwTM4wUMcsI8FftNA7new==",
      "dev": true,
      "requires": {
        "@types/node": "*",
        "@types/source-list-map": "*",
        "source-map": "^0.6.1"
      },
      "dependencies": {
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "@webassemblyjs/ast": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
      "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
      "dev": true,
      "requires": {
        "@webassemblyjs/helper-numbers": "1.11.1",
        "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
      }
    },
    "@webassemblyjs/floating-point-hex-parser": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
      "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
      "dev": true
    },
    "@webassemblyjs/helper-api-error": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
      "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
      "dev": true
    },
    "@webassemblyjs/helper-buffer": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
      "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
      "dev": true
    },
    "@webassemblyjs/helper-numbers": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
      "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
      "dev": true,
      "requires": {
        "@webassemblyjs/floating-point-hex-parser": "1.11.1",
        "@webassemblyjs/helper-api-error": "1.11.1",
        "@xtuc/long": "4.2.2"
      }
    },
    "@webassemblyjs/helper-wasm-bytecode": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
      "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
      "dev": true
    },
    "@webassemblyjs/helper-wasm-section": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
      "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
      "dev": true,
      "requires": {
        "@webassemblyjs/ast": "1.11.1",
        "@webassemblyjs/helper-buffer": "1.11.1",
        "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
        "@webassemblyjs/wasm-gen": "1.11.1"
      }
    },
    "@webassemblyjs/ieee754": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
      "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
      "dev": true,
      "requires": {
        "@xtuc/ieee754": "^1.2.0"
      }
    },
    "@webassemblyjs/leb128": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
      "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
      "dev": true,
      "requires": {
        "@xtuc/long": "4.2.2"
      }
    },
    "@webassemblyjs/utf8": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
      "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
      "dev": true
    },
    "@webassemblyjs/wasm-edit": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
      "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
      "dev": true,
      "requires": {
        "@webassemblyjs/ast": "1.11.1",
        "@webassemblyjs/helper-buffer": "1.11.1",
        "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
        "@webassemblyjs/helper-wasm-section": "1.11.1",
        "@webassemblyjs/wasm-gen": "1.11.1",
        "@webassemblyjs/wasm-opt": "1.11.1",
        "@webassemblyjs/wasm-parser": "1.11.1",
        "@webassemblyjs/wast-printer": "1.11.1"
      }
    },
    "@webassemblyjs/wasm-gen": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
      "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
      "dev": true,
      "requires": {
        "@webassemblyjs/ast": "1.11.1",
        "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
        "@webassemblyjs/ieee754": "1.11.1",
        "@webassemblyjs/leb128": "1.11.1",
        "@webassemblyjs/utf8": "1.11.1"
      }
    },
    "@webassemblyjs/wasm-opt": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
      "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
      "dev": true,
      "requires": {
        "@webassemblyjs/ast": "1.11.1",
        "@webassemblyjs/helper-buffer": "1.11.1",
        "@webassemblyjs/wasm-gen": "1.11.1",
        "@webassemblyjs/wasm-parser": "1.11.1"
      }
    },
    "@webassemblyjs/wasm-parser": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
      "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
      "dev": true,
      "requires": {
        "@webassemblyjs/ast": "1.11.1",
        "@webassemblyjs/helper-api-error": "1.11.1",
        "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
        "@webassemblyjs/ieee754": "1.11.1",
        "@webassemblyjs/leb128": "1.11.1",
        "@webassemblyjs/utf8": "1.11.1"
      }
    },
    "@webassemblyjs/wast-printer": {
      "version": "1.11.1",
      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
      "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
      "dev": true,
      "requires": {
        "@webassemblyjs/ast": "1.11.1",
        "@xtuc/long": "4.2.2"
      }
    },
    "@xtuc/ieee754": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
      "dev": true
    },
    "@xtuc/long": {
      "version": "4.2.2",
      "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
      "dev": true
    },
    "@yarnpkg/lockfile": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
      "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
      "dev": true
    },
    "abab": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
      "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==",
      "dev": true
    },
    "abbrev": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
      "dev": true
    },
    "accepts": {
      "version": "1.3.7",
      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
      "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
      "dev": true,
      "requires": {
        "mime-types": "~2.1.24",
        "negotiator": "0.6.2"
      }
    },
    "acorn": {
      "version": "8.7.0",
      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
      "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
      "dev": true
    },
    "adjust-sourcemap-loader": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz",
      "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==",
      "dev": true,
      "requires": {
        "loader-utils": "^2.0.0",
        "regex-parser": "^2.2.11"
      }
    },
    "agent-base": {
      "version": "6.0.2",
      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
      "dev": true,
      "requires": {
        "debug": "4"
      }
    },
    "agentkeepalive": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.0.tgz",
      "integrity": "sha512-0PhAp58jZNw13UJv7NVdTGb0ZcghHUb3DrZ046JiiJY/BOaTTpbwdHq2VObPCBV8M2GPh7sgrJ3AQ8Ey468LJw==",
      "dev": true,
      "requires": {
        "debug": "^4.1.0",
        "depd": "^1.1.2",
        "humanize-ms": "^1.2.1"
      }
    },
    "aggregate-error": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
      "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
      "dev": true,
      "requires": {
        "clean-stack": "^2.0.0",
        "indent-string": "^4.0.0"
      }
    },
    "ajv": {
      "version": "8.6.0",
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz",
      "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==",
      "dev": true,
      "requires": {
        "fast-deep-equal": "^3.1.1",
        "json-schema-traverse": "^1.0.0",
        "require-from-string": "^2.0.2",
        "uri-js": "^4.2.2"
      }
    },
    "ajv-errors": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
      "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
      "dev": true,
      "requires": {}
    },
    "ajv-formats": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz",
      "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==",
      "dev": true,
      "requires": {
        "ajv": "^8.0.0"
      }
    },
    "alphanum-sort": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
      "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
      "dev": true
    },
    "ansi-colors": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
      "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
      "dev": true
    },
    "ansi-escapes": {
      "version": "4.3.2",
      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
      "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
      "dev": true,
      "requires": {
        "type-fest": "^0.21.3"
      }
    },
    "ansi-html": {
      "version": "0.0.7",
      "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
      "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
      "dev": true
    },
    "ansi-regex": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
      "dev": true
    },
    "ansi-styles": {
      "version": "3.2.1",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
      "dev": true,
      "requires": {
        "color-convert": "^1.9.0"
      }
    },
    "anymatch": {
      "version": "3.1.2",
      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
      "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
      "dev": true,
      "requires": {
        "normalize-path": "^3.0.0",
        "picomatch": "^2.0.4"
      }
    },
    "aproba": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
      "dev": true
    },
    "are-we-there-yet": {
      "version": "1.1.7",
      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz",
      "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==",
      "dev": true,
      "requires": {
        "delegates": "^1.0.0",
        "readable-stream": "^2.0.6"
      },
      "dependencies": {
        "readable-stream": {
          "version": "2.3.7",
          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
          "dev": true,
          "requires": {
            "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"
          }
        },
        "string_decoder": {
          "version": "1.1.1",
          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
          "dev": true,
          "requires": {
            "safe-buffer": "~5.1.0"
          }
        }
      }
    },
    "arr-diff": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
      "dev": true
    },
    "arr-flatten": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
      "dev": true
    },
    "arr-union": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
      "dev": true
    },
    "array-flatten": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
      "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
      "dev": true
    },
    "array-union": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
      "dev": true
    },
    "array-uniq": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
      "dev": true
    },
    "array-unique": {
      "version": "0.3.2",
      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
      "dev": true
    },
    "asn1": {
      "version": "0.2.6",
      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
      "dev": true,
      "requires": {
        "safer-buffer": "~2.1.0"
      }
    },
    "assert-plus": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
      "dev": true
    },
    "assign-symbols": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
      "dev": true
    },
    "async": {
      "version": "2.6.3",
      "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
      "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
      "dev": true,
      "requires": {
        "lodash": "^4.17.14"
      }
    },
    "async-each": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
      "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
      "dev": true
    },
    "async-limiter": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
      "dev": true
    },
    "asynckit": {
      "version": "0.4.0",
      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
      "dev": true
    },
    "atob": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
      "dev": true
    },
    "autoprefixer": {
      "version": "9.8.8",
      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz",
      "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==",
      "dev": true,
      "requires": {
        "browserslist": "^4.12.0",
        "caniuse-lite": "^1.0.30001109",
        "normalize-range": "^0.1.2",
        "num2fraction": "^1.2.2",
        "picocolors": "^0.2.1",
        "postcss": "^7.0.32",
        "postcss-value-parser": "^4.1.0"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "aws-sign2": {
      "version": "0.7.0",
      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
      "dev": true
    },
    "aws4": {
      "version": "1.11.0",
      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
      "dev": true
    },
    "babel-loader": {
      "version": "8.2.2",
      "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz",
      "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==",
      "dev": true,
      "requires": {
        "find-cache-dir": "^3.3.1",
        "loader-utils": "^1.4.0",
        "make-dir": "^3.1.0",
        "schema-utils": "^2.6.5"
      },
      "dependencies": {
        "json5": {
          "version": "1.0.1",
          "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
          "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
          "dev": true,
          "requires": {
            "minimist": "^1.2.0"
          }
        },
        "loader-utils": {
          "version": "1.4.0",
          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
          "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
          "dev": true,
          "requires": {
            "big.js": "^5.2.2",
            "emojis-list": "^3.0.0",
            "json5": "^1.0.1"
          }
        }
      }
    },
    "babel-plugin-dynamic-import-node": {
      "version": "2.3.3",
      "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
      "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
      "dev": true,
      "requires": {
        "object.assign": "^4.1.0"
      }
    },
    "babel-plugin-polyfill-corejs2": {
      "version": "0.2.3",
      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.3.tgz",
      "integrity": "sha512-NDZ0auNRzmAfE1oDDPW2JhzIMXUk+FFe2ICejmt5T4ocKgiQx3e0VCRx9NCAidcMtL2RUZaWtXnmjTCkx0tcbA==",
      "dev": true,
      "requires": {
        "@babel/compat-data": "^7.13.11",
        "@babel/helper-define-polyfill-provider": "^0.2.4",
        "semver": "^6.1.1"
      },
      "dependencies": {
        "semver": {
          "version": "6.3.0",
          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
          "dev": true
        }
      }
    },
    "babel-plugin-polyfill-corejs3": {
      "version": "0.2.5",
      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.5.tgz",
      "integrity": "sha512-ninF5MQNwAX9Z7c9ED+H2pGt1mXdP4TqzlHKyPIYmJIYz0N+++uwdM7RnJukklhzJ54Q84vA4ZJkgs7lu5vqcw==",
      "dev": true,
      "requires": {
        "@babel/helper-define-polyfill-provider": "^0.2.2",
        "core-js-compat": "^3.16.2"
      }
    },
    "babel-plugin-polyfill-regenerator": {
      "version": "0.2.3",
      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.3.tgz",
      "integrity": "sha512-JVE78oRZPKFIeUqFGrSORNzQnrDwZR16oiWeGM8ZyjBn2XAT5OjP+wXx5ESuo33nUsFUEJYjtklnsKbxW5L+7g==",
      "dev": true,
      "requires": {
        "@babel/helper-define-polyfill-provider": "^0.2.4"
      }
    },
    "balanced-match": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
      "dev": true
    },
    "base": {
      "version": "0.11.2",
      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
      "dev": true,
      "requires": {
        "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"
      },
      "dependencies": {
        "define-property": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^1.0.0"
          }
        }
      }
    },
    "base64-js": {
      "version": "1.5.1",
      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
      "dev": true
    },
    "base64id": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
      "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
      "dev": true
    },
    "batch": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
      "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
      "dev": true
    },
    "bcrypt-pbkdf": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
      "dev": true,
      "requires": {
        "tweetnacl": "^0.14.3"
      }
    },
    "big.js": {
      "version": "5.2.2",
      "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
      "dev": true
    },
    "binary-extensions": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
      "dev": true
    },
    "bindings": {
      "version": "1.5.0",
      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
      "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
      "dev": true,
      "optional": true,
      "requires": {
        "file-uri-to-path": "1.0.0"
      }
    },
    "bl": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
      "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
      "dev": true,
      "requires": {
        "buffer": "^5.5.0",
        "inherits": "^2.0.4",
        "readable-stream": "^3.4.0"
      }
    },
    "body-parser": {
      "version": "1.19.1",
      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz",
      "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==",
      "dev": true,
      "requires": {
        "bytes": "3.1.1",
        "content-type": "~1.0.4",
        "debug": "2.6.9",
        "depd": "~1.1.2",
        "http-errors": "1.8.1",
        "iconv-lite": "0.4.24",
        "on-finished": "~2.3.0",
        "qs": "6.9.6",
        "raw-body": "2.4.2",
        "type-is": "~1.6.18"
      },
      "dependencies": {
        "debug": {
          "version": "2.6.9",
          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          }
        },
        "ms": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
          "dev": true
        }
      }
    },
    "bonjour": {
      "version": "3.5.0",
      "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
      "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
      "dev": true,
      "requires": {
        "array-flatten": "^2.1.0",
        "deep-equal": "^1.0.1",
        "dns-equal": "^1.0.0",
        "dns-txt": "^2.0.2",
        "multicast-dns": "^6.0.1",
        "multicast-dns-service-types": "^1.1.0"
      }
    },
    "boolbase": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
      "dev": true
    },
    "brace-expansion": {
      "version": "1.1.11",
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
      "dev": true,
      "requires": {
        "balanced-match": "^1.0.0",
        "concat-map": "0.0.1"
      }
    },
    "braces": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
      "dev": true,
      "requires": {
        "fill-range": "^7.0.1"
      }
    },
    "browserslist": {
      "version": "4.19.1",
      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz",
      "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==",
      "dev": true,
      "requires": {
        "caniuse-lite": "^1.0.30001286",
        "electron-to-chromium": "^1.4.17",
        "escalade": "^3.1.1",
        "node-releases": "^2.0.1",
        "picocolors": "^1.0.0"
      }
    },
    "buffer": {
      "version": "5.7.1",
      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
      "dev": true,
      "requires": {
        "base64-js": "^1.3.1",
        "ieee754": "^1.1.13"
      }
    },
    "buffer-from": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
      "dev": true
    },
    "buffer-indexof": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
      "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
      "dev": true
    },
    "builtins": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz",
      "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=",
      "dev": true
    },
    "bytes": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz",
      "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==",
      "dev": true
    },
    "cacache": {
      "version": "15.2.0",
      "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz",
      "integrity": "sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw==",
      "dev": true,
      "requires": {
        "@npmcli/move-file": "^1.0.1",
        "chownr": "^2.0.0",
        "fs-minipass": "^2.0.0",
        "glob": "^7.1.4",
        "infer-owner": "^1.0.4",
        "lru-cache": "^6.0.0",
        "minipass": "^3.1.1",
        "minipass-collect": "^1.0.2",
        "minipass-flush": "^1.0.5",
        "minipass-pipeline": "^1.2.2",
        "mkdirp": "^1.0.3",
        "p-map": "^4.0.0",
        "promise-inflight": "^1.0.1",
        "rimraf": "^3.0.2",
        "ssri": "^8.0.1",
        "tar": "^6.0.2",
        "unique-filename": "^1.1.1"
      }
    },
    "cache-base": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
      "dev": true,
      "requires": {
        "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": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
      "dev": true,
      "requires": {
        "function-bind": "^1.1.1",
        "get-intrinsic": "^1.0.2"
      }
    },
    "callsites": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
      "dev": true
    },
    "camelcase": {
      "version": "5.3.1",
      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
      "dev": true
    },
    "can-use-dom": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/can-use-dom/-/can-use-dom-0.1.0.tgz",
      "integrity": "sha1-IsxKNKCrxDlQ9CxkEQJKP2NmtFo="
    },
    "caniuse-api": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
      "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
      "dev": true,
      "requires": {
        "browserslist": "^4.0.0",
        "caniuse-lite": "^1.0.0",
        "lodash.memoize": "^4.1.2",
        "lodash.uniq": "^4.5.0"
      }
    },
    "caniuse-lite": {
      "version": "1.0.30001300",
      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001300.tgz",
      "integrity": "sha512-cVjiJHWGcNlJi8TZVKNMnvMid3Z3TTdDHmLDzlOdIiZq138Exvo0G+G0wTdVYolxKb4AYwC+38pxodiInVtJSA==",
      "dev": true
    },
    "canonical-path": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz",
      "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==",
      "dev": true
    },
    "caseless": {
      "version": "0.12.0",
      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
      "dev": true
    },
    "chalk": {
      "version": "2.4.2",
      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
      "dev": true,
      "requires": {
        "ansi-styles": "^3.2.1",
        "escape-string-regexp": "^1.0.5",
        "supports-color": "^5.3.0"
      }
    },
    "chardet": {
      "version": "0.7.0",
      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
      "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
      "dev": true
    },
    "chokidar": {
      "version": "3.5.2",
      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
      "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
      "dev": true,
      "requires": {
        "anymatch": "~3.1.2",
        "braces": "~3.0.2",
        "fsevents": "~2.3.2",
        "glob-parent": "~5.1.2",
        "is-binary-path": "~2.1.0",
        "is-glob": "~4.0.1",
        "normalize-path": "~3.0.0",
        "readdirp": "~3.6.0"
      }
    },
    "chownr": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
      "dev": true
    },
    "chrome-trace-event": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
      "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
      "dev": true
    },
    "circular-dependency-plugin": {
      "version": "5.2.2",
      "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz",
      "integrity": "sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ==",
      "dev": true,
      "requires": {}
    },
    "class-utils": {
      "version": "0.3.6",
      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
      "dev": true,
      "requires": {
        "arr-union": "^3.1.0",
        "define-property": "^0.2.5",
        "isobject": "^3.0.0",
        "static-extend": "^0.1.1"
      },
      "dependencies": {
        "define-property": {
          "version": "0.2.5",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^0.1.0"
          }
        },
        "is-accessor-descriptor": {
          "version": "0.1.6",
          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
          "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
          "dev": true,
          "requires": {
            "kind-of": "^3.0.2"
          },
          "dependencies": {
            "kind-of": {
              "version": "3.2.2",
              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
              "dev": true,
              "requires": {
                "is-buffer": "^1.1.5"
              }
            }
          }
        },
        "is-data-descriptor": {
          "version": "0.1.4",
          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
          "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
          "dev": true,
          "requires": {
            "kind-of": "^3.0.2"
          },
          "dependencies": {
            "kind-of": {
              "version": "3.2.2",
              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
              "dev": true,
              "requires": {
                "is-buffer": "^1.1.5"
              }
            }
          }
        },
        "is-descriptor": {
          "version": "0.1.6",
          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
          "dev": true,
          "requires": {
            "is-accessor-descriptor": "^0.1.6",
            "is-data-descriptor": "^0.1.4",
            "kind-of": "^5.0.0"
          }
        },
        "kind-of": {
          "version": "5.1.0",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
          "dev": true
        }
      }
    },
    "clean-stack": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
      "dev": true
    },
    "cli-cursor": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
      "dev": true,
      "requires": {
        "restore-cursor": "^3.1.0"
      }
    },
    "cli-spinners": {
      "version": "2.6.1",
      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz",
      "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==",
      "dev": true
    },
    "cli-width": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
      "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
      "dev": true
    },
    "cliui": {
      "version": "7.0.4",
      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
      "dev": true,
      "requires": {
        "string-width": "^4.2.0",
        "strip-ansi": "^6.0.0",
        "wrap-ansi": "^7.0.0"
      }
    },
    "clone": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
      "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
      "dev": true
    },
    "clone-deep": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
      "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
      "dev": true,
      "requires": {
        "is-plain-object": "^2.0.4",
        "kind-of": "^6.0.2",
        "shallow-clone": "^3.0.0"
      }
    },
    "code-point-at": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
      "dev": true
    },
    "collection-visit": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
      "dev": true,
      "requires": {
        "map-visit": "^1.0.0",
        "object-visit": "^1.0.0"
      }
    },
    "color-convert": {
      "version": "1.9.3",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
      "dev": true,
      "requires": {
        "color-name": "1.1.3"
      }
    },
    "color-name": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
      "dev": true
    },
    "colord": {
      "version": "2.9.2",
      "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz",
      "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==",
      "dev": true
    },
    "colorette": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz",
      "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==",
      "dev": true
    },
    "colors": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
      "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
      "dev": true
    },
    "combined-stream": {
      "version": "1.0.8",
      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
      "dev": true,
      "requires": {
        "delayed-stream": "~1.0.0"
      }
    },
    "commander": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
      "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
      "dev": true
    },
    "commondir": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
      "dev": true
    },
    "component-emitter": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
      "dev": true
    },
    "compressible": {
      "version": "2.0.18",
      "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
      "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
      "dev": true,
      "requires": {
        "mime-db": ">= 1.43.0 < 2"
      }
    },
    "compression": {
      "version": "1.7.4",
      "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
      "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
      "dev": true,
      "requires": {
        "accepts": "~1.3.5",
        "bytes": "3.0.0",
        "compressible": "~2.0.16",
        "debug": "2.6.9",
        "on-headers": "~1.0.2",
        "safe-buffer": "5.1.2",
        "vary": "~1.1.2"
      },
      "dependencies": {
        "bytes": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
          "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
          "dev": true
        },
        "debug": {
          "version": "2.6.9",
          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          }
        },
        "ms": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
          "dev": true
        }
      }
    },
    "concat-map": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
      "dev": true
    },
    "connect": {
      "version": "3.7.0",
      "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
      "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
      "dev": true,
      "requires": {
        "debug": "2.6.9",
        "finalhandler": "1.1.2",
        "parseurl": "~1.3.3",
        "utils-merge": "1.0.1"
      },
      "dependencies": {
        "debug": {
          "version": "2.6.9",
          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          }
        },
        "ms": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
          "dev": true
        }
      }
    },
    "connect-history-api-fallback": {
      "version": "1.6.0",
      "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
      "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
      "dev": true
    },
    "console-control-strings": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
      "dev": true
    },
    "content-disposition": {
      "version": "0.5.4",
      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
      "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
      "dev": true,
      "requires": {
        "safe-buffer": "5.2.1"
      },
      "dependencies": {
        "safe-buffer": {
          "version": "5.2.1",
          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
          "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
          "dev": true
        }
      }
    },
    "content-type": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
      "dev": true
    },
    "convert-source-map": {
      "version": "1.8.0",
      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
      "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
      "dev": true,
      "requires": {
        "safe-buffer": "~5.1.1"
      }
    },
    "cookie": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
      "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
      "dev": true
    },
    "cookie-signature": {
      "version": "1.0.6",
      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
      "dev": true
    },
    "copy-anything": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.3.tgz",
      "integrity": "sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ==",
      "dev": true,
      "requires": {
        "is-what": "^3.12.0"
      }
    },
    "copy-descriptor": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
      "dev": true
    },
    "copy-webpack-plugin": {
      "version": "9.0.0",
      "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-9.0.0.tgz",
      "integrity": "sha512-k8UB2jLIb1Jip2nZbCz83T/XfhfjX6mB1yLJNYKrpYi7FQimfOoFv/0//iT6HV1K8FwUB5yUbCcnpLebJXJTug==",
      "dev": true,
      "requires": {
        "fast-glob": "^3.2.5",
        "glob-parent": "^6.0.0",
        "globby": "^11.0.3",
        "normalize-path": "^3.0.0",
        "p-limit": "^3.1.0",
        "schema-utils": "^3.0.0",
        "serialize-javascript": "^5.0.1"
      },
      "dependencies": {
        "ajv": {
          "version": "6.12.6",
          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
          "dev": true,
          "requires": {
            "fast-deep-equal": "^3.1.1",
            "fast-json-stable-stringify": "^2.0.0",
            "json-schema-traverse": "^0.4.1",
            "uri-js": "^4.2.2"
          }
        },
        "ajv-keywords": {
          "version": "3.5.2",
          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
          "dev": true,
          "requires": {}
        },
        "glob-parent": {
          "version": "6.0.2",
          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
          "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
          "dev": true,
          "requires": {
            "is-glob": "^4.0.3"
          }
        },
        "json-schema-traverse": {
          "version": "0.4.1",
          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
          "dev": true
        },
        "schema-utils": {
          "version": "3.1.1",
          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
          "dev": true,
          "requires": {
            "@types/json-schema": "^7.0.8",
            "ajv": "^6.12.5",
            "ajv-keywords": "^3.5.2"
          }
        }
      }
    },
    "core-js": {
      "version": "3.15.1",
      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.1.tgz",
      "integrity": "sha512-h8VbZYnc9pDzueiS2610IULDkpFFPunHwIpl8yRwFahAEEdSpHlTy3h3z3rKq5h11CaUdBEeRViu9AYvbxiMeg=="
    },
    "core-js-compat": {
      "version": "3.20.3",
      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.3.tgz",
      "integrity": "sha512-c8M5h0IkNZ+I92QhIpuSijOxGAcj3lgpsWdkCqmUTZNwidujF4r3pi6x1DCN+Vcs5qTS2XWWMfWSuCqyupX8gw==",
      "dev": true,
      "requires": {
        "browserslist": "^4.19.1",
        "semver": "7.0.0"
      },
      "dependencies": {
        "semver": {
          "version": "7.0.0",
          "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
          "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
          "dev": true
        }
      }
    },
    "core-util-is": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
      "dev": true
    },
    "cors": {
      "version": "2.8.5",
      "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
      "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
      "dev": true,
      "requires": {
        "object-assign": "^4",
        "vary": "^1"
      }
    },
    "cosmiconfig": {
      "version": "7.0.1",
      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz",
      "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==",
      "dev": true,
      "requires": {
        "@types/parse-json": "^4.0.0",
        "import-fresh": "^3.2.1",
        "parse-json": "^5.0.0",
        "path-type": "^4.0.0",
        "yaml": "^1.10.0"
      }
    },
    "critters": {
      "version": "0.0.10",
      "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.10.tgz",
      "integrity": "sha512-p5VKhP1803+f+0Jq5P03w1SbiHtpAKm+1EpJHkiPxQPq0Vu9QLZHviJ02GRrWi0dlcJqrmzMWInbwp4d22RsGw==",
      "dev": true,
      "requires": {
        "chalk": "^4.1.0",
        "css": "^3.0.0",
        "parse5": "^6.0.1",
        "parse5-htmlparser2-tree-adapter": "^6.0.1",
        "pretty-bytes": "^5.3.0"
      },
      "dependencies": {
        "ansi-styles": {
          "version": "4.3.0",
          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
          "dev": true,
          "requires": {
            "color-convert": "^2.0.1"
          }
        },
        "chalk": {
          "version": "4.1.2",
          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
          "dev": true,
          "requires": {
            "ansi-styles": "^4.1.0",
            "supports-color": "^7.1.0"
          }
        },
        "color-convert": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
          "dev": true,
          "requires": {
            "color-name": "~1.1.4"
          }
        },
        "color-name": {
          "version": "1.1.4",
          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
          "dev": true
        },
        "has-flag": {
          "version": "4.0.0",
          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
          "dev": true
        },
        "parse5": {
          "version": "6.0.1",
          "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
          "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
          "dev": true
        },
        "supports-color": {
          "version": "7.2.0",
          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
          "dev": true,
          "requires": {
            "has-flag": "^4.0.0"
          }
        }
      }
    },
    "cross-spawn": {
      "version": "6.0.5",
      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
      "dev": true,
      "requires": {
        "nice-try": "^1.0.4",
        "path-key": "^2.0.1",
        "semver": "^5.5.0",
        "shebang-command": "^1.2.0",
        "which": "^1.2.9"
      },
      "dependencies": {
        "semver": {
          "version": "5.7.1",
          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
          "dev": true
        }
      }
    },
    "css": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz",
      "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==",
      "dev": true,
      "requires": {
        "inherits": "^2.0.4",
        "source-map": "^0.6.1",
        "source-map-resolve": "^0.6.0"
      },
      "dependencies": {
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "css-blank-pseudo": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz",
      "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.5"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "css-declaration-sorter": {
      "version": "6.1.4",
      "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.1.4.tgz",
      "integrity": "sha512-lpfkqS0fctcmZotJGhnxkIyJWvBXgpyi2wsFd4J8VB7wzyrT6Ch/3Q+FMNJpjK4gu1+GN5khOnpU2ZVKrLbhCw==",
      "dev": true,
      "requires": {
        "timsort": "^0.3.0"
      }
    },
    "css-has-pseudo": {
      "version": "0.10.0",
      "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz",
      "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.6",
        "postcss-selector-parser": "^5.0.0-rc.4"
      },
      "dependencies": {
        "cssesc": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
          "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
          "dev": true
        },
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "postcss-selector-parser": {
          "version": "5.0.0",
          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
          "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
          "dev": true,
          "requires": {
            "cssesc": "^2.0.0",
            "indexes-of": "^1.0.1",
            "uniq": "^1.0.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "css-loader": {
      "version": "5.2.6",
      "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.6.tgz",
      "integrity": "sha512-0wyN5vXMQZu6BvjbrPdUJvkCzGEO24HC7IS7nW4llc6BBFC+zwR9CKtYGv63Puzsg10L/o12inMY5/2ByzfD6w==",
      "dev": true,
      "requires": {
        "icss-utils": "^5.1.0",
        "loader-utils": "^2.0.0",
        "postcss": "^8.2.15",
        "postcss-modules-extract-imports": "^3.0.0",
        "postcss-modules-local-by-default": "^4.0.0",
        "postcss-modules-scope": "^3.0.0",
        "postcss-modules-values": "^4.0.0",
        "postcss-value-parser": "^4.1.0",
        "schema-utils": "^3.0.0",
        "semver": "^7.3.5"
      },
      "dependencies": {
        "ajv": {
          "version": "6.12.6",
          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
          "dev": true,
          "requires": {
            "fast-deep-equal": "^3.1.1",
            "fast-json-stable-stringify": "^2.0.0",
            "json-schema-traverse": "^0.4.1",
            "uri-js": "^4.2.2"
          }
        },
        "ajv-keywords": {
          "version": "3.5.2",
          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
          "dev": true,
          "requires": {}
        },
        "json-schema-traverse": {
          "version": "0.4.1",
          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
          "dev": true
        },
        "schema-utils": {
          "version": "3.1.1",
          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
          "dev": true,
          "requires": {
            "@types/json-schema": "^7.0.8",
            "ajv": "^6.12.5",
            "ajv-keywords": "^3.5.2"
          }
        }
      }
    },
    "css-minimizer-webpack-plugin": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.0.1.tgz",
      "integrity": "sha512-RGFIv6iZWUPO2T1vE5+5pNCSs2H2xtHYRdfZPiiNH8Of6QOn9BeFnZSoHiQMkmsxOO/JkPe4BpKfs7slFIWcTA==",
      "dev": true,
      "requires": {
        "cssnano": "^5.0.0",
        "jest-worker": "^27.0.2",
        "p-limit": "^3.0.2",
        "postcss": "^8.2.9",
        "schema-utils": "^3.0.0",
        "serialize-javascript": "^5.0.1",
        "source-map": "^0.6.1"
      },
      "dependencies": {
        "ajv": {
          "version": "6.12.6",
          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
          "dev": true,
          "requires": {
            "fast-deep-equal": "^3.1.1",
            "fast-json-stable-stringify": "^2.0.0",
            "json-schema-traverse": "^0.4.1",
            "uri-js": "^4.2.2"
          }
        },
        "ajv-keywords": {
          "version": "3.5.2",
          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
          "dev": true,
          "requires": {}
        },
        "json-schema-traverse": {
          "version": "0.4.1",
          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
          "dev": true
        },
        "schema-utils": {
          "version": "3.1.1",
          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
          "dev": true,
          "requires": {
            "@types/json-schema": "^7.0.8",
            "ajv": "^6.12.5",
            "ajv-keywords": "^3.5.2"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "css-parse": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz",
      "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=",
      "dev": true,
      "requires": {
        "css": "^2.0.0"
      },
      "dependencies": {
        "css": {
          "version": "2.2.4",
          "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
          "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
          "dev": true,
          "requires": {
            "inherits": "^2.0.3",
            "source-map": "^0.6.1",
            "source-map-resolve": "^0.5.2",
            "urix": "^0.1.0"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        },
        "source-map-resolve": {
          "version": "0.5.3",
          "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
          "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
          "dev": true,
          "requires": {
            "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"
          }
        }
      }
    },
    "css-prefers-color-scheme": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz",
      "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.5"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "css-select": {
      "version": "4.2.1",
      "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz",
      "integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==",
      "dev": true,
      "requires": {
        "boolbase": "^1.0.0",
        "css-what": "^5.1.0",
        "domhandler": "^4.3.0",
        "domutils": "^2.8.0",
        "nth-check": "^2.0.1"
      }
    },
    "css-tree": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
      "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
      "dev": true,
      "requires": {
        "mdn-data": "2.0.14",
        "source-map": "^0.6.1"
      },
      "dependencies": {
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "css-what": {
      "version": "5.1.0",
      "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz",
      "integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==",
      "dev": true
    },
    "cssdb": {
      "version": "4.4.0",
      "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz",
      "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==",
      "dev": true
    },
    "cssesc": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
      "dev": true
    },
    "cssnano": {
      "version": "5.0.15",
      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.15.tgz",
      "integrity": "sha512-ppZsS7oPpi2sfiyV5+i+NbB/3GtQ+ab2Vs1azrZaXWujUSN4o+WdTxlCZIMcT9yLW3VO/5yX3vpyDaQ1nIn8CQ==",
      "dev": true,
      "requires": {
        "cssnano-preset-default": "^5.1.10",
        "lilconfig": "^2.0.3",
        "yaml": "^1.10.2"
      }
    },
    "cssnano-preset-default": {
      "version": "5.1.10",
      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.10.tgz",
      "integrity": "sha512-BcpSzUVygHMOnp9uG5rfPzTOCb0GAHQkqtUQx8j1oMNF9A1Q8hziOOhiM4bdICpmrBIU85BE64RD5XGYsVQZNA==",
      "dev": true,
      "requires": {
        "css-declaration-sorter": "^6.0.3",
        "cssnano-utils": "^3.0.0",
        "postcss-calc": "^8.2.0",
        "postcss-colormin": "^5.2.3",
        "postcss-convert-values": "^5.0.2",
        "postcss-discard-comments": "^5.0.1",
        "postcss-discard-duplicates": "^5.0.1",
        "postcss-discard-empty": "^5.0.1",
        "postcss-discard-overridden": "^5.0.2",
        "postcss-merge-longhand": "^5.0.4",
        "postcss-merge-rules": "^5.0.4",
        "postcss-minify-font-values": "^5.0.2",
        "postcss-minify-gradients": "^5.0.4",
        "postcss-minify-params": "^5.0.3",
        "postcss-minify-selectors": "^5.1.1",
        "postcss-normalize-charset": "^5.0.1",
        "postcss-normalize-display-values": "^5.0.2",
        "postcss-normalize-positions": "^5.0.2",
        "postcss-normalize-repeat-style": "^5.0.2",
        "postcss-normalize-string": "^5.0.2",
        "postcss-normalize-timing-functions": "^5.0.2",
        "postcss-normalize-unicode": "^5.0.2",
        "postcss-normalize-url": "^5.0.4",
        "postcss-normalize-whitespace": "^5.0.2",
        "postcss-ordered-values": "^5.0.3",
        "postcss-reduce-initial": "^5.0.2",
        "postcss-reduce-transforms": "^5.0.2",
        "postcss-svgo": "^5.0.3",
        "postcss-unique-selectors": "^5.0.2"
      }
    },
    "cssnano-utils": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.0.0.tgz",
      "integrity": "sha512-Pzs7/BZ6OgT+tXXuF12DKR8SmSbzUeVYCtMBbS8lI0uAm3mrYmkyqCXXPsQESI6kmLfEVBppbdVY/el3hg3nAA==",
      "dev": true,
      "requires": {}
    },
    "csso": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz",
      "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==",
      "dev": true,
      "requires": {
        "css-tree": "^1.1.2"
      }
    },
    "custom-event": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
      "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=",
      "dev": true
    },
    "dashdash": {
      "version": "1.14.1",
      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
      "dev": true,
      "requires": {
        "assert-plus": "^1.0.0"
      }
    },
    "date-format": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz",
      "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==",
      "dev": true
    },
    "debug": {
      "version": "4.3.1",
      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
      "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
      "dev": true,
      "requires": {
        "ms": "2.1.2"
      }
    },
    "decamelize": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
      "dev": true
    },
    "decode-uri-component": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
      "dev": true
    },
    "deep-equal": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
      "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
      "dev": true,
      "requires": {
        "is-arguments": "^1.0.4",
        "is-date-object": "^1.0.1",
        "is-regex": "^1.0.4",
        "object-is": "^1.0.1",
        "object-keys": "^1.1.1",
        "regexp.prototype.flags": "^1.2.0"
      }
    },
    "default-gateway": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
      "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==",
      "dev": true,
      "requires": {
        "execa": "^1.0.0",
        "ip-regex": "^2.1.0"
      }
    },
    "defaults": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
      "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
      "dev": true,
      "requires": {
        "clone": "^1.0.2"
      }
    },
    "define-lazy-prop": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
      "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
      "dev": true
    },
    "define-properties": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
      "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
      "dev": true,
      "requires": {
        "object-keys": "^1.0.12"
      }
    },
    "define-property": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
      "dev": true,
      "requires": {
        "is-descriptor": "^1.0.2",
        "isobject": "^3.0.1"
      }
    },
    "del": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz",
      "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==",
      "dev": true,
      "requires": {
        "@types/glob": "^7.1.1",
        "globby": "^6.1.0",
        "is-path-cwd": "^2.0.0",
        "is-path-in-cwd": "^2.0.0",
        "p-map": "^2.0.0",
        "pify": "^4.0.1",
        "rimraf": "^2.6.3"
      },
      "dependencies": {
        "array-union": {
          "version": "1.0.2",
          "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
          "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
          "dev": true,
          "requires": {
            "array-uniq": "^1.0.1"
          }
        },
        "globby": {
          "version": "6.1.0",
          "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
          "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
          "dev": true,
          "requires": {
            "array-union": "^1.0.1",
            "glob": "^7.0.3",
            "object-assign": "^4.0.1",
            "pify": "^2.0.0",
            "pinkie-promise": "^2.0.0"
          },
          "dependencies": {
            "pify": {
              "version": "2.3.0",
              "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
              "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
              "dev": true
            }
          }
        },
        "p-map": {
          "version": "2.1.0",
          "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
          "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
          "dev": true
        },
        "pify": {
          "version": "4.0.1",
          "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
          "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
          "dev": true
        },
        "rimraf": {
          "version": "2.7.1",
          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
          "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
          "dev": true,
          "requires": {
            "glob": "^7.1.3"
          }
        }
      }
    },
    "delayed-stream": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
      "dev": true
    },
    "delegates": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
      "dev": true
    },
    "depd": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
      "dev": true
    },
    "dependency-graph": {
      "version": "0.11.0",
      "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz",
      "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==",
      "dev": true
    },
    "destroy": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
      "dev": true
    },
    "detect-node": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
      "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
      "dev": true
    },
    "di": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
      "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=",
      "dev": true
    },
    "dir-glob": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
      "dev": true,
      "requires": {
        "path-type": "^4.0.0"
      }
    },
    "dns-equal": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
      "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=",
      "dev": true
    },
    "dns-packet": {
      "version": "1.3.4",
      "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz",
      "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==",
      "dev": true,
      "requires": {
        "ip": "^1.1.0",
        "safe-buffer": "^5.0.1"
      }
    },
    "dns-txt": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
      "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
      "dev": true,
      "requires": {
        "buffer-indexof": "^1.0.0"
      }
    },
    "dom-serialize": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz",
      "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=",
      "dev": true,
      "requires": {
        "custom-event": "~1.0.0",
        "ent": "~2.2.0",
        "extend": "^3.0.0",
        "void-elements": "^2.0.0"
      }
    },
    "dom-serializer": {
      "version": "1.3.2",
      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
      "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
      "dev": true,
      "requires": {
        "domelementtype": "^2.0.1",
        "domhandler": "^4.2.0",
        "entities": "^2.0.0"
      }
    },
    "domelementtype": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
      "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
      "dev": true
    },
    "domhandler": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz",
      "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==",
      "dev": true,
      "requires": {
        "domelementtype": "^2.2.0"
      }
    },
    "domutils": {
      "version": "2.8.0",
      "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
      "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
      "dev": true,
      "requires": {
        "dom-serializer": "^1.0.1",
        "domelementtype": "^2.2.0",
        "domhandler": "^4.2.0"
      }
    },
    "ecc-jsbn": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
      "dev": true,
      "requires": {
        "jsbn": "~0.1.0",
        "safer-buffer": "^2.1.0"
      }
    },
    "ee-first": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
      "dev": true
    },
    "electron-to-chromium": {
      "version": "1.4.46",
      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.46.tgz",
      "integrity": "sha512-UtV0xUA/dibCKKP2JMxOpDtXR74zABevuUEH4K0tvduFSIoxRVcYmQsbB51kXsFTX8MmOyWMt8tuZAlmDOqkrQ==",
      "dev": true
    },
    "emoji-regex": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
      "dev": true
    },
    "emojis-list": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
      "dev": true
    },
    "encodeurl": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
      "dev": true
    },
    "encoding": {
      "version": "0.1.13",
      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
      "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
      "dev": true,
      "optional": true,
      "requires": {
        "iconv-lite": "^0.6.2"
      },
      "dependencies": {
        "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==",
          "dev": true,
          "optional": true,
          "requires": {
            "safer-buffer": ">= 2.1.2 < 3.0.0"
          }
        }
      }
    },
    "end-of-stream": {
      "version": "1.4.4",
      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
      "dev": true,
      "requires": {
        "once": "^1.4.0"
      }
    },
    "engine.io": {
      "version": "6.1.1",
      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.1.tgz",
      "integrity": "sha512-AyMc20q8JUUdvKd46+thc9o7yCZ6iC6MoBCChG5Z1XmFMpp+2+y/oKvwpZTUJB0KCjxScw1dV9c2h5pjiYBLuQ==",
      "dev": true,
      "requires": {
        "@types/cookie": "^0.4.1",
        "@types/cors": "^2.8.12",
        "@types/node": ">=10.0.0",
        "accepts": "~1.3.4",
        "base64id": "2.0.0",
        "cookie": "~0.4.1",
        "cors": "~2.8.5",
        "debug": "~4.3.1",
        "engine.io-parser": "~5.0.0",
        "ws": "~8.2.3"
      }
    },
    "engine.io-parser": {
      "version": "5.0.3",
      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.3.tgz",
      "integrity": "sha512-BtQxwF27XUNnSafQLvDi0dQ8s3i6VgzSoQMJacpIcGNrlUdfHSKbgm3jmjCVvQluGzqwujQMPAoMai3oYSTurg==",
      "dev": true,
      "requires": {
        "@socket.io/base64-arraybuffer": "~1.0.2"
      }
    },
    "enhanced-resolve": {
      "version": "5.8.2",
      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz",
      "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==",
      "dev": true,
      "requires": {
        "graceful-fs": "^4.2.4",
        "tapable": "^2.2.0"
      }
    },
    "ent": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz",
      "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=",
      "dev": true
    },
    "entities": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
      "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
      "dev": true
    },
    "env-paths": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
      "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
      "dev": true
    },
    "err-code": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
      "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
      "dev": true
    },
    "errno": {
      "version": "0.1.8",
      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
      "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
      "dev": true,
      "requires": {
        "prr": "~1.0.1"
      }
    },
    "error-ex": {
      "version": "1.3.2",
      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
      "dev": true,
      "requires": {
        "is-arrayish": "^0.2.1"
      }
    },
    "es-module-lexer": {
      "version": "0.7.1",
      "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz",
      "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==",
      "dev": true
    },
    "escalade": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
      "dev": true
    },
    "escape-html": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
      "dev": true
    },
    "escape-string-regexp": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
      "dev": true
    },
    "eslint-scope": {
      "version": "5.1.1",
      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
      "dev": true,
      "requires": {
        "esrecurse": "^4.3.0",
        "estraverse": "^4.1.1"
      }
    },
    "esrecurse": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
      "dev": true,
      "requires": {
        "estraverse": "^5.2.0"
      },
      "dependencies": {
        "estraverse": {
          "version": "5.3.0",
          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
          "dev": true
        }
      }
    },
    "estraverse": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
      "dev": true
    },
    "esutils": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
      "dev": true
    },
    "etag": {
      "version": "1.8.1",
      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
      "dev": true
    },
    "eventemitter3": {
      "version": "4.0.7",
      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
      "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
      "dev": true
    },
    "events": {
      "version": "3.3.0",
      "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
      "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
      "dev": true
    },
    "eventsource": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz",
      "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==",
      "dev": true,
      "requires": {
        "original": "^1.0.0"
      }
    },
    "execa": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
      "dev": true,
      "requires": {
        "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"
      }
    },
    "expand-brackets": {
      "version": "2.1.4",
      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
      "dev": true,
      "requires": {
        "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"
      },
      "dependencies": {
        "debug": {
          "version": "2.6.9",
          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          }
        },
        "define-property": {
          "version": "0.2.5",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^0.1.0"
          }
        },
        "extend-shallow": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
          "dev": true,
          "requires": {
            "is-extendable": "^0.1.0"
          }
        },
        "is-accessor-descriptor": {
          "version": "0.1.6",
          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
          "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
          "dev": true,
          "requires": {
            "kind-of": "^3.0.2"
          },
          "dependencies": {
            "kind-of": {
              "version": "3.2.2",
              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
              "dev": true,
              "requires": {
                "is-buffer": "^1.1.5"
              }
            }
          }
        },
        "is-data-descriptor": {
          "version": "0.1.4",
          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
          "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
          "dev": true,
          "requires": {
            "kind-of": "^3.0.2"
          },
          "dependencies": {
            "kind-of": {
              "version": "3.2.2",
              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
              "dev": true,
              "requires": {
                "is-buffer": "^1.1.5"
              }
            }
          }
        },
        "is-descriptor": {
          "version": "0.1.6",
          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
          "dev": true,
          "requires": {
            "is-accessor-descriptor": "^0.1.6",
            "is-data-descriptor": "^0.1.4",
            "kind-of": "^5.0.0"
          }
        },
        "is-extendable": {
          "version": "0.1.1",
          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
          "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
          "dev": true
        },
        "kind-of": {
          "version": "5.1.0",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
          "dev": true
        },
        "ms": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
          "dev": true
        }
      }
    },
    "express": {
      "version": "4.17.2",
      "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz",
      "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==",
      "dev": true,
      "requires": {
        "accepts": "~1.3.7",
        "array-flatten": "1.1.1",
        "body-parser": "1.19.1",
        "content-disposition": "0.5.4",
        "content-type": "~1.0.4",
        "cookie": "0.4.1",
        "cookie-signature": "1.0.6",
        "debug": "2.6.9",
        "depd": "~1.1.2",
        "encodeurl": "~1.0.2",
        "escape-html": "~1.0.3",
        "etag": "~1.8.1",
        "finalhandler": "~1.1.2",
        "fresh": "0.5.2",
        "merge-descriptors": "1.0.1",
        "methods": "~1.1.2",
        "on-finished": "~2.3.0",
        "parseurl": "~1.3.3",
        "path-to-regexp": "0.1.7",
        "proxy-addr": "~2.0.7",
        "qs": "6.9.6",
        "range-parser": "~1.2.1",
        "safe-buffer": "5.2.1",
        "send": "0.17.2",
        "serve-static": "1.14.2",
        "setprototypeof": "1.2.0",
        "statuses": "~1.5.0",
        "type-is": "~1.6.18",
        "utils-merge": "1.0.1",
        "vary": "~1.1.2"
      },
      "dependencies": {
        "array-flatten": {
          "version": "1.1.1",
          "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
          "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
          "dev": true
        },
        "debug": {
          "version": "2.6.9",
          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          }
        },
        "ms": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
          "dev": true
        },
        "safe-buffer": {
          "version": "5.2.1",
          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
          "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
          "dev": true
        }
      }
    },
    "extend": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
      "dev": true
    },
    "extend-shallow": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
      "dev": true,
      "requires": {
        "assign-symbols": "^1.0.0",
        "is-extendable": "^1.0.1"
      }
    },
    "external-editor": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
      "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
      "dev": true,
      "requires": {
        "chardet": "^0.7.0",
        "iconv-lite": "^0.4.24",
        "tmp": "^0.0.33"
      }
    },
    "extglob": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
      "dev": true,
      "requires": {
        "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"
      },
      "dependencies": {
        "define-property": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^1.0.0"
          }
        },
        "extend-shallow": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
          "dev": true,
          "requires": {
            "is-extendable": "^0.1.0"
          }
        },
        "is-extendable": {
          "version": "0.1.1",
          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
          "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
          "dev": true
        }
      }
    },
    "extsprintf": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
      "dev": true
    },
    "fast-deep-equal": {
      "version": "3.1.3",
      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
      "dev": true
    },
    "fast-glob": {
      "version": "3.2.11",
      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
      "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
      "dev": true,
      "requires": {
        "@nodelib/fs.stat": "^2.0.2",
        "@nodelib/fs.walk": "^1.2.3",
        "glob-parent": "^5.1.2",
        "merge2": "^1.3.0",
        "micromatch": "^4.0.4"
      }
    },
    "fast-json-stable-stringify": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
      "dev": true
    },
    "fastq": {
      "version": "1.13.0",
      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
      "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
      "dev": true,
      "requires": {
        "reusify": "^1.0.4"
      }
    },
    "faye-websocket": {
      "version": "0.11.4",
      "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
      "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
      "dev": true,
      "requires": {
        "websocket-driver": ">=0.5.1"
      }
    },
    "figures": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
      "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
      "dev": true,
      "requires": {
        "escape-string-regexp": "^1.0.5"
      }
    },
    "file-uri-to-path": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
      "dev": true,
      "optional": true
    },
    "fill-range": {
      "version": "7.0.1",
      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
      "dev": true,
      "requires": {
        "to-regex-range": "^5.0.1"
      }
    },
    "finalhandler": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
      "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
      "dev": true,
      "requires": {
        "debug": "2.6.9",
        "encodeurl": "~1.0.2",
        "escape-html": "~1.0.3",
        "on-finished": "~2.3.0",
        "parseurl": "~1.3.3",
        "statuses": "~1.5.0",
        "unpipe": "~1.0.0"
      },
      "dependencies": {
        "debug": {
          "version": "2.6.9",
          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          }
        },
        "ms": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
          "dev": true
        }
      }
    },
    "find-cache-dir": {
      "version": "3.3.1",
      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
      "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
      "dev": true,
      "requires": {
        "commondir": "^1.0.1",
        "make-dir": "^3.0.2",
        "pkg-dir": "^4.1.0"
      }
    },
    "find-up": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
      "dev": true,
      "requires": {
        "locate-path": "^5.0.0",
        "path-exists": "^4.0.0"
      }
    },
    "flatted": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
      "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
      "dev": true
    },
    "flatten": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz",
      "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==",
      "dev": true
    },
    "follow-redirects": {
      "version": "1.14.7",
      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
      "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==",
      "dev": true
    },
    "for-in": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
      "dev": true
    },
    "forever-agent": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
      "dev": true
    },
    "form-data": {
      "version": "2.3.3",
      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
      "dev": true,
      "requires": {
        "asynckit": "^0.4.0",
        "combined-stream": "^1.0.6",
        "mime-types": "^2.1.12"
      }
    },
    "forwarded": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
      "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
      "dev": true
    },
    "fragment-cache": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
      "dev": true,
      "requires": {
        "map-cache": "^0.2.2"
      }
    },
    "fresh": {
      "version": "0.5.2",
      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
      "dev": true
    },
    "fs-extra": {
      "version": "8.1.0",
      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
      "dev": true,
      "requires": {
        "graceful-fs": "^4.2.0",
        "jsonfile": "^4.0.0",
        "universalify": "^0.1.0"
      }
    },
    "fs-minipass": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
      "dev": true,
      "requires": {
        "minipass": "^3.0.0"
      }
    },
    "fs-monkey": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz",
      "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==",
      "dev": true
    },
    "fs.realpath": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
      "dev": true
    },
    "fsevents": {
      "version": "2.3.2",
      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
      "dev": true,
      "optional": true
    },
    "function-bind": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
      "dev": true
    },
    "gauge": {
      "version": "2.7.4",
      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
      "dev": true,
      "requires": {
        "aproba": "^1.0.3",
        "console-control-strings": "^1.0.0",
        "has-unicode": "^2.0.0",
        "object-assign": "^4.1.0",
        "signal-exit": "^3.0.0",
        "string-width": "^1.0.1",
        "strip-ansi": "^3.0.1",
        "wide-align": "^1.1.0"
      },
      "dependencies": {
        "ansi-regex": {
          "version": "2.1.1",
          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
          "dev": true
        },
        "is-fullwidth-code-point": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
          "dev": true,
          "requires": {
            "number-is-nan": "^1.0.0"
          }
        },
        "string-width": {
          "version": "1.0.2",
          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
          "dev": true,
          "requires": {
            "code-point-at": "^1.0.0",
            "is-fullwidth-code-point": "^1.0.0",
            "strip-ansi": "^3.0.0"
          }
        },
        "strip-ansi": {
          "version": "3.0.1",
          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
          "dev": true,
          "requires": {
            "ansi-regex": "^2.0.0"
          }
        }
      }
    },
    "gensync": {
      "version": "1.0.0-beta.2",
      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
      "dev": true
    },
    "get-caller-file": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
      "dev": true
    },
    "get-intrinsic": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
      "dev": true,
      "requires": {
        "function-bind": "^1.1.1",
        "has": "^1.0.3",
        "has-symbols": "^1.0.1"
      }
    },
    "get-stream": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
      "dev": true,
      "requires": {
        "pump": "^3.0.0"
      }
    },
    "get-value": {
      "version": "2.0.6",
      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
      "dev": true
    },
    "getpass": {
      "version": "0.1.7",
      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
      "dev": true,
      "requires": {
        "assert-plus": "^1.0.0"
      }
    },
    "glob": {
      "version": "7.1.7",
      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
      "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
      "dev": true,
      "requires": {
        "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"
      }
    },
    "glob-parent": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
      "dev": true,
      "requires": {
        "is-glob": "^4.0.1"
      }
    },
    "glob-to-regexp": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
      "dev": true
    },
    "globals": {
      "version": "11.12.0",
      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
      "dev": true
    },
    "globby": {
      "version": "11.1.0",
      "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
      "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
      "dev": true,
      "requires": {
        "array-union": "^2.1.0",
        "dir-glob": "^3.0.1",
        "fast-glob": "^3.2.9",
        "ignore": "^5.2.0",
        "merge2": "^1.4.1",
        "slash": "^3.0.0"
      }
    },
    "graceful-fs": {
      "version": "4.2.9",
      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
      "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==",
      "dev": true
    },
    "handle-thing": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
      "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==",
      "dev": true
    },
    "har-schema": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
      "dev": true
    },
    "har-validator": {
      "version": "5.1.5",
      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
      "dev": true,
      "requires": {
        "ajv": "^6.12.3",
        "har-schema": "^2.0.0"
      },
      "dependencies": {
        "ajv": {
          "version": "6.12.6",
          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
          "dev": true,
          "requires": {
            "fast-deep-equal": "^3.1.1",
            "fast-json-stable-stringify": "^2.0.0",
            "json-schema-traverse": "^0.4.1",
            "uri-js": "^4.2.2"
          }
        },
        "json-schema-traverse": {
          "version": "0.4.1",
          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
          "dev": true
        }
      }
    },
    "has": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
      "dev": true,
      "requires": {
        "function-bind": "^1.1.1"
      }
    },
    "has-flag": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
      "dev": true
    },
    "has-symbols": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
      "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
      "dev": true
    },
    "has-tostringtag": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
      "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
      "dev": true,
      "requires": {
        "has-symbols": "^1.0.2"
      }
    },
    "has-unicode": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
      "dev": true
    },
    "has-value": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
      "dev": true,
      "requires": {
        "get-value": "^2.0.6",
        "has-values": "^1.0.0",
        "isobject": "^3.0.0"
      }
    },
    "has-values": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
      "dev": true,
      "requires": {
        "is-number": "^3.0.0",
        "kind-of": "^4.0.0"
      },
      "dependencies": {
        "is-number": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
          "dev": true,
          "requires": {
            "kind-of": "^3.0.2"
          },
          "dependencies": {
            "kind-of": {
              "version": "3.2.2",
              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
              "dev": true,
              "requires": {
                "is-buffer": "^1.1.5"
              }
            }
          }
        },
        "kind-of": {
          "version": "4.0.0",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
          "dev": true,
          "requires": {
            "is-buffer": "^1.1.5"
          }
        }
      }
    },
    "hosted-git-info": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
      "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
      "dev": true,
      "requires": {
        "lru-cache": "^6.0.0"
      }
    },
    "hpack.js": {
      "version": "2.1.6",
      "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
      "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
      "dev": true,
      "requires": {
        "inherits": "^2.0.1",
        "obuf": "^1.0.0",
        "readable-stream": "^2.0.1",
        "wbuf": "^1.1.0"
      },
      "dependencies": {
        "readable-stream": {
          "version": "2.3.7",
          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
          "dev": true,
          "requires": {
            "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"
          }
        },
        "string_decoder": {
          "version": "1.1.1",
          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
          "dev": true,
          "requires": {
            "safe-buffer": "~5.1.0"
          }
        }
      }
    },
    "html-entities": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz",
      "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==",
      "dev": true
    },
    "html-escaper": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
      "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
      "dev": true
    },
    "http-cache-semantics": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
      "dev": true
    },
    "http-deceiver": {
      "version": "1.2.7",
      "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
      "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
      "dev": true
    },
    "http-errors": {
      "version": "1.8.1",
      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
      "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
      "dev": true,
      "requires": {
        "depd": "~1.1.2",
        "inherits": "2.0.4",
        "setprototypeof": "1.2.0",
        "statuses": ">= 1.5.0 < 2",
        "toidentifier": "1.0.1"
      }
    },
    "http-parser-js": {
      "version": "0.5.5",
      "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz",
      "integrity": "sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==",
      "dev": true
    },
    "http-proxy": {
      "version": "1.18.1",
      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
      "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
      "dev": true,
      "requires": {
        "eventemitter3": "^4.0.0",
        "follow-redirects": "^1.0.0",
        "requires-port": "^1.0.0"
      }
    },
    "http-proxy-agent": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
      "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
      "dev": true,
      "requires": {
        "@tootallnate/once": "1",
        "agent-base": "6",
        "debug": "4"
      }
    },
    "http-proxy-middleware": {
      "version": "0.19.1",
      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
      "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
      "dev": true,
      "requires": {
        "http-proxy": "^1.17.0",
        "is-glob": "^4.0.0",
        "lodash": "^4.17.11",
        "micromatch": "^3.1.10"
      },
      "dependencies": {
        "braces": {
          "version": "2.3.2",
          "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
          "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
          "dev": true,
          "requires": {
            "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"
          },
          "dependencies": {
            "extend-shallow": {
              "version": "2.0.1",
              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
              "dev": true,
              "requires": {
                "is-extendable": "^0.1.0"
              }
            }
          }
        },
        "fill-range": {
          "version": "4.0.0",
          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
          "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
          "dev": true,
          "requires": {
            "extend-shallow": "^2.0.1",
            "is-number": "^3.0.0",
            "repeat-string": "^1.6.1",
            "to-regex-range": "^2.1.0"
          },
          "dependencies": {
            "extend-shallow": {
              "version": "2.0.1",
              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
              "dev": true,
              "requires": {
                "is-extendable": "^0.1.0"
              }
            }
          }
        },
        "is-extendable": {
          "version": "0.1.1",
          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
          "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
          "dev": true
        },
        "is-number": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
          "dev": true,
          "requires": {
            "kind-of": "^3.0.2"
          },
          "dependencies": {
            "kind-of": {
              "version": "3.2.2",
              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
              "dev": true,
              "requires": {
                "is-buffer": "^1.1.5"
              }
            }
          }
        },
        "micromatch": {
          "version": "3.1.10",
          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
          "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
          "dev": true,
          "requires": {
            "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"
          }
        },
        "to-regex-range": {
          "version": "2.1.1",
          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
          "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
          "dev": true,
          "requires": {
            "is-number": "^3.0.0",
            "repeat-string": "^1.6.1"
          }
        }
      }
    },
    "http-signature": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
      "dev": true,
      "requires": {
        "assert-plus": "^1.0.0",
        "jsprim": "^1.2.2",
        "sshpk": "^1.7.0"
      }
    },
    "https-proxy-agent": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
      "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
      "dev": true,
      "requires": {
        "agent-base": "6",
        "debug": "4"
      }
    },
    "humanize-ms": {
      "version": "1.2.1",
      "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
      "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=",
      "dev": true,
      "requires": {
        "ms": "^2.0.0"
      }
    },
    "iconv-lite": {
      "version": "0.4.24",
      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
      "dev": true,
      "requires": {
        "safer-buffer": ">= 2.1.2 < 3"
      }
    },
    "icss-utils": {
      "version": "5.1.0",
      "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
      "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
      "dev": true,
      "requires": {}
    },
    "ieee754": {
      "version": "1.2.1",
      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
      "dev": true
    },
    "ignore": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
      "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
      "dev": true
    },
    "ignore-walk": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz",
      "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==",
      "dev": true,
      "requires": {
        "minimatch": "^3.0.4"
      }
    },
    "image-size": {
      "version": "0.5.5",
      "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
      "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
      "dev": true,
      "optional": true
    },
    "import-fresh": {
      "version": "3.3.0",
      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
      "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
      "dev": true,
      "requires": {
        "parent-module": "^1.0.0",
        "resolve-from": "^4.0.0"
      }
    },
    "import-local": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
      "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==",
      "dev": true,
      "requires": {
        "pkg-dir": "^3.0.0",
        "resolve-cwd": "^2.0.0"
      },
      "dependencies": {
        "find-up": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
          "dev": true,
          "requires": {
            "locate-path": "^3.0.0"
          }
        },
        "locate-path": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
          "dev": true,
          "requires": {
            "p-locate": "^3.0.0",
            "path-exists": "^3.0.0"
          }
        },
        "p-limit": {
          "version": "2.3.0",
          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
          "dev": true,
          "requires": {
            "p-try": "^2.0.0"
          }
        },
        "p-locate": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
          "dev": true,
          "requires": {
            "p-limit": "^2.0.0"
          }
        },
        "path-exists": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
          "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
          "dev": true
        },
        "pkg-dir": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
          "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
          "dev": true,
          "requires": {
            "find-up": "^3.0.0"
          }
        }
      }
    },
    "imurmurhash": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
      "dev": true
    },
    "indent-string": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
      "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
      "dev": true
    },
    "indexes-of": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
      "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
      "dev": true
    },
    "infer-owner": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
      "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
      "dev": true
    },
    "inflight": {
      "version": "1.0.6",
      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
      "dev": true,
      "requires": {
        "once": "^1.3.0",
        "wrappy": "1"
      }
    },
    "inherits": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
      "dev": true
    },
    "ini": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
      "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
      "dev": true
    },
    "inquirer": {
      "version": "8.1.1",
      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.1.1.tgz",
      "integrity": "sha512-hUDjc3vBkh/uk1gPfMAD/7Z188Q8cvTGl0nxwaCdwSbzFh6ZKkZh+s2ozVxbE5G9ZNRyeY0+lgbAIOUFsFf98w==",
      "dev": true,
      "requires": {
        "ansi-escapes": "^4.2.1",
        "chalk": "^4.1.1",
        "cli-cursor": "^3.1.0",
        "cli-width": "^3.0.0",
        "external-editor": "^3.0.3",
        "figures": "^3.0.0",
        "lodash": "^4.17.21",
        "mute-stream": "0.0.8",
        "ora": "^5.3.0",
        "run-async": "^2.4.0",
        "rxjs": "^6.6.6",
        "string-width": "^4.1.0",
        "strip-ansi": "^6.0.0",
        "through": "^2.3.6"
      },
      "dependencies": {
        "ansi-styles": {
          "version": "4.3.0",
          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
          "dev": true,
          "requires": {
            "color-convert": "^2.0.1"
          }
        },
        "chalk": {
          "version": "4.1.2",
          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
          "dev": true,
          "requires": {
            "ansi-styles": "^4.1.0",
            "supports-color": "^7.1.0"
          }
        },
        "color-convert": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
          "dev": true,
          "requires": {
            "color-name": "~1.1.4"
          }
        },
        "color-name": {
          "version": "1.1.4",
          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
          "dev": true
        },
        "has-flag": {
          "version": "4.0.0",
          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
          "dev": true
        },
        "supports-color": {
          "version": "7.2.0",
          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
          "dev": true,
          "requires": {
            "has-flag": "^4.0.0"
          }
        }
      }
    },
    "internal-ip": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz",
      "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==",
      "dev": true,
      "requires": {
        "default-gateway": "^4.2.0",
        "ipaddr.js": "^1.9.0"
      }
    },
    "ip": {
      "version": "1.1.5",
      "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
      "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
      "dev": true
    },
    "ip-regex": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
      "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
      "dev": true
    },
    "ipaddr.js": {
      "version": "1.9.1",
      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
      "dev": true
    },
    "is-absolute-url": {
      "version": "3.0.3",
      "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz",
      "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==",
      "dev": true
    },
    "is-accessor-descriptor": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
      "dev": true,
      "requires": {
        "kind-of": "^6.0.0"
      }
    },
    "is-arguments": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
      "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
      "dev": true,
      "requires": {
        "call-bind": "^1.0.2",
        "has-tostringtag": "^1.0.0"
      }
    },
    "is-arrayish": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
      "dev": true
    },
    "is-binary-path": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
      "dev": true,
      "requires": {
        "binary-extensions": "^2.0.0"
      }
    },
    "is-buffer": {
      "version": "1.1.6",
      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
      "dev": true
    },
    "is-core-module": {
      "version": "2.8.1",
      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
      "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==",
      "dev": true,
      "requires": {
        "has": "^1.0.3"
      }
    },
    "is-data-descriptor": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
      "dev": true,
      "requires": {
        "kind-of": "^6.0.0"
      }
    },
    "is-date-object": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
      "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
      "dev": true,
      "requires": {
        "has-tostringtag": "^1.0.0"
      }
    },
    "is-descriptor": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
      "dev": true,
      "requires": {
        "is-accessor-descriptor": "^1.0.0",
        "is-data-descriptor": "^1.0.0",
        "kind-of": "^6.0.2"
      }
    },
    "is-docker": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
      "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
      "dev": true
    },
    "is-extendable": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
      "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
      "dev": true,
      "requires": {
        "is-plain-object": "^2.0.4"
      }
    },
    "is-extglob": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
      "dev": true
    },
    "is-fullwidth-code-point": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
      "dev": true
    },
    "is-glob": {
      "version": "4.0.3",
      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
      "dev": true,
      "requires": {
        "is-extglob": "^2.1.1"
      }
    },
    "is-interactive": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
      "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
      "dev": true
    },
    "is-lambda": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
      "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=",
      "dev": true
    },
    "is-number": {
      "version": "7.0.0",
      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
      "dev": true
    },
    "is-path-cwd": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
      "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
      "dev": true
    },
    "is-path-in-cwd": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz",
      "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==",
      "dev": true,
      "requires": {
        "is-path-inside": "^2.1.0"
      }
    },
    "is-path-inside": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
      "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
      "dev": true,
      "requires": {
        "path-is-inside": "^1.0.2"
      }
    },
    "is-plain-object": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
      "dev": true,
      "requires": {
        "isobject": "^3.0.1"
      }
    },
    "is-regex": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
      "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
      "dev": true,
      "requires": {
        "call-bind": "^1.0.2",
        "has-tostringtag": "^1.0.0"
      }
    },
    "is-stream": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
      "dev": true
    },
    "is-typedarray": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
      "dev": true
    },
    "is-unicode-supported": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
      "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
      "dev": true
    },
    "is-what": {
      "version": "3.14.1",
      "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz",
      "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==",
      "dev": true
    },
    "is-windows": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
      "dev": true
    },
    "is-wsl": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
      "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
      "dev": true,
      "requires": {
        "is-docker": "^2.0.0"
      }
    },
    "isarray": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
      "dev": true
    },
    "isbinaryfile": {
      "version": "4.0.8",
      "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz",
      "integrity": "sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==",
      "dev": true
    },
    "isexe": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
      "dev": true
    },
    "isobject": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
      "dev": true
    },
    "isstream": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
      "dev": true
    },
    "istanbul-lib-coverage": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
      "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
      "dev": true
    },
    "istanbul-lib-instrument": {
      "version": "4.0.3",
      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
      "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
      "dev": true,
      "requires": {
        "@babel/core": "^7.7.5",
        "@istanbuljs/schema": "^0.1.2",
        "istanbul-lib-coverage": "^3.0.0",
        "semver": "^6.3.0"
      },
      "dependencies": {
        "semver": {
          "version": "6.3.0",
          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
          "dev": true
        }
      }
    },
    "istanbul-lib-report": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
      "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
      "dev": true,
      "requires": {
        "istanbul-lib-coverage": "^3.0.0",
        "make-dir": "^3.0.0",
        "supports-color": "^7.1.0"
      },
      "dependencies": {
        "has-flag": {
          "version": "4.0.0",
          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
          "dev": true
        },
        "supports-color": {
          "version": "7.2.0",
          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
          "dev": true,
          "requires": {
            "has-flag": "^4.0.0"
          }
        }
      }
    },
    "istanbul-lib-source-maps": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
      "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
      "dev": true,
      "requires": {
        "debug": "^4.1.1",
        "istanbul-lib-coverage": "^3.0.0",
        "source-map": "^0.6.1"
      },
      "dependencies": {
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "istanbul-reports": {
      "version": "3.1.3",
      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz",
      "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==",
      "dev": true,
      "requires": {
        "html-escaper": "^2.0.0",
        "istanbul-lib-report": "^3.0.0"
      }
    },
    "jasmine-core": {
      "version": "3.7.1",
      "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.7.1.tgz",
      "integrity": "sha512-DH3oYDS/AUvvr22+xUBW62m1Xoy7tUlY1tsxKEJvl5JeJ7q8zd1K5bUwiOxdH+erj6l2vAMM3hV25Xs9/WrmuQ==",
      "dev": true
    },
    "jest-worker": {
      "version": "27.0.2",
      "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.2.tgz",
      "integrity": "sha512-EoBdilOTTyOgmHXtw/cPc+ZrCA0KJMrkXzkrPGNwLmnvvlN1nj7MPrxpT7m+otSv2e1TLaVffzDnE/LB14zJMg==",
      "dev": true,
      "requires": {
        "@types/node": "*",
        "merge-stream": "^2.0.0",
        "supports-color": "^8.0.0"
      },
      "dependencies": {
        "has-flag": {
          "version": "4.0.0",
          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
          "dev": true
        },
        "supports-color": {
          "version": "8.1.1",
          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
          "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
          "dev": true,
          "requires": {
            "has-flag": "^4.0.0"
          }
        }
      }
    },
    "js-tokens": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
      "dev": true
    },
    "jsbn": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
      "dev": true
    },
    "jsesc": {
      "version": "2.5.2",
      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
      "dev": true
    },
    "json-parse-better-errors": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
      "dev": true
    },
    "json-parse-even-better-errors": {
      "version": "2.3.1",
      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
      "dev": true
    },
    "json-schema": {
      "version": "0.4.0",
      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
      "dev": true
    },
    "json-schema-traverse": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
      "dev": true
    },
    "json-stringify-safe": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
      "dev": true
    },
    "json3": {
      "version": "3.3.3",
      "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz",
      "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==",
      "dev": true
    },
    "json5": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
      "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
      "dev": true,
      "requires": {
        "minimist": "^1.2.5"
      }
    },
    "jsonc-parser": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz",
      "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==",
      "dev": true
    },
    "jsonfile": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
      "dev": true,
      "requires": {
        "graceful-fs": "^4.1.6"
      }
    },
    "jsonparse": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
      "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
      "dev": true
    },
    "jsprim": {
      "version": "1.4.2",
      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
      "dev": true,
      "requires": {
        "assert-plus": "1.0.0",
        "extsprintf": "1.3.0",
        "json-schema": "0.4.0",
        "verror": "1.10.0"
      }
    },
    "karma": {
      "version": "6.3.11",
      "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.11.tgz",
      "integrity": "sha512-QGUh4yXgizzDNPLB5nWTvP+wysKexngbyLVWFOyikB661hpa2RZLf5anZQzqliWtAQuYVep0ot0D1U7UQKpsxQ==",
      "dev": true,
      "requires": {
        "body-parser": "^1.19.0",
        "braces": "^3.0.2",
        "chokidar": "^3.5.1",
        "colors": "1.4.0",
        "connect": "^3.7.0",
        "di": "^0.0.1",
        "dom-serialize": "^2.2.1",
        "glob": "^7.1.7",
        "graceful-fs": "^4.2.6",
        "http-proxy": "^1.18.1",
        "isbinaryfile": "^4.0.8",
        "lodash": "^4.17.21",
        "log4js": "^6.3.0",
        "mime": "^2.5.2",
        "minimatch": "^3.0.4",
        "qjobs": "^1.2.0",
        "range-parser": "^1.2.1",
        "rimraf": "^3.0.2",
        "socket.io": "^4.2.0",
        "source-map": "^0.6.1",
        "tmp": "^0.2.1",
        "ua-parser-js": "^0.7.30",
        "yargs": "^16.1.1"
      },
      "dependencies": {
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        },
        "tmp": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
          "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
          "dev": true,
          "requires": {
            "rimraf": "^3.0.0"
          }
        },
        "yargs": {
          "version": "16.2.0",
          "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
          "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
          "dev": true,
          "requires": {
            "cliui": "^7.0.2",
            "escalade": "^3.1.1",
            "get-caller-file": "^2.0.5",
            "require-directory": "^2.1.1",
            "string-width": "^4.2.0",
            "y18n": "^5.0.5",
            "yargs-parser": "^20.2.2"
          }
        },
        "yargs-parser": {
          "version": "20.2.9",
          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
          "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
          "dev": true
        }
      }
    },
    "karma-chrome-launcher": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz",
      "integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==",
      "dev": true,
      "requires": {
        "which": "^1.2.1"
      }
    },
    "karma-coverage": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.0.3.tgz",
      "integrity": "sha512-atDvLQqvPcLxhED0cmXYdsPMCQuh6Asa9FMZW1bhNqlVEhJoB9qyZ2BY1gu7D/rr5GLGb5QzYO4siQskxaWP/g==",
      "dev": true,
      "requires": {
        "istanbul-lib-coverage": "^3.0.0",
        "istanbul-lib-instrument": "^4.0.1",
        "istanbul-lib-report": "^3.0.0",
        "istanbul-lib-source-maps": "^4.0.0",
        "istanbul-reports": "^3.0.0",
        "minimatch": "^3.0.4"
      }
    },
    "karma-jasmine": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-4.0.1.tgz",
      "integrity": "sha512-h8XDAhTiZjJKzfkoO1laMH+zfNlra+dEQHUAjpn5JV1zCPtOIVWGQjLBrqhnzQa/hrU2XrZwSyBa6XjEBzfXzw==",
      "dev": true,
      "requires": {
        "jasmine-core": "^3.6.0"
      }
    },
    "karma-jasmine-html-reporter": {
      "version": "1.7.0",
      "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.7.0.tgz",
      "integrity": "sha512-pzum1TL7j90DTE86eFt48/s12hqwQuiD+e5aXx2Dc9wDEn2LfGq6RoAxEZZjFiN0RDSCOnosEKRZWxbQ+iMpQQ==",
      "dev": true,
      "requires": {}
    },
    "karma-source-map-support": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz",
      "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==",
      "dev": true,
      "requires": {
        "source-map-support": "^0.5.5"
      }
    },
    "killable": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
      "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==",
      "dev": true
    },
    "kind-of": {
      "version": "6.0.3",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
      "dev": true
    },
    "klona": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz",
      "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==",
      "dev": true
    },
    "less": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/less/-/less-4.1.1.tgz",
      "integrity": "sha512-w09o8tZFPThBscl5d0Ggp3RcrKIouBoQscnOMgFH3n5V3kN/CXGHNfCkRPtxJk6nKryDXaV9aHLK55RXuH4sAw==",
      "dev": true,
      "requires": {
        "copy-anything": "^2.0.1",
        "errno": "^0.1.1",
        "graceful-fs": "^4.1.2",
        "image-size": "~0.5.0",
        "make-dir": "^2.1.0",
        "mime": "^1.4.1",
        "needle": "^2.5.2",
        "parse-node-version": "^1.0.1",
        "source-map": "~0.6.0",
        "tslib": "^1.10.0"
      },
      "dependencies": {
        "make-dir": {
          "version": "2.1.0",
          "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
          "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
          "dev": true,
          "optional": true,
          "requires": {
            "pify": "^4.0.1",
            "semver": "^5.6.0"
          }
        },
        "mime": {
          "version": "1.6.0",
          "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
          "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
          "dev": true,
          "optional": true
        },
        "pify": {
          "version": "4.0.1",
          "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
          "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
          "dev": true,
          "optional": true
        },
        "semver": {
          "version": "5.7.1",
          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
          "dev": true,
          "optional": true
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true,
          "optional": true
        },
        "tslib": {
          "version": "1.14.1",
          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
          "dev": true
        }
      }
    },
    "less-loader": {
      "version": "10.0.0",
      "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-10.0.0.tgz",
      "integrity": "sha512-JjioAkw9qyavL0BzMPUOHJa0a20fh+ipq/MNZH4OkU8qERsCMeZIWRE0FDBIx2O+cFguvY01vHh/lmBA9LyWDg==",
      "dev": true,
      "requires": {
        "klona": "^2.0.4"
      }
    },
    "license-webpack-plugin": {
      "version": "2.3.20",
      "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-2.3.20.tgz",
      "integrity": "sha512-AHVueg9clOKACSHkhmEI+PCC9x8+qsQVuKECZD3ETxETK5h/PCv5/MUzyG1gm8OMcip/s1tcNxqo9Qb7WhjGsg==",
      "dev": true,
      "requires": {
        "@types/webpack-sources": "^0.1.5",
        "webpack-sources": "^1.2.0"
      }
    },
    "lilconfig": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz",
      "integrity": "sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==",
      "dev": true
    },
    "lines-and-columns": {
      "version": "1.2.4",
      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
      "dev": true
    },
    "loader-runner": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz",
      "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==",
      "dev": true
    },
    "loader-utils": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
      "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
      "dev": true,
      "requires": {
        "big.js": "^5.2.2",
        "emojis-list": "^3.0.0",
        "json5": "^2.1.2"
      }
    },
    "locate-path": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
      "dev": true,
      "requires": {
        "p-locate": "^4.1.0"
      }
    },
    "lodash": {
      "version": "4.17.21",
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
      "dev": true
    },
    "lodash.debounce": {
      "version": "4.0.8",
      "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
      "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
    },
    "lodash.memoize": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
      "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
    },
    "lodash.throttle": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
      "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
    },
    "lodash.uniq": {
      "version": "4.5.0",
      "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
      "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
      "dev": true
    },
    "log-symbols": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
      "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
      "dev": true,
      "requires": {
        "chalk": "^4.1.0",
        "is-unicode-supported": "^0.1.0"
      },
      "dependencies": {
        "ansi-styles": {
          "version": "4.3.0",
          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
          "dev": true,
          "requires": {
            "color-convert": "^2.0.1"
          }
        },
        "chalk": {
          "version": "4.1.2",
          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
          "dev": true,
          "requires": {
            "ansi-styles": "^4.1.0",
            "supports-color": "^7.1.0"
          }
        },
        "color-convert": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
          "dev": true,
          "requires": {
            "color-name": "~1.1.4"
          }
        },
        "color-name": {
          "version": "1.1.4",
          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
          "dev": true
        },
        "has-flag": {
          "version": "4.0.0",
          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
          "dev": true
        },
        "supports-color": {
          "version": "7.2.0",
          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
          "dev": true,
          "requires": {
            "has-flag": "^4.0.0"
          }
        }
      }
    },
    "log4js": {
      "version": "6.3.0",
      "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz",
      "integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==",
      "dev": true,
      "requires": {
        "date-format": "^3.0.0",
        "debug": "^4.1.1",
        "flatted": "^2.0.1",
        "rfdc": "^1.1.4",
        "streamroller": "^2.2.4"
      }
    },
    "loglevel": {
      "version": "1.8.0",
      "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.8.0.tgz",
      "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==",
      "dev": true
    },
    "lru-cache": {
      "version": "6.0.0",
      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
      "dev": true,
      "requires": {
        "yallist": "^4.0.0"
      }
    },
    "magic-string": {
      "version": "0.25.7",
      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
      "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
      "dev": true,
      "requires": {
        "sourcemap-codec": "^1.4.4"
      }
    },
    "make-dir": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
      "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
      "dev": true,
      "requires": {
        "semver": "^6.0.0"
      },
      "dependencies": {
        "semver": {
          "version": "6.3.0",
          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
          "dev": true
        }
      }
    },
    "make-fetch-happen": {
      "version": "9.1.0",
      "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
      "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
      "dev": true,
      "requires": {
        "agentkeepalive": "^4.1.3",
        "cacache": "^15.2.0",
        "http-cache-semantics": "^4.1.0",
        "http-proxy-agent": "^4.0.1",
        "https-proxy-agent": "^5.0.0",
        "is-lambda": "^1.0.1",
        "lru-cache": "^6.0.0",
        "minipass": "^3.1.3",
        "minipass-collect": "^1.0.2",
        "minipass-fetch": "^1.3.2",
        "minipass-flush": "^1.0.5",
        "minipass-pipeline": "^1.2.4",
        "negotiator": "^0.6.2",
        "promise-retry": "^2.0.1",
        "socks-proxy-agent": "^6.0.0",
        "ssri": "^8.0.0"
      }
    },
    "map-age-cleaner": {
      "version": "0.1.3",
      "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
      "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
      "dev": true,
      "requires": {
        "p-defer": "^1.0.0"
      }
    },
    "map-cache": {
      "version": "0.2.2",
      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
      "dev": true
    },
    "map-visit": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
      "dev": true,
      "requires": {
        "object-visit": "^1.0.0"
      }
    },
    "mdn-data": {
      "version": "2.0.14",
      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
      "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
      "dev": true
    },
    "media-typer": {
      "version": "0.3.0",
      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
      "dev": true
    },
    "mem": {
      "version": "8.1.1",
      "resolved": "https://registry.npmjs.org/mem/-/mem-8.1.1.tgz",
      "integrity": "sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA==",
      "dev": true,
      "requires": {
        "map-age-cleaner": "^0.1.3",
        "mimic-fn": "^3.1.0"
      },
      "dependencies": {
        "mimic-fn": {
          "version": "3.1.0",
          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz",
          "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==",
          "dev": true
        }
      }
    },
    "memfs": {
      "version": "3.4.1",
      "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz",
      "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==",
      "dev": true,
      "requires": {
        "fs-monkey": "1.0.3"
      }
    },
    "memory-fs": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
      "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
      "dev": true,
      "requires": {
        "errno": "^0.1.3",
        "readable-stream": "^2.0.1"
      },
      "dependencies": {
        "readable-stream": {
          "version": "2.3.7",
          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
          "dev": true,
          "requires": {
            "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"
          }
        },
        "string_decoder": {
          "version": "1.1.1",
          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
          "dev": true,
          "requires": {
            "safe-buffer": "~5.1.0"
          }
        }
      }
    },
    "merge-descriptors": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
      "dev": true
    },
    "merge-source-map": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz",
      "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==",
      "dev": true,
      "requires": {
        "source-map": "^0.6.1"
      },
      "dependencies": {
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "merge-stream": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
      "dev": true
    },
    "merge2": {
      "version": "1.4.1",
      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
      "dev": true
    },
    "methods": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
      "dev": true
    },
    "micromatch": {
      "version": "4.0.4",
      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
      "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
      "dev": true,
      "requires": {
        "braces": "^3.0.1",
        "picomatch": "^2.2.3"
      }
    },
    "mime": {
      "version": "2.6.0",
      "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
      "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
      "dev": true
    },
    "mime-db": {
      "version": "1.51.0",
      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
      "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
      "dev": true
    },
    "mime-types": {
      "version": "2.1.34",
      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
      "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
      "dev": true,
      "requires": {
        "mime-db": "1.51.0"
      }
    },
    "mimic-fn": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
      "dev": true
    },
    "mini-css-extract-plugin": {
      "version": "1.6.2",
      "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz",
      "integrity": "sha512-WhDvO3SjGm40oV5y26GjMJYjd2UMqrLAGKy5YS2/3QKJy2F7jgynuHTir/tgUUOiNQu5saXHdc8reo7YuhhT4Q==",
      "dev": true,
      "requires": {
        "loader-utils": "^2.0.0",
        "schema-utils": "^3.0.0",
        "webpack-sources": "^1.1.0"
      },
      "dependencies": {
        "ajv": {
          "version": "6.12.6",
          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
          "dev": true,
          "requires": {
            "fast-deep-equal": "^3.1.1",
            "fast-json-stable-stringify": "^2.0.0",
            "json-schema-traverse": "^0.4.1",
            "uri-js": "^4.2.2"
          }
        },
        "ajv-keywords": {
          "version": "3.5.2",
          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
          "dev": true,
          "requires": {}
        },
        "json-schema-traverse": {
          "version": "0.4.1",
          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
          "dev": true
        },
        "schema-utils": {
          "version": "3.1.1",
          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
          "dev": true,
          "requires": {
            "@types/json-schema": "^7.0.8",
            "ajv": "^6.12.5",
            "ajv-keywords": "^3.5.2"
          }
        }
      }
    },
    "minimalistic-assert": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
      "dev": true
    },
    "minimatch": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
      "dev": true,
      "requires": {
        "brace-expansion": "^1.1.7"
      }
    },
    "minimist": {
      "version": "1.2.5",
      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
      "dev": true
    },
    "minipass": {
      "version": "3.1.6",
      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz",
      "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==",
      "dev": true,
      "requires": {
        "yallist": "^4.0.0"
      }
    },
    "minipass-collect": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
      "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
      "dev": true,
      "requires": {
        "minipass": "^3.0.0"
      }
    },
    "minipass-fetch": {
      "version": "1.4.1",
      "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
      "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
      "dev": true,
      "requires": {
        "encoding": "^0.1.12",
        "minipass": "^3.1.0",
        "minipass-sized": "^1.0.3",
        "minizlib": "^2.0.0"
      }
    },
    "minipass-flush": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
      "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
      "dev": true,
      "requires": {
        "minipass": "^3.0.0"
      }
    },
    "minipass-json-stream": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz",
      "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==",
      "dev": true,
      "requires": {
        "jsonparse": "^1.3.1",
        "minipass": "^3.0.0"
      }
    },
    "minipass-pipeline": {
      "version": "1.2.4",
      "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
      "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
      "dev": true,
      "requires": {
        "minipass": "^3.0.0"
      }
    },
    "minipass-sized": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
      "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
      "dev": true,
      "requires": {
        "minipass": "^3.0.0"
      }
    },
    "minizlib": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
      "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
      "dev": true,
      "requires": {
        "minipass": "^3.0.0",
        "yallist": "^4.0.0"
      }
    },
    "mixin-deep": {
      "version": "1.3.2",
      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
      "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
      "dev": true,
      "requires": {
        "for-in": "^1.0.2",
        "is-extendable": "^1.0.1"
      }
    },
    "mkdirp": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
      "dev": true
    },
    "ms": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
      "dev": true
    },
    "multicast-dns": {
      "version": "6.2.3",
      "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
      "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
      "dev": true,
      "requires": {
        "dns-packet": "^1.3.1",
        "thunky": "^1.0.2"
      }
    },
    "multicast-dns-service-types": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
      "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
      "dev": true
    },
    "mute-stream": {
      "version": "0.0.8",
      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
      "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
      "dev": true
    },
    "nan": {
      "version": "2.15.0",
      "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
      "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
      "dev": true,
      "optional": true
    },
    "nanoid": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
      "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
      "dev": true
    },
    "nanomatch": {
      "version": "1.2.13",
      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
      "dev": true,
      "requires": {
        "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"
      }
    },
    "needle": {
      "version": "2.9.1",
      "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz",
      "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==",
      "dev": true,
      "optional": true,
      "requires": {
        "debug": "^3.2.6",
        "iconv-lite": "^0.4.4",
        "sax": "^1.2.4"
      },
      "dependencies": {
        "debug": {
          "version": "3.2.7",
          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
          "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
          "dev": true,
          "optional": true,
          "requires": {
            "ms": "^2.1.1"
          }
        }
      }
    },
    "negotiator": {
      "version": "0.6.2",
      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
      "dev": true
    },
    "neo-async": {
      "version": "2.6.2",
      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
      "dev": true
    },
    "nice-try": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
      "dev": true
    },
    "node-forge": {
      "version": "0.10.0",
      "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
      "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==",
      "dev": true
    },
    "node-gyp": {
      "version": "7.1.2",
      "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz",
      "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==",
      "dev": true,
      "requires": {
        "env-paths": "^2.2.0",
        "glob": "^7.1.4",
        "graceful-fs": "^4.2.3",
        "nopt": "^5.0.0",
        "npmlog": "^4.1.2",
        "request": "^2.88.2",
        "rimraf": "^3.0.2",
        "semver": "^7.3.2",
        "tar": "^6.0.2",
        "which": "^2.0.2"
      },
      "dependencies": {
        "which": {
          "version": "2.0.2",
          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
          "dev": true,
          "requires": {
            "isexe": "^2.0.0"
          }
        }
      }
    },
    "node-releases": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz",
      "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==",
      "dev": true
    },
    "nopt": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
      "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
      "dev": true,
      "requires": {
        "abbrev": "1"
      }
    },
    "normalize-path": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
      "dev": true
    },
    "normalize-range": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
      "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
      "dev": true
    },
    "normalize-url": {
      "version": "6.1.0",
      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
      "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
      "dev": true
    },
    "npm-bundled": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz",
      "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==",
      "dev": true,
      "requires": {
        "npm-normalize-package-bin": "^1.0.1"
      }
    },
    "npm-install-checks": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-4.0.0.tgz",
      "integrity": "sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w==",
      "dev": true,
      "requires": {
        "semver": "^7.1.1"
      }
    },
    "npm-normalize-package-bin": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz",
      "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==",
      "dev": true
    },
    "npm-package-arg": {
      "version": "8.1.5",
      "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.5.tgz",
      "integrity": "sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q==",
      "dev": true,
      "requires": {
        "hosted-git-info": "^4.0.1",
        "semver": "^7.3.4",
        "validate-npm-package-name": "^3.0.0"
      }
    },
    "npm-packlist": {
      "version": "2.2.2",
      "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-2.2.2.tgz",
      "integrity": "sha512-Jt01acDvJRhJGthnUJVF/w6gumWOZxO7IkpY/lsX9//zqQgnF7OJaxgQXcerd4uQOLu7W5bkb4mChL9mdfm+Zg==",
      "dev": true,
      "requires": {
        "glob": "^7.1.6",
        "ignore-walk": "^3.0.3",
        "npm-bundled": "^1.1.1",
        "npm-normalize-package-bin": "^1.0.1"
      }
    },
    "npm-pick-manifest": {
      "version": "6.1.1",
      "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz",
      "integrity": "sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA==",
      "dev": true,
      "requires": {
        "npm-install-checks": "^4.0.0",
        "npm-normalize-package-bin": "^1.0.1",
        "npm-package-arg": "^8.1.2",
        "semver": "^7.3.4"
      }
    },
    "npm-registry-fetch": {
      "version": "11.0.0",
      "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-11.0.0.tgz",
      "integrity": "sha512-jmlgSxoDNuhAtxUIG6pVwwtz840i994dL14FoNVZisrmZW5kWd63IUTNv1m/hyRSGSqWjCUp/YZlS1BJyNp9XA==",
      "dev": true,
      "requires": {
        "make-fetch-happen": "^9.0.1",
        "minipass": "^3.1.3",
        "minipass-fetch": "^1.3.0",
        "minipass-json-stream": "^1.0.1",
        "minizlib": "^2.0.0",
        "npm-package-arg": "^8.0.0"
      }
    },
    "npm-run-path": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
      "dev": true,
      "requires": {
        "path-key": "^2.0.0"
      }
    },
    "npmlog": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
      "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
      "dev": true,
      "requires": {
        "are-we-there-yet": "~1.1.2",
        "console-control-strings": "~1.1.0",
        "gauge": "~2.7.3",
        "set-blocking": "~2.0.0"
      }
    },
    "nth-check": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
      "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
      "dev": true,
      "requires": {
        "boolbase": "^1.0.0"
      }
    },
    "num2fraction": {
      "version": "1.2.2",
      "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
      "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
      "dev": true
    },
    "number-is-nan": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
      "dev": true
    },
    "oauth-sign": {
      "version": "0.9.0",
      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
      "dev": true
    },
    "object-assign": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
      "dev": true
    },
    "object-copy": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
      "dev": true,
      "requires": {
        "copy-descriptor": "^0.1.0",
        "define-property": "^0.2.5",
        "kind-of": "^3.0.3"
      },
      "dependencies": {
        "define-property": {
          "version": "0.2.5",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^0.1.0"
          }
        },
        "is-accessor-descriptor": {
          "version": "0.1.6",
          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
          "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
          "dev": true,
          "requires": {
            "kind-of": "^3.0.2"
          }
        },
        "is-data-descriptor": {
          "version": "0.1.4",
          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
          "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
          "dev": true,
          "requires": {
            "kind-of": "^3.0.2"
          }
        },
        "is-descriptor": {
          "version": "0.1.6",
          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
          "dev": true,
          "requires": {
            "is-accessor-descriptor": "^0.1.6",
            "is-data-descriptor": "^0.1.4",
            "kind-of": "^5.0.0"
          },
          "dependencies": {
            "kind-of": {
              "version": "5.1.0",
              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
              "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
              "dev": true
            }
          }
        },
        "kind-of": {
          "version": "3.2.2",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
          "dev": true,
          "requires": {
            "is-buffer": "^1.1.5"
          }
        }
      }
    },
    "object-is": {
      "version": "1.1.5",
      "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
      "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
      "dev": true,
      "requires": {
        "call-bind": "^1.0.2",
        "define-properties": "^1.1.3"
      }
    },
    "object-keys": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
      "dev": true
    },
    "object-visit": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
      "dev": true,
      "requires": {
        "isobject": "^3.0.0"
      }
    },
    "object.assign": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
      "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
      "dev": true,
      "requires": {
        "call-bind": "^1.0.0",
        "define-properties": "^1.1.3",
        "has-symbols": "^1.0.1",
        "object-keys": "^1.1.1"
      }
    },
    "object.pick": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
      "dev": true,
      "requires": {
        "isobject": "^3.0.1"
      }
    },
    "obuf": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
      "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
      "dev": true
    },
    "on-finished": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
      "dev": true,
      "requires": {
        "ee-first": "1.1.1"
      }
    },
    "on-headers": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
      "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
      "dev": true
    },
    "once": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
      "dev": true,
      "requires": {
        "wrappy": "1"
      }
    },
    "onetime": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
      "dev": true,
      "requires": {
        "mimic-fn": "^2.1.0"
      }
    },
    "open": {
      "version": "8.2.1",
      "resolved": "https://registry.npmjs.org/open/-/open-8.2.1.tgz",
      "integrity": "sha512-rXILpcQlkF/QuFez2BJDf3GsqpjGKbkUUToAIGo9A0Q6ZkoSGogZJulrUdwRkrAsoQvoZsrjCYt8+zblOk7JQQ==",
      "dev": true,
      "requires": {
        "define-lazy-prop": "^2.0.0",
        "is-docker": "^2.1.1",
        "is-wsl": "^2.2.0"
      }
    },
    "opn": {
      "version": "5.5.0",
      "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
      "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==",
      "dev": true,
      "requires": {
        "is-wsl": "^1.1.0"
      },
      "dependencies": {
        "is-wsl": {
          "version": "1.1.0",
          "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
          "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
          "dev": true
        }
      }
    },
    "ora": {
      "version": "5.4.1",
      "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
      "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
      "dev": true,
      "requires": {
        "bl": "^4.1.0",
        "chalk": "^4.1.0",
        "cli-cursor": "^3.1.0",
        "cli-spinners": "^2.5.0",
        "is-interactive": "^1.0.0",
        "is-unicode-supported": "^0.1.0",
        "log-symbols": "^4.1.0",
        "strip-ansi": "^6.0.0",
        "wcwidth": "^1.0.1"
      },
      "dependencies": {
        "ansi-styles": {
          "version": "4.3.0",
          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
          "dev": true,
          "requires": {
            "color-convert": "^2.0.1"
          }
        },
        "chalk": {
          "version": "4.1.2",
          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
          "dev": true,
          "requires": {
            "ansi-styles": "^4.1.0",
            "supports-color": "^7.1.0"
          }
        },
        "color-convert": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
          "dev": true,
          "requires": {
            "color-name": "~1.1.4"
          }
        },
        "color-name": {
          "version": "1.1.4",
          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
          "dev": true
        },
        "has-flag": {
          "version": "4.0.0",
          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
          "dev": true
        },
        "supports-color": {
          "version": "7.2.0",
          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
          "dev": true,
          "requires": {
            "has-flag": "^4.0.0"
          }
        }
      }
    },
    "original": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
      "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
      "dev": true,
      "requires": {
        "url-parse": "^1.4.3"
      }
    },
    "os-tmpdir": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
      "dev": true
    },
    "p-defer": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
      "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
      "dev": true
    },
    "p-finally": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
      "dev": true
    },
    "p-limit": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
      "dev": true,
      "requires": {
        "yocto-queue": "^0.1.0"
      }
    },
    "p-locate": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
      "dev": true,
      "requires": {
        "p-limit": "^2.2.0"
      },
      "dependencies": {
        "p-limit": {
          "version": "2.3.0",
          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
          "dev": true,
          "requires": {
            "p-try": "^2.0.0"
          }
        }
      }
    },
    "p-map": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
      "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
      "dev": true,
      "requires": {
        "aggregate-error": "^3.0.0"
      }
    },
    "p-retry": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz",
      "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==",
      "dev": true,
      "requires": {
        "retry": "^0.12.0"
      }
    },
    "p-try": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
      "dev": true
    },
    "pacote": {
      "version": "11.3.4",
      "resolved": "https://registry.npmjs.org/pacote/-/pacote-11.3.4.tgz",
      "integrity": "sha512-RfahPCunM9GI7ryJV/zY0bWQiokZyLqaSNHXtbNSoLb7bwTvBbJBEyCJ01KWs4j1Gj7GmX8crYXQ1sNX6P2VKA==",
      "dev": true,
      "requires": {
        "@npmcli/git": "^2.0.1",
        "@npmcli/installed-package-contents": "^1.0.6",
        "@npmcli/promise-spawn": "^1.2.0",
        "@npmcli/run-script": "^1.8.2",
        "cacache": "^15.0.5",
        "chownr": "^2.0.0",
        "fs-minipass": "^2.1.0",
        "infer-owner": "^1.0.4",
        "minipass": "^3.1.3",
        "mkdirp": "^1.0.3",
        "npm-package-arg": "^8.0.1",
        "npm-packlist": "^2.1.4",
        "npm-pick-manifest": "^6.0.0",
        "npm-registry-fetch": "^11.0.0",
        "promise-retry": "^2.0.1",
        "read-package-json-fast": "^2.0.1",
        "rimraf": "^3.0.2",
        "ssri": "^8.0.1",
        "tar": "^6.1.0"
      }
    },
    "parent-module": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
      "dev": true,
      "requires": {
        "callsites": "^3.0.0"
      }
    },
    "parse-json": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
      "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
      "dev": true,
      "requires": {
        "@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-node-version": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
      "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
      "dev": true
    },
    "parse5": {
      "version": "5.1.1",
      "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
      "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
      "optional": true
    },
    "parse5-html-rewriting-stream": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-6.0.1.tgz",
      "integrity": "sha512-vwLQzynJVEfUlURxgnf51yAJDQTtVpNyGD8tKi2Za7m+akukNHxCcUQMAa/mUGLhCeicFdpy7Tlvj8ZNKadprg==",
      "dev": true,
      "requires": {
        "parse5": "^6.0.1",
        "parse5-sax-parser": "^6.0.1"
      },
      "dependencies": {
        "parse5": {
          "version": "6.0.1",
          "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
          "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
          "dev": true
        }
      }
    },
    "parse5-htmlparser2-tree-adapter": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
      "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
      "dev": true,
      "requires": {
        "parse5": "^6.0.1"
      },
      "dependencies": {
        "parse5": {
          "version": "6.0.1",
          "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
          "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
          "dev": true
        }
      }
    },
    "parse5-sax-parser": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-6.0.1.tgz",
      "integrity": "sha512-kXX+5S81lgESA0LsDuGjAlBybImAChYRMT+/uKCEXFBFOeEhS52qUCydGhU3qLRD8D9DVjaUo821WK7DM4iCeg==",
      "dev": true,
      "requires": {
        "parse5": "^6.0.1"
      },
      "dependencies": {
        "parse5": {
          "version": "6.0.1",
          "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
          "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
          "dev": true
        }
      }
    },
    "parseurl": {
      "version": "1.3.3",
      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
      "dev": true
    },
    "pascalcase": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
      "dev": true
    },
    "path-dirname": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
      "dev": true
    },
    "path-exists": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
      "dev": true
    },
    "path-is-absolute": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
      "dev": true
    },
    "path-is-inside": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
      "dev": true
    },
    "path-key": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
      "dev": true
    },
    "path-parse": {
      "version": "1.0.7",
      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
      "dev": true
    },
    "path-to-regexp": {
      "version": "0.1.7",
      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
      "dev": true
    },
    "path-type": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
      "dev": true
    },
    "performance-now": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
      "dev": true
    },
    "picocolors": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
      "dev": true
    },
    "picomatch": {
      "version": "2.3.1",
      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
      "dev": true
    },
    "pify": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
      "dev": true
    },
    "pinkie": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
      "dev": true
    },
    "pinkie-promise": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
      "dev": true,
      "requires": {
        "pinkie": "^2.0.0"
      }
    },
    "pkg-dir": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
      "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
      "dev": true,
      "requires": {
        "find-up": "^4.0.0"
      }
    },
    "portfinder": {
      "version": "1.0.28",
      "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
      "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==",
      "dev": true,
      "requires": {
        "async": "^2.6.2",
        "debug": "^3.1.1",
        "mkdirp": "^0.5.5"
      },
      "dependencies": {
        "debug": {
          "version": "3.2.7",
          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
          "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
          "dev": true,
          "requires": {
            "ms": "^2.1.1"
          }
        },
        "mkdirp": {
          "version": "0.5.5",
          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
          "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
          "dev": true,
          "requires": {
            "minimist": "^1.2.5"
          }
        }
      }
    },
    "posix-character-classes": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
      "dev": true
    },
    "postcss": {
      "version": "8.3.5",
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.5.tgz",
      "integrity": "sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA==",
      "dev": true,
      "requires": {
        "colorette": "^1.2.2",
        "nanoid": "^3.1.23",
        "source-map-js": "^0.6.2"
      }
    },
    "postcss-attribute-case-insensitive": {
      "version": "4.0.2",
      "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz",
      "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2",
        "postcss-selector-parser": "^6.0.2"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-calc": {
      "version": "8.2.2",
      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.2.tgz",
      "integrity": "sha512-B5R0UeB4zLJvxNt1FVCaDZULdzsKLPc6FhjFJ+xwFiq7VG4i9cuaJLxVjNtExNK8ocm3n2o4unXXLiVX1SCqxA==",
      "dev": true,
      "requires": {
        "postcss-selector-parser": "^6.0.2",
        "postcss-value-parser": "^4.0.2"
      }
    },
    "postcss-color-functional-notation": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz",
      "integrity": "sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2",
        "postcss-values-parser": "^2.0.0"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-color-gray": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz",
      "integrity": "sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==",
      "dev": true,
      "requires": {
        "@csstools/convert-colors": "^1.4.0",
        "postcss": "^7.0.5",
        "postcss-values-parser": "^2.0.0"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-color-hex-alpha": {
      "version": "5.0.3",
      "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz",
      "integrity": "sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.14",
        "postcss-values-parser": "^2.0.1"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-color-mod-function": {
      "version": "3.0.3",
      "resolved": "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz",
      "integrity": "sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==",
      "dev": true,
      "requires": {
        "@csstools/convert-colors": "^1.4.0",
        "postcss": "^7.0.2",
        "postcss-values-parser": "^2.0.0"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-color-rebeccapurple": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz",
      "integrity": "sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2",
        "postcss-values-parser": "^2.0.0"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-colormin": {
      "version": "5.2.3",
      "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.2.3.tgz",
      "integrity": "sha512-dra4xoAjub2wha6RUXAgadHEn2lGxbj8drhFcIGLOMn914Eu7DkPUurugDXgstwttCYkJtZ/+PkWRWdp3UHRIA==",
      "dev": true,
      "requires": {
        "browserslist": "^4.16.6",
        "caniuse-api": "^3.0.0",
        "colord": "^2.9.1",
        "postcss-value-parser": "^4.2.0"
      }
    },
    "postcss-convert-values": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.2.tgz",
      "integrity": "sha512-KQ04E2yadmfa1LqXm7UIDwW1ftxU/QWZmz6NKnHnUvJ3LEYbbcX6i329f/ig+WnEByHegulocXrECaZGLpL8Zg==",
      "dev": true,
      "requires": {
        "postcss-value-parser": "^4.1.0"
      }
    },
    "postcss-custom-media": {
      "version": "7.0.8",
      "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz",
      "integrity": "sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.14"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-custom-properties": {
      "version": "8.0.11",
      "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz",
      "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.17",
        "postcss-values-parser": "^2.0.1"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-custom-selectors": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz",
      "integrity": "sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2",
        "postcss-selector-parser": "^5.0.0-rc.3"
      },
      "dependencies": {
        "cssesc": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
          "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
          "dev": true
        },
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "postcss-selector-parser": {
          "version": "5.0.0",
          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
          "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
          "dev": true,
          "requires": {
            "cssesc": "^2.0.0",
            "indexes-of": "^1.0.1",
            "uniq": "^1.0.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-dir-pseudo-class": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz",
      "integrity": "sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2",
        "postcss-selector-parser": "^5.0.0-rc.3"
      },
      "dependencies": {
        "cssesc": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
          "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
          "dev": true
        },
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "postcss-selector-parser": {
          "version": "5.0.0",
          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
          "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
          "dev": true,
          "requires": {
            "cssesc": "^2.0.0",
            "indexes-of": "^1.0.1",
            "uniq": "^1.0.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-discard-comments": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz",
      "integrity": "sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg==",
      "dev": true,
      "requires": {}
    },
    "postcss-discard-duplicates": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz",
      "integrity": "sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA==",
      "dev": true,
      "requires": {}
    },
    "postcss-discard-empty": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz",
      "integrity": "sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw==",
      "dev": true,
      "requires": {}
    },
    "postcss-discard-overridden": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.2.tgz",
      "integrity": "sha512-+56BLP6NSSUuWUXjRgAQuho1p5xs/hU5Sw7+xt9S3JSg+7R6+WMGnJW7Hre/6tTuZ2xiXMB42ObkiZJ2hy/Pew==",
      "dev": true,
      "requires": {}
    },
    "postcss-double-position-gradients": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz",
      "integrity": "sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.5",
        "postcss-values-parser": "^2.0.0"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-env-function": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz",
      "integrity": "sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2",
        "postcss-values-parser": "^2.0.0"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-focus-visible": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz",
      "integrity": "sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-focus-within": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz",
      "integrity": "sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-font-variant": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz",
      "integrity": "sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-gap-properties": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz",
      "integrity": "sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-image-set-function": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz",
      "integrity": "sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2",
        "postcss-values-parser": "^2.0.0"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-import": {
      "version": "14.0.2",
      "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.0.2.tgz",
      "integrity": "sha512-BJ2pVK4KhUyMcqjuKs9RijV5tatNzNa73e/32aBVE/ejYPe37iH+6vAu9WvqUkB5OAYgLHzbSvzHnorybJCm9g==",
      "dev": true,
      "requires": {
        "postcss-value-parser": "^4.0.0",
        "read-cache": "^1.0.0",
        "resolve": "^1.1.7"
      }
    },
    "postcss-initial": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.4.tgz",
      "integrity": "sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-lab-function": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz",
      "integrity": "sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==",
      "dev": true,
      "requires": {
        "@csstools/convert-colors": "^1.4.0",
        "postcss": "^7.0.2",
        "postcss-values-parser": "^2.0.0"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-loader": {
      "version": "6.1.0",
      "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.1.0.tgz",
      "integrity": "sha512-yA/cXBfACkthZNA2hQxOnaReVfQ6uLmvbEDQzNafpbK40URZJvP/28dL1DG174Gvz3ptkkHbbwDBCh+gXR94CA==",
      "dev": true,
      "requires": {
        "cosmiconfig": "^7.0.0",
        "klona": "^2.0.4",
        "semver": "^7.3.5"
      }
    },
    "postcss-logical": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz",
      "integrity": "sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-media-minmax": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz",
      "integrity": "sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-merge-longhand": {
      "version": "5.0.4",
      "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.4.tgz",
      "integrity": "sha512-2lZrOVD+d81aoYkZDpWu6+3dTAAGkCKbV5DoRhnIR7KOULVrI/R7bcMjhrH9KTRy6iiHKqmtG+n/MMj1WmqHFw==",
      "dev": true,
      "requires": {
        "postcss-value-parser": "^4.1.0",
        "stylehacks": "^5.0.1"
      }
    },
    "postcss-merge-rules": {
      "version": "5.0.4",
      "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.4.tgz",
      "integrity": "sha512-yOj7bW3NxlQxaERBB0lEY1sH5y+RzevjbdH4DBJurjKERNpknRByFNdNe+V72i5pIZL12woM9uGdS5xbSB+kDQ==",
      "dev": true,
      "requires": {
        "browserslist": "^4.16.6",
        "caniuse-api": "^3.0.0",
        "cssnano-utils": "^3.0.0",
        "postcss-selector-parser": "^6.0.5"
      }
    },
    "postcss-minify-font-values": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.2.tgz",
      "integrity": "sha512-R6MJZryq28Cw0AmnyhXrM7naqJZZLoa1paBltIzh2wM7yb4D45TLur+eubTQ4jCmZU9SGeZdWsc5KcSoqTMeTg==",
      "dev": true,
      "requires": {
        "postcss-value-parser": "^4.2.0"
      }
    },
    "postcss-minify-gradients": {
      "version": "5.0.4",
      "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.4.tgz",
      "integrity": "sha512-RVwZA7NC4R4J76u8X0Q0j+J7ItKUWAeBUJ8oEEZWmtv3Xoh19uNJaJwzNpsydQjk6PkuhRrK+YwwMf+c+68EYg==",
      "dev": true,
      "requires": {
        "colord": "^2.9.1",
        "cssnano-utils": "^3.0.0",
        "postcss-value-parser": "^4.2.0"
      }
    },
    "postcss-minify-params": {
      "version": "5.0.3",
      "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.3.tgz",
      "integrity": "sha512-NY92FUikE+wralaiVexFd5gwb7oJTIDhgTNeIw89i1Ymsgt4RWiPXfz3bg7hDy4NL6gepcThJwOYNtZO/eNi7Q==",
      "dev": true,
      "requires": {
        "alphanum-sort": "^1.0.2",
        "browserslist": "^4.16.6",
        "cssnano-utils": "^3.0.0",
        "postcss-value-parser": "^4.2.0"
      }
    },
    "postcss-minify-selectors": {
      "version": "5.1.1",
      "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.1.1.tgz",
      "integrity": "sha512-TOzqOPXt91O2luJInaVPiivh90a2SIK5Nf1Ea7yEIM/5w+XA5BGrZGUSW8aEx9pJ/oNj7ZJBhjvigSiBV+bC1Q==",
      "dev": true,
      "requires": {
        "alphanum-sort": "^1.0.2",
        "postcss-selector-parser": "^6.0.5"
      }
    },
    "postcss-modules-extract-imports": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
      "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
      "dev": true,
      "requires": {}
    },
    "postcss-modules-local-by-default": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz",
      "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==",
      "dev": true,
      "requires": {
        "icss-utils": "^5.0.0",
        "postcss-selector-parser": "^6.0.2",
        "postcss-value-parser": "^4.1.0"
      }
    },
    "postcss-modules-scope": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz",
      "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==",
      "dev": true,
      "requires": {
        "postcss-selector-parser": "^6.0.4"
      }
    },
    "postcss-modules-values": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
      "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
      "dev": true,
      "requires": {
        "icss-utils": "^5.0.0"
      }
    },
    "postcss-nesting": {
      "version": "7.0.1",
      "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz",
      "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-normalize-charset": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz",
      "integrity": "sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg==",
      "dev": true,
      "requires": {}
    },
    "postcss-normalize-display-values": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.2.tgz",
      "integrity": "sha512-RxXoJPUR0shSjkMMzgEZDjGPrgXUVYyWA/YwQRicb48H15OClPuaDR7tYokLAlGZ2tCSENEN5WxjgxSD5m4cUw==",
      "dev": true,
      "requires": {
        "postcss-value-parser": "^4.2.0"
      }
    },
    "postcss-normalize-positions": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.2.tgz",
      "integrity": "sha512-tqghWFVDp2btqFg1gYob1etPNxXLNh3uVeWgZE2AQGh6b2F8AK2Gj36v5Vhyh+APwIzNjmt6jwZ9pTBP+/OM8g==",
      "dev": true,
      "requires": {
        "postcss-value-parser": "^4.2.0"
      }
    },
    "postcss-normalize-repeat-style": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.2.tgz",
      "integrity": "sha512-/rIZn8X9bBzC7KvY4iKUhXUGW3MmbXwfPF23jC9wT9xTi7kAvgj8sEgwxjixBmoL6MVa4WOgxNz2hAR6wTK8tw==",
      "dev": true,
      "requires": {
        "postcss-value-parser": "^4.2.0"
      }
    },
    "postcss-normalize-string": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.2.tgz",
      "integrity": "sha512-zaI1yzwL+a/FkIzUWMQoH25YwCYxi917J4pYm1nRXtdgiCdnlTkx5eRzqWEC64HtRa06WCJ9TIutpb6GmW4gFw==",
      "dev": true,
      "requires": {
        "postcss-value-parser": "^4.2.0"
      }
    },
    "postcss-normalize-timing-functions": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.2.tgz",
      "integrity": "sha512-Ao0PP6MoYsRU1LxeVUW740ioknvdIUmfr6uAA3xWlQJ9s69/Tupy8qwhuKG3xWfl+KvLMAP9p2WXF9cwuk/7Bg==",
      "dev": true,
      "requires": {
        "postcss-value-parser": "^4.2.0"
      }
    },
    "postcss-normalize-unicode": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.2.tgz",
      "integrity": "sha512-3y/V+vjZ19HNcTizeqwrbZSUsE69ZMRHfiiyLAJb7C7hJtYmM4Gsbajy7gKagu97E8q5rlS9k8FhojA8cpGhWw==",
      "dev": true,
      "requires": {
        "browserslist": "^4.16.6",
        "postcss-value-parser": "^4.2.0"
      }
    },
    "postcss-normalize-url": {
      "version": "5.0.4",
      "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.4.tgz",
      "integrity": "sha512-cNj3RzK2pgQQyNp7dzq0dqpUpQ/wYtdDZM3DepPmFjCmYIfceuD9VIAcOdvrNetjIU65g1B4uwdP/Krf6AFdXg==",
      "dev": true,
      "requires": {
        "normalize-url": "^6.0.1",
        "postcss-value-parser": "^4.2.0"
      }
    },
    "postcss-normalize-whitespace": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.2.tgz",
      "integrity": "sha512-CXBx+9fVlzSgbk0IXA/dcZn9lXixnQRndnsPC5ht3HxlQ1bVh77KQDL1GffJx1LTzzfae8ftMulsjYmO2yegxA==",
      "dev": true,
      "requires": {
        "postcss-value-parser": "^4.2.0"
      }
    },
    "postcss-ordered-values": {
      "version": "5.0.3",
      "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.3.tgz",
      "integrity": "sha512-T9pDS+P9bWeFvqivXd5ACzQmrCmHjv3ZP+djn8E1UZY7iK79pFSm7i3WbKw2VSmFmdbMm8sQ12OPcNpzBo3Z2w==",
      "dev": true,
      "requires": {
        "cssnano-utils": "^3.0.0",
        "postcss-value-parser": "^4.2.0"
      }
    },
    "postcss-overflow-shorthand": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz",
      "integrity": "sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-page-break": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz",
      "integrity": "sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-place": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz",
      "integrity": "sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2",
        "postcss-values-parser": "^2.0.0"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-preset-env": {
      "version": "6.7.0",
      "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz",
      "integrity": "sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==",
      "dev": true,
      "requires": {
        "autoprefixer": "^9.6.1",
        "browserslist": "^4.6.4",
        "caniuse-lite": "^1.0.30000981",
        "css-blank-pseudo": "^0.1.4",
        "css-has-pseudo": "^0.10.0",
        "css-prefers-color-scheme": "^3.1.1",
        "cssdb": "^4.4.0",
        "postcss": "^7.0.17",
        "postcss-attribute-case-insensitive": "^4.0.1",
        "postcss-color-functional-notation": "^2.0.1",
        "postcss-color-gray": "^5.0.0",
        "postcss-color-hex-alpha": "^5.0.3",
        "postcss-color-mod-function": "^3.0.3",
        "postcss-color-rebeccapurple": "^4.0.1",
        "postcss-custom-media": "^7.0.8",
        "postcss-custom-properties": "^8.0.11",
        "postcss-custom-selectors": "^5.1.2",
        "postcss-dir-pseudo-class": "^5.0.0",
        "postcss-double-position-gradients": "^1.0.0",
        "postcss-env-function": "^2.0.2",
        "postcss-focus-visible": "^4.0.0",
        "postcss-focus-within": "^3.0.0",
        "postcss-font-variant": "^4.0.0",
        "postcss-gap-properties": "^2.0.0",
        "postcss-image-set-function": "^3.0.1",
        "postcss-initial": "^3.0.0",
        "postcss-lab-function": "^2.0.1",
        "postcss-logical": "^3.0.0",
        "postcss-media-minmax": "^4.0.0",
        "postcss-nesting": "^7.0.0",
        "postcss-overflow-shorthand": "^2.0.0",
        "postcss-page-break": "^2.0.0",
        "postcss-place": "^4.0.1",
        "postcss-pseudo-class-any-link": "^6.0.0",
        "postcss-replace-overflow-wrap": "^3.0.0",
        "postcss-selector-matches": "^4.0.0",
        "postcss-selector-not": "^4.0.0"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-pseudo-class-any-link": {
      "version": "6.0.0",
      "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz",
      "integrity": "sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2",
        "postcss-selector-parser": "^5.0.0-rc.3"
      },
      "dependencies": {
        "cssesc": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
          "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
          "dev": true
        },
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "postcss-selector-parser": {
          "version": "5.0.0",
          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
          "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
          "dev": true,
          "requires": {
            "cssesc": "^2.0.0",
            "indexes-of": "^1.0.1",
            "uniq": "^1.0.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-reduce-initial": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.2.tgz",
      "integrity": "sha512-v/kbAAQ+S1V5v9TJvbGkV98V2ERPdU6XvMcKMjqAlYiJ2NtsHGlKYLPjWWcXlaTKNxooId7BGxeraK8qXvzKtw==",
      "dev": true,
      "requires": {
        "browserslist": "^4.16.6",
        "caniuse-api": "^3.0.0"
      }
    },
    "postcss-reduce-transforms": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.2.tgz",
      "integrity": "sha512-25HeDeFsgiPSUx69jJXZn8I06tMxLQJJNF5h7i9gsUg8iP4KOOJ8EX8fj3seeoLt3SLU2YDD6UPnDYVGUO7DEA==",
      "dev": true,
      "requires": {
        "postcss-value-parser": "^4.2.0"
      }
    },
    "postcss-replace-overflow-wrap": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz",
      "integrity": "sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==",
      "dev": true,
      "requires": {
        "postcss": "^7.0.2"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-selector-matches": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz",
      "integrity": "sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==",
      "dev": true,
      "requires": {
        "balanced-match": "^1.0.0",
        "postcss": "^7.0.2"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-selector-not": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz",
      "integrity": "sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ==",
      "dev": true,
      "requires": {
        "balanced-match": "^1.0.0",
        "postcss": "^7.0.2"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "postcss-selector-parser": {
      "version": "6.0.8",
      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz",
      "integrity": "sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ==",
      "dev": true,
      "requires": {
        "cssesc": "^3.0.0",
        "util-deprecate": "^1.0.2"
      }
    },
    "postcss-svgo": {
      "version": "5.0.3",
      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.3.tgz",
      "integrity": "sha512-41XZUA1wNDAZrQ3XgWREL/M2zSw8LJPvb5ZWivljBsUQAGoEKMYm6okHsTjJxKYI4M75RQEH4KYlEM52VwdXVA==",
      "dev": true,
      "requires": {
        "postcss-value-parser": "^4.1.0",
        "svgo": "^2.7.0"
      }
    },
    "postcss-unique-selectors": {
      "version": "5.0.2",
      "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.2.tgz",
      "integrity": "sha512-w3zBVlrtZm7loQWRPVC0yjUwwpty7OM6DnEHkxcSQXO1bMS3RJ+JUS5LFMSDZHJcvGsRwhZinCWVqn8Kej4EDA==",
      "dev": true,
      "requires": {
        "alphanum-sort": "^1.0.2",
        "postcss-selector-parser": "^6.0.5"
      }
    },
    "postcss-value-parser": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
      "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
      "dev": true
    },
    "postcss-values-parser": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz",
      "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==",
      "dev": true,
      "requires": {
        "flatten": "^1.0.2",
        "indexes-of": "^1.0.1",
        "uniq": "^1.0.1"
      }
    },
    "pretty-bytes": {
      "version": "5.6.0",
      "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
      "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
      "dev": true
    },
    "process-nextick-args": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
      "dev": true
    },
    "promise-inflight": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
      "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
      "dev": true
    },
    "promise-retry": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
      "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
      "dev": true,
      "requires": {
        "err-code": "^2.0.2",
        "retry": "^0.12.0"
      }
    },
    "proxy-addr": {
      "version": "2.0.7",
      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
      "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
      "dev": true,
      "requires": {
        "forwarded": "0.2.0",
        "ipaddr.js": "1.9.1"
      }
    },
    "prr": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
      "dev": true
    },
    "psl": {
      "version": "1.8.0",
      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
      "dev": true
    },
    "pump": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
      "dev": true,
      "requires": {
        "end-of-stream": "^1.1.0",
        "once": "^1.3.1"
      }
    },
    "punycode": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
      "dev": true
    },
    "qjobs": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
      "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
      "dev": true
    },
    "qs": {
      "version": "6.9.6",
      "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz",
      "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==",
      "dev": true
    },
    "querystring": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
      "dev": true
    },
    "querystringify": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
      "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
      "dev": true
    },
    "queue-microtask": {
      "version": "1.2.3",
      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
      "dev": true
    },
    "randombytes": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
      "dev": true,
      "requires": {
        "safe-buffer": "^5.1.0"
      }
    },
    "range-parser": {
      "version": "1.2.1",
      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
      "dev": true
    },
    "raw-body": {
      "version": "2.4.2",
      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz",
      "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==",
      "dev": true,
      "requires": {
        "bytes": "3.1.1",
        "http-errors": "1.8.1",
        "iconv-lite": "0.4.24",
        "unpipe": "1.0.0"
      }
    },
    "raw-loader": {
      "version": "4.0.2",
      "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz",
      "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==",
      "dev": true,
      "requires": {
        "loader-utils": "^2.0.0",
        "schema-utils": "^3.0.0"
      },
      "dependencies": {
        "ajv": {
          "version": "6.12.6",
          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
          "dev": true,
          "requires": {
            "fast-deep-equal": "^3.1.1",
            "fast-json-stable-stringify": "^2.0.0",
            "json-schema-traverse": "^0.4.1",
            "uri-js": "^4.2.2"
          }
        },
        "ajv-keywords": {
          "version": "3.5.2",
          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
          "dev": true,
          "requires": {}
        },
        "json-schema-traverse": {
          "version": "0.4.1",
          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
          "dev": true
        },
        "schema-utils": {
          "version": "3.1.1",
          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
          "dev": true,
          "requires": {
            "@types/json-schema": "^7.0.8",
            "ajv": "^6.12.5",
            "ajv-keywords": "^3.5.2"
          }
        }
      }
    },
    "read-cache": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
      "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
      "dev": true,
      "requires": {
        "pify": "^2.3.0"
      }
    },
    "read-package-json-fast": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz",
      "integrity": "sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ==",
      "dev": true,
      "requires": {
        "json-parse-even-better-errors": "^2.3.0",
        "npm-normalize-package-bin": "^1.0.1"
      }
    },
    "readable-stream": {
      "version": "3.6.0",
      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
      "dev": true,
      "requires": {
        "inherits": "^2.0.3",
        "string_decoder": "^1.1.1",
        "util-deprecate": "^1.0.1"
      }
    },
    "readdirp": {
      "version": "3.6.0",
      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
      "dev": true,
      "requires": {
        "picomatch": "^2.2.1"
      }
    },
    "reflect-metadata": {
      "version": "0.1.13",
      "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
      "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==",
      "dev": true
    },
    "regenerate": {
      "version": "1.4.2",
      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
      "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
      "dev": true
    },
    "regenerate-unicode-properties": {
      "version": "9.0.0",
      "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz",
      "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==",
      "dev": true,
      "requires": {
        "regenerate": "^1.4.2"
      }
    },
    "regenerator-runtime": {
      "version": "0.13.7",
      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
      "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
      "dev": true
    },
    "regenerator-transform": {
      "version": "0.14.5",
      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz",
      "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==",
      "dev": true,
      "requires": {
        "@babel/runtime": "^7.8.4"
      }
    },
    "regex-not": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
      "dev": true,
      "requires": {
        "extend-shallow": "^3.0.2",
        "safe-regex": "^1.1.0"
      }
    },
    "regex-parser": {
      "version": "2.2.11",
      "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz",
      "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==",
      "dev": true
    },
    "regexp.prototype.flags": {
      "version": "1.4.1",
      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz",
      "integrity": "sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ==",
      "dev": true,
      "requires": {
        "call-bind": "^1.0.2",
        "define-properties": "^1.1.3"
      }
    },
    "regexpu-core": {
      "version": "4.8.0",
      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz",
      "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==",
      "dev": true,
      "requires": {
        "regenerate": "^1.4.2",
        "regenerate-unicode-properties": "^9.0.0",
        "regjsgen": "^0.5.2",
        "regjsparser": "^0.7.0",
        "unicode-match-property-ecmascript": "^2.0.0",
        "unicode-match-property-value-ecmascript": "^2.0.0"
      }
    },
    "regjsgen": {
      "version": "0.5.2",
      "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
      "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==",
      "dev": true
    },
    "regjsparser": {
      "version": "0.7.0",
      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz",
      "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==",
      "dev": true,
      "requires": {
        "jsesc": "~0.5.0"
      },
      "dependencies": {
        "jsesc": {
          "version": "0.5.0",
          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
          "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
          "dev": true
        }
      }
    },
    "remove-trailing-separator": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
      "dev": true
    },
    "repeat-element": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz",
      "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==",
      "dev": true
    },
    "repeat-string": {
      "version": "1.6.1",
      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
      "dev": true
    },
    "request": {
      "version": "2.88.2",
      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
      "dev": true,
      "requires": {
        "aws-sign2": "~0.7.0",
        "aws4": "^1.8.0",
        "caseless": "~0.12.0",
        "combined-stream": "~1.0.6",
        "extend": "~3.0.2",
        "forever-agent": "~0.6.1",
        "form-data": "~2.3.2",
        "har-validator": "~5.1.3",
        "http-signature": "~1.2.0",
        "is-typedarray": "~1.0.0",
        "isstream": "~0.1.2",
        "json-stringify-safe": "~5.0.1",
        "mime-types": "~2.1.19",
        "oauth-sign": "~0.9.0",
        "performance-now": "^2.1.0",
        "qs": "~6.5.2",
        "safe-buffer": "^5.1.2",
        "tough-cookie": "~2.5.0",
        "tunnel-agent": "^0.6.0",
        "uuid": "^3.3.2"
      },
      "dependencies": {
        "qs": {
          "version": "6.5.3",
          "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
          "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
          "dev": true
        },
        "uuid": {
          "version": "3.4.0",
          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
          "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
          "dev": true
        }
      }
    },
    "require-directory": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
      "dev": true
    },
    "require-from-string": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
      "dev": true
    },
    "require-main-filename": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
      "dev": true
    },
    "requires-port": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
      "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
      "dev": true
    },
    "resolve": {
      "version": "1.20.0",
      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
      "dev": true,
      "requires": {
        "is-core-module": "^2.2.0",
        "path-parse": "^1.0.6"
      }
    },
    "resolve-cwd": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
      "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
      "dev": true,
      "requires": {
        "resolve-from": "^3.0.0"
      },
      "dependencies": {
        "resolve-from": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
          "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
          "dev": true
        }
      }
    },
    "resolve-from": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
      "dev": true
    },
    "resolve-url": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
      "dev": true
    },
    "resolve-url-loader": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz",
      "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==",
      "dev": true,
      "requires": {
        "adjust-sourcemap-loader": "^4.0.0",
        "convert-source-map": "^1.7.0",
        "loader-utils": "^2.0.0",
        "postcss": "^7.0.35",
        "source-map": "0.6.1"
      },
      "dependencies": {
        "picocolors": {
          "version": "0.2.1",
          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
          "dev": true
        },
        "postcss": {
          "version": "7.0.39",
          "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
          "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
          "dev": true,
          "requires": {
            "picocolors": "^0.2.1",
            "source-map": "^0.6.1"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "restore-cursor": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
      "dev": true,
      "requires": {
        "onetime": "^5.1.0",
        "signal-exit": "^3.0.2"
      }
    },
    "ret": {
      "version": "0.1.15",
      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
      "dev": true
    },
    "retry": {
      "version": "0.12.0",
      "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
      "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
      "dev": true
    },
    "reusify": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
      "dev": true
    },
    "rfdc": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
      "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
      "dev": true
    },
    "rimraf": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
      "dev": true,
      "requires": {
        "glob": "^7.1.3"
      }
    },
    "run-async": {
      "version": "2.4.1",
      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
      "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
      "dev": true
    },
    "run-parallel": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
      "dev": true,
      "requires": {
        "queue-microtask": "^1.2.2"
      }
    },
    "rxjs": {
      "version": "6.6.7",
      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
      "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
      "requires": {
        "tslib": "^1.9.0"
      },
      "dependencies": {
        "tslib": {
          "version": "1.14.1",
          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
        }
      }
    },
    "safe-buffer": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
      "dev": true
    },
    "safe-regex": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
      "dev": true,
      "requires": {
        "ret": "~0.1.10"
      }
    },
    "safer-buffer": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
      "dev": true
    },
    "sass": {
      "version": "1.35.1",
      "resolved": "https://registry.npmjs.org/sass/-/sass-1.35.1.tgz",
      "integrity": "sha512-oCisuQJstxMcacOPmxLNiLlj4cUyN2+8xJnG7VanRoh2GOLr9RqkvI4AxA4a6LHVg/rsu+PmxXeGhrdSF9jCiQ==",
      "dev": true,
      "requires": {
        "chokidar": ">=3.0.0 <4.0.0"
      }
    },
    "sass-loader": {
      "version": "12.1.0",
      "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.1.0.tgz",
      "integrity": "sha512-FVJZ9kxVRYNZTIe2xhw93n3xJNYZADr+q69/s98l9nTCrWASo+DR2Ot0s5xTKQDDEosUkatsGeHxcH4QBp5bSg==",
      "dev": true,
      "requires": {
        "klona": "^2.0.4",
        "neo-async": "^2.6.2"
      }
    },
    "sax": {
      "version": "1.2.4",
      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
      "dev": true
    },
    "schema-utils": {
      "version": "2.7.1",
      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
      "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
      "dev": true,
      "requires": {
        "@types/json-schema": "^7.0.5",
        "ajv": "^6.12.4",
        "ajv-keywords": "^3.5.2"
      },
      "dependencies": {
        "ajv": {
          "version": "6.12.6",
          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
          "dev": true,
          "requires": {
            "fast-deep-equal": "^3.1.1",
            "fast-json-stable-stringify": "^2.0.0",
            "json-schema-traverse": "^0.4.1",
            "uri-js": "^4.2.2"
          }
        },
        "ajv-keywords": {
          "version": "3.5.2",
          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
          "dev": true,
          "requires": {}
        },
        "json-schema-traverse": {
          "version": "0.4.1",
          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
          "dev": true
        }
      }
    },
    "select-hose": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
      "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=",
      "dev": true
    },
    "selfsigned": {
      "version": "1.10.14",
      "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.14.tgz",
      "integrity": "sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA==",
      "dev": true,
      "requires": {
        "node-forge": "^0.10.0"
      }
    },
    "semver": {
      "version": "7.3.5",
      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
      "dev": true,
      "requires": {
        "lru-cache": "^6.0.0"
      }
    },
    "send": {
      "version": "0.17.2",
      "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz",
      "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==",
      "dev": true,
      "requires": {
        "debug": "2.6.9",
        "depd": "~1.1.2",
        "destroy": "~1.0.4",
        "encodeurl": "~1.0.2",
        "escape-html": "~1.0.3",
        "etag": "~1.8.1",
        "fresh": "0.5.2",
        "http-errors": "1.8.1",
        "mime": "1.6.0",
        "ms": "2.1.3",
        "on-finished": "~2.3.0",
        "range-parser": "~1.2.1",
        "statuses": "~1.5.0"
      },
      "dependencies": {
        "debug": {
          "version": "2.6.9",
          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          },
          "dependencies": {
            "ms": {
              "version": "2.0.0",
              "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
              "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
              "dev": true
            }
          }
        },
        "mime": {
          "version": "1.6.0",
          "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
          "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
          "dev": true
        },
        "ms": {
          "version": "2.1.3",
          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
          "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
          "dev": true
        }
      }
    },
    "serialize-javascript": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
      "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
      "dev": true,
      "requires": {
        "randombytes": "^2.1.0"
      }
    },
    "serve-index": {
      "version": "1.9.1",
      "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
      "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
      "dev": true,
      "requires": {
        "accepts": "~1.3.4",
        "batch": "0.6.1",
        "debug": "2.6.9",
        "escape-html": "~1.0.3",
        "http-errors": "~1.6.2",
        "mime-types": "~2.1.17",
        "parseurl": "~1.3.2"
      },
      "dependencies": {
        "debug": {
          "version": "2.6.9",
          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          }
        },
        "http-errors": {
          "version": "1.6.3",
          "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
          "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
          "dev": true,
          "requires": {
            "depd": "~1.1.2",
            "inherits": "2.0.3",
            "setprototypeof": "1.1.0",
            "statuses": ">= 1.4.0 < 2"
          }
        },
        "inherits": {
          "version": "2.0.3",
          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
          "dev": true
        },
        "ms": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
          "dev": true
        },
        "setprototypeof": {
          "version": "1.1.0",
          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
          "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
          "dev": true
        }
      }
    },
    "serve-static": {
      "version": "1.14.2",
      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz",
      "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==",
      "dev": true,
      "requires": {
        "encodeurl": "~1.0.2",
        "escape-html": "~1.0.3",
        "parseurl": "~1.3.3",
        "send": "0.17.2"
      }
    },
    "set-blocking": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
      "dev": true
    },
    "set-value": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
      "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
      "dev": true,
      "requires": {
        "extend-shallow": "^2.0.1",
        "is-extendable": "^0.1.1",
        "is-plain-object": "^2.0.3",
        "split-string": "^3.0.1"
      },
      "dependencies": {
        "extend-shallow": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
          "dev": true,
          "requires": {
            "is-extendable": "^0.1.0"
          }
        },
        "is-extendable": {
          "version": "0.1.1",
          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
          "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
          "dev": true
        }
      }
    },
    "setprototypeof": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
      "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
      "dev": true
    },
    "shallow-clone": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
      "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
      "dev": true,
      "requires": {
        "kind-of": "^6.0.2"
      }
    },
    "shebang-command": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
      "dev": true,
      "requires": {
        "shebang-regex": "^1.0.0"
      }
    },
    "shebang-regex": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
      "dev": true
    },
    "signal-exit": {
      "version": "3.0.6",
      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz",
      "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==",
      "dev": true
    },
    "simplebar": {
      "version": "5.3.6",
      "resolved": "https://registry.npmjs.org/simplebar/-/simplebar-5.3.6.tgz",
      "integrity": "sha512-FJUMbV+hNDd/m+1/fvD41TXKd5mSdlI5zgBygkaQIV3SffNbcLhSbJT6ufTs8ZNRLJ6i+qc/KCFMqWmvlGWMhA==",
      "requires": {
        "@juggle/resize-observer": "^3.3.1",
        "can-use-dom": "^0.1.0",
        "core-js": "^3.0.1",
        "lodash.debounce": "^4.0.8",
        "lodash.memoize": "^4.1.2",
        "lodash.throttle": "^4.1.1"
      }
    },
    "simplebar-angular": {
      "version": "2.3.6",
      "resolved": "https://registry.npmjs.org/simplebar-angular/-/simplebar-angular-2.3.6.tgz",
      "integrity": "sha512-chSUdCYCLOdajbCA73oL/OU+H/YFNGGdAYkcYx76YDY81C3sj3vMePjuW8cPgZZHwSCGI+opcl6xoBsCK56fJA==",
      "requires": {
        "simplebar": "^5.3.6",
        "tslib": "^1.9.0"
      },
      "dependencies": {
        "tslib": {
          "version": "1.14.1",
          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
        }
      }
    },
    "slash": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
      "dev": true
    },
    "smart-buffer": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
      "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
      "dev": true
    },
    "snapdragon": {
      "version": "0.8.2",
      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
      "dev": true,
      "requires": {
        "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"
      },
      "dependencies": {
        "debug": {
          "version": "2.6.9",
          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          }
        },
        "define-property": {
          "version": "0.2.5",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^0.1.0"
          }
        },
        "extend-shallow": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
          "dev": true,
          "requires": {
            "is-extendable": "^0.1.0"
          }
        },
        "is-accessor-descriptor": {
          "version": "0.1.6",
          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
          "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
          "dev": true,
          "requires": {
            "kind-of": "^3.0.2"
          },
          "dependencies": {
            "kind-of": {
              "version": "3.2.2",
              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
              "dev": true,
              "requires": {
                "is-buffer": "^1.1.5"
              }
            }
          }
        },
        "is-data-descriptor": {
          "version": "0.1.4",
          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
          "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
          "dev": true,
          "requires": {
            "kind-of": "^3.0.2"
          },
          "dependencies": {
            "kind-of": {
              "version": "3.2.2",
              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
              "dev": true,
              "requires": {
                "is-buffer": "^1.1.5"
              }
            }
          }
        },
        "is-descriptor": {
          "version": "0.1.6",
          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
          "dev": true,
          "requires": {
            "is-accessor-descriptor": "^0.1.6",
            "is-data-descriptor": "^0.1.4",
            "kind-of": "^5.0.0"
          }
        },
        "is-extendable": {
          "version": "0.1.1",
          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
          "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
          "dev": true
        },
        "kind-of": {
          "version": "5.1.0",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
          "dev": true
        },
        "ms": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
          "dev": true
        },
        "source-map": {
          "version": "0.5.7",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
          "dev": true
        },
        "source-map-resolve": {
          "version": "0.5.3",
          "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
          "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
          "dev": true,
          "requires": {
            "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"
          }
        }
      }
    },
    "snapdragon-node": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
      "dev": true,
      "requires": {
        "define-property": "^1.0.0",
        "isobject": "^3.0.0",
        "snapdragon-util": "^3.0.1"
      },
      "dependencies": {
        "define-property": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^1.0.0"
          }
        }
      }
    },
    "snapdragon-util": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
      "dev": true,
      "requires": {
        "kind-of": "^3.2.0"
      },
      "dependencies": {
        "kind-of": {
          "version": "3.2.2",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
          "dev": true,
          "requires": {
            "is-buffer": "^1.1.5"
          }
        }
      }
    },
    "socket.io": {
      "version": "4.4.1",
      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.4.1.tgz",
      "integrity": "sha512-s04vrBswdQBUmuWJuuNTmXUVJhP0cVky8bBDhdkf8y0Ptsu7fKU2LuLbts9g+pdmAdyMMn8F/9Mf1/wbtUN0fg==",
      "dev": true,
      "requires": {
        "accepts": "~1.3.4",
        "base64id": "~2.0.0",
        "debug": "~4.3.2",
        "engine.io": "~6.1.0",
        "socket.io-adapter": "~2.3.3",
        "socket.io-parser": "~4.0.4"
      },
      "dependencies": {
        "debug": {
          "version": "4.3.3",
          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
          "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
          "dev": true,
          "requires": {
            "ms": "2.1.2"
          }
        }
      }
    },
    "socket.io-adapter": {
      "version": "2.3.3",
      "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz",
      "integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==",
      "dev": true
    },
    "socket.io-parser": {
      "version": "4.0.4",
      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
      "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
      "dev": true,
      "requires": {
        "@types/component-emitter": "^1.2.10",
        "component-emitter": "~1.3.0",
        "debug": "~4.3.1"
      }
    },
    "sockjs": {
      "version": "0.3.24",
      "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
      "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==",
      "dev": true,
      "requires": {
        "faye-websocket": "^0.11.3",
        "uuid": "^8.3.2",
        "websocket-driver": "^0.7.4"
      }
    },
    "sockjs-client": {
      "version": "1.5.2",
      "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.2.tgz",
      "integrity": "sha512-ZzRxPBISQE7RpzlH4tKJMQbHM9pabHluk0WBaxAQ+wm/UieeBVBou0p4wVnSQGN9QmpAZygQ0cDIypWuqOFmFQ==",
      "dev": true,
      "requires": {
        "debug": "^3.2.6",
        "eventsource": "^1.0.7",
        "faye-websocket": "^0.11.3",
        "inherits": "^2.0.4",
        "json3": "^3.3.3",
        "url-parse": "^1.5.3"
      },
      "dependencies": {
        "debug": {
          "version": "3.2.7",
          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
          "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
          "dev": true,
          "requires": {
            "ms": "^2.1.1"
          }
        }
      }
    },
    "socks": {
      "version": "2.6.1",
      "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz",
      "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==",
      "dev": true,
      "requires": {
        "ip": "^1.1.5",
        "smart-buffer": "^4.1.0"
      }
    },
    "socks-proxy-agent": {
      "version": "6.1.1",
      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz",
      "integrity": "sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==",
      "dev": true,
      "requires": {
        "agent-base": "^6.0.2",
        "debug": "^4.3.1",
        "socks": "^2.6.1"
      }
    },
    "source-list-map": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
      "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
      "dev": true
    },
    "source-map": {
      "version": "0.7.3",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
      "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
      "dev": true
    },
    "source-map-js": {
      "version": "0.6.2",
      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz",
      "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==",
      "dev": true
    },
    "source-map-loader": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.0.tgz",
      "integrity": "sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw==",
      "dev": true,
      "requires": {
        "abab": "^2.0.5",
        "iconv-lite": "^0.6.2",
        "source-map-js": "^0.6.2"
      },
      "dependencies": {
        "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==",
          "dev": true,
          "requires": {
            "safer-buffer": ">= 2.1.2 < 3.0.0"
          }
        }
      }
    },
    "source-map-resolve": {
      "version": "0.6.0",
      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz",
      "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==",
      "dev": true,
      "requires": {
        "atob": "^2.1.2",
        "decode-uri-component": "^0.2.0"
      }
    },
    "source-map-support": {
      "version": "0.5.19",
      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
      "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
      "dev": true,
      "requires": {
        "buffer-from": "^1.0.0",
        "source-map": "^0.6.0"
      },
      "dependencies": {
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "source-map-url": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
      "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
      "dev": true
    },
    "sourcemap-codec": {
      "version": "1.4.8",
      "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
      "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
      "dev": true
    },
    "spdy": {
      "version": "4.0.2",
      "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
      "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==",
      "dev": true,
      "requires": {
        "debug": "^4.1.0",
        "handle-thing": "^2.0.0",
        "http-deceiver": "^1.2.7",
        "select-hose": "^2.0.0",
        "spdy-transport": "^3.0.0"
      }
    },
    "spdy-transport": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz",
      "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
      "dev": true,
      "requires": {
        "debug": "^4.1.0",
        "detect-node": "^2.0.4",
        "hpack.js": "^2.1.6",
        "obuf": "^1.1.2",
        "readable-stream": "^3.0.6",
        "wbuf": "^1.7.3"
      }
    },
    "split-string": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
      "dev": true,
      "requires": {
        "extend-shallow": "^3.0.0"
      }
    },
    "sshpk": {
      "version": "1.17.0",
      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
      "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
      "dev": true,
      "requires": {
        "asn1": "~0.2.3",
        "assert-plus": "^1.0.0",
        "bcrypt-pbkdf": "^1.0.0",
        "dashdash": "^1.12.0",
        "ecc-jsbn": "~0.1.1",
        "getpass": "^0.1.1",
        "jsbn": "~0.1.0",
        "safer-buffer": "^2.0.2",
        "tweetnacl": "~0.14.0"
      }
    },
    "ssri": {
      "version": "8.0.1",
      "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
      "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
      "dev": true,
      "requires": {
        "minipass": "^3.1.1"
      }
    },
    "stable": {
      "version": "0.1.8",
      "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
      "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
      "dev": true
    },
    "static-extend": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
      "dev": true,
      "requires": {
        "define-property": "^0.2.5",
        "object-copy": "^0.1.0"
      },
      "dependencies": {
        "define-property": {
          "version": "0.2.5",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^0.1.0"
          }
        },
        "is-accessor-descriptor": {
          "version": "0.1.6",
          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
          "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
          "dev": true,
          "requires": {
            "kind-of": "^3.0.2"
          },
          "dependencies": {
            "kind-of": {
              "version": "3.2.2",
              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
              "dev": true,
              "requires": {
                "is-buffer": "^1.1.5"
              }
            }
          }
        },
        "is-data-descriptor": {
          "version": "0.1.4",
          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
          "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
          "dev": true,
          "requires": {
            "kind-of": "^3.0.2"
          },
          "dependencies": {
            "kind-of": {
              "version": "3.2.2",
              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
              "dev": true,
              "requires": {
                "is-buffer": "^1.1.5"
              }
            }
          }
        },
        "is-descriptor": {
          "version": "0.1.6",
          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
          "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
          "dev": true,
          "requires": {
            "is-accessor-descriptor": "^0.1.6",
            "is-data-descriptor": "^0.1.4",
            "kind-of": "^5.0.0"
          }
        },
        "kind-of": {
          "version": "5.1.0",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
          "dev": true
        }
      }
    },
    "statuses": {
      "version": "1.5.0",
      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
      "dev": true
    },
    "streamroller": {
      "version": "2.2.4",
      "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz",
      "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==",
      "dev": true,
      "requires": {
        "date-format": "^2.1.0",
        "debug": "^4.1.1",
        "fs-extra": "^8.1.0"
      },
      "dependencies": {
        "date-format": {
          "version": "2.1.0",
          "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz",
          "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==",
          "dev": true
        }
      }
    },
    "string_decoder": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
      "dev": true,
      "requires": {
        "safe-buffer": "~5.2.0"
      },
      "dependencies": {
        "safe-buffer": {
          "version": "5.2.1",
          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
          "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
          "dev": true
        }
      }
    },
    "string-width": {
      "version": "4.2.3",
      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
      "dev": true,
      "requires": {
        "emoji-regex": "^8.0.0",
        "is-fullwidth-code-point": "^3.0.0",
        "strip-ansi": "^6.0.1"
      }
    },
    "strip-ansi": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
      "dev": true,
      "requires": {
        "ansi-regex": "^5.0.1"
      }
    },
    "strip-eof": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
      "dev": true
    },
    "style-loader": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz",
      "integrity": "sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==",
      "dev": true,
      "requires": {
        "loader-utils": "^2.0.0",
        "schema-utils": "^3.0.0"
      },
      "dependencies": {
        "ajv": {
          "version": "6.12.6",
          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
          "dev": true,
          "requires": {
            "fast-deep-equal": "^3.1.1",
            "fast-json-stable-stringify": "^2.0.0",
            "json-schema-traverse": "^0.4.1",
            "uri-js": "^4.2.2"
          }
        },
        "ajv-keywords": {
          "version": "3.5.2",
          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
          "dev": true,
          "requires": {}
        },
        "json-schema-traverse": {
          "version": "0.4.1",
          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
          "dev": true
        },
        "schema-utils": {
          "version": "3.1.1",
          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
          "dev": true,
          "requires": {
            "@types/json-schema": "^7.0.8",
            "ajv": "^6.12.5",
            "ajv-keywords": "^3.5.2"
          }
        }
      }
    },
    "stylehacks": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.1.tgz",
      "integrity": "sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA==",
      "dev": true,
      "requires": {
        "browserslist": "^4.16.0",
        "postcss-selector-parser": "^6.0.4"
      }
    },
    "stylus": {
      "version": "0.54.8",
      "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.8.tgz",
      "integrity": "sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg==",
      "dev": true,
      "requires": {
        "css-parse": "~2.0.0",
        "debug": "~3.1.0",
        "glob": "^7.1.6",
        "mkdirp": "~1.0.4",
        "safer-buffer": "^2.1.2",
        "sax": "~1.2.4",
        "semver": "^6.3.0",
        "source-map": "^0.7.3"
      },
      "dependencies": {
        "debug": {
          "version": "3.1.0",
          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          }
        },
        "ms": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
          "dev": true
        },
        "semver": {
          "version": "6.3.0",
          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
          "dev": true
        }
      }
    },
    "stylus-loader": {
      "version": "6.1.0",
      "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-6.1.0.tgz",
      "integrity": "sha512-qKO34QCsOtSJrXxQQmXsPeaVHh6hMumBAFIoJTcsSr2VzrA6o/CW9HCGR8spCjzJhN8oKQHdj/Ytx0wwXyElkw==",
      "dev": true,
      "requires": {
        "fast-glob": "^3.2.5",
        "klona": "^2.0.4",
        "normalize-path": "^3.0.0"
      }
    },
    "supports-color": {
      "version": "5.5.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
      "dev": true,
      "requires": {
        "has-flag": "^3.0.0"
      }
    },
    "svgo": {
      "version": "2.8.0",
      "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
      "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==",
      "dev": true,
      "requires": {
        "@trysound/sax": "0.2.0",
        "commander": "^7.2.0",
        "css-select": "^4.1.3",
        "css-tree": "^1.1.3",
        "csso": "^4.2.0",
        "picocolors": "^1.0.0",
        "stable": "^0.1.8"
      }
    },
    "symbol-observable": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz",
      "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==",
      "dev": true
    },
    "tapable": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
      "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
      "dev": true
    },
    "tar": {
      "version": "6.1.11",
      "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
      "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
      "dev": true,
      "requires": {
        "chownr": "^2.0.0",
        "fs-minipass": "^2.0.0",
        "minipass": "^3.0.0",
        "minizlib": "^2.1.1",
        "mkdirp": "^1.0.3",
        "yallist": "^4.0.0"
      }
    },
    "terser": {
      "version": "5.7.0",
      "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.0.tgz",
      "integrity": "sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g==",
      "dev": true,
      "requires": {
        "commander": "^2.20.0",
        "source-map": "~0.7.2",
        "source-map-support": "~0.5.19"
      },
      "dependencies": {
        "commander": {
          "version": "2.20.3",
          "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
          "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
          "dev": true
        }
      }
    },
    "terser-webpack-plugin": {
      "version": "5.1.3",
      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.3.tgz",
      "integrity": "sha512-cxGbMqr6+A2hrIB5ehFIF+F/iST5ZOxvOmy9zih9ySbP1C2oEWQSOUS+2SNBTjzx5xLKO4xnod9eywdfq1Nb9A==",
      "dev": true,
      "requires": {
        "jest-worker": "^27.0.2",
        "p-limit": "^3.1.0",
        "schema-utils": "^3.0.0",
        "serialize-javascript": "^5.0.1",
        "source-map": "^0.6.1",
        "terser": "^5.7.0"
      },
      "dependencies": {
        "ajv": {
          "version": "6.12.6",
          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
          "dev": true,
          "requires": {
            "fast-deep-equal": "^3.1.1",
            "fast-json-stable-stringify": "^2.0.0",
            "json-schema-traverse": "^0.4.1",
            "uri-js": "^4.2.2"
          }
        },
        "ajv-keywords": {
          "version": "3.5.2",
          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
          "dev": true,
          "requires": {}
        },
        "json-schema-traverse": {
          "version": "0.4.1",
          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
          "dev": true
        },
        "schema-utils": {
          "version": "3.1.1",
          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
          "dev": true,
          "requires": {
            "@types/json-schema": "^7.0.8",
            "ajv": "^6.12.5",
            "ajv-keywords": "^3.5.2"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "text-table": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
      "dev": true
    },
    "through": {
      "version": "2.3.8",
      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
      "dev": true
    },
    "thunky": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
      "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
      "dev": true
    },
    "timsort": {
      "version": "0.3.0",
      "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
      "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
      "dev": true
    },
    "tmp": {
      "version": "0.0.33",
      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
      "dev": true,
      "requires": {
        "os-tmpdir": "~1.0.2"
      }
    },
    "to-fast-properties": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
      "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
      "dev": true
    },
    "to-object-path": {
      "version": "0.3.0",
      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
      "dev": true,
      "requires": {
        "kind-of": "^3.0.2"
      },
      "dependencies": {
        "kind-of": {
          "version": "3.2.2",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
          "dev": true,
          "requires": {
            "is-buffer": "^1.1.5"
          }
        }
      }
    },
    "to-regex": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
      "dev": true,
      "requires": {
        "define-property": "^2.0.2",
        "extend-shallow": "^3.0.2",
        "regex-not": "^1.0.2",
        "safe-regex": "^1.1.0"
      }
    },
    "to-regex-range": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
      "dev": true,
      "requires": {
        "is-number": "^7.0.0"
      }
    },
    "toidentifier": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
      "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
      "dev": true
    },
    "tough-cookie": {
      "version": "2.5.0",
      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
      "dev": true,
      "requires": {
        "psl": "^1.1.28",
        "punycode": "^2.1.1"
      }
    },
    "tree-kill": {
      "version": "1.2.2",
      "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
      "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
      "dev": true
    },
    "tslib": {
      "version": "2.3.1",
      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
      "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
    },
    "tunnel-agent": {
      "version": "0.6.0",
      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
      "dev": true,
      "requires": {
        "safe-buffer": "^5.0.1"
      }
    },
    "tweetnacl": {
      "version": "0.14.5",
      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
      "dev": true
    },
    "type-fest": {
      "version": "0.21.3",
      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
      "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
      "dev": true
    },
    "type-is": {
      "version": "1.6.18",
      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
      "dev": true,
      "requires": {
        "media-typer": "0.3.0",
        "mime-types": "~2.1.24"
      }
    },
    "typescript": {
      "version": "4.3.5",
      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
      "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
      "dev": 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==",
      "dev": true
    },
    "unicode-canonical-property-names-ecmascript": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
      "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==",
      "dev": true
    },
    "unicode-match-property-ecmascript": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
      "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
      "dev": true,
      "requires": {
        "unicode-canonical-property-names-ecmascript": "^2.0.0",
        "unicode-property-aliases-ecmascript": "^2.0.0"
      }
    },
    "unicode-match-property-value-ecmascript": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz",
      "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==",
      "dev": true
    },
    "unicode-property-aliases-ecmascript": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz",
      "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==",
      "dev": true
    },
    "union-value": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
      "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
      "dev": true,
      "requires": {
        "arr-union": "^3.1.0",
        "get-value": "^2.0.6",
        "is-extendable": "^0.1.1",
        "set-value": "^2.0.1"
      },
      "dependencies": {
        "is-extendable": {
          "version": "0.1.1",
          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
          "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
          "dev": true
        }
      }
    },
    "uniq": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
      "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
      "dev": true
    },
    "unique-filename": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
      "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
      "dev": true,
      "requires": {
        "unique-slug": "^2.0.0"
      }
    },
    "unique-slug": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
      "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
      "dev": true,
      "requires": {
        "imurmurhash": "^0.1.4"
      }
    },
    "universalify": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
      "dev": true
    },
    "unpipe": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
      "dev": true
    },
    "unset-value": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
      "dev": true,
      "requires": {
        "has-value": "^0.3.1",
        "isobject": "^3.0.0"
      },
      "dependencies": {
        "has-value": {
          "version": "0.3.1",
          "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
          "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
          "dev": true,
          "requires": {
            "get-value": "^2.0.3",
            "has-values": "^0.1.4",
            "isobject": "^2.0.0"
          },
          "dependencies": {
            "isobject": {
              "version": "2.1.0",
              "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
              "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
              "dev": true,
              "requires": {
                "isarray": "1.0.0"
              }
            }
          }
        },
        "has-values": {
          "version": "0.1.4",
          "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
          "dev": true
        }
      }
    },
    "upath": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
      "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
      "dev": true
    },
    "uri-js": {
      "version": "4.4.1",
      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
      "dev": true,
      "requires": {
        "punycode": "^2.1.0"
      }
    },
    "urix": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
      "dev": true
    },
    "url": {
      "version": "0.11.0",
      "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
      "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
      "dev": true,
      "requires": {
        "punycode": "1.3.2",
        "querystring": "0.2.0"
      },
      "dependencies": {
        "punycode": {
          "version": "1.3.2",
          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
          "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
          "dev": true
        }
      }
    },
    "url-parse": {
      "version": "1.5.4",
      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.4.tgz",
      "integrity": "sha512-ITeAByWWoqutFClc/lRZnFplgXgEZr3WJ6XngMM/N9DMIm4K8zXPCZ1Jdu0rERwO84w1WC5wkle2ubwTA4NTBg==",
      "dev": true,
      "requires": {
        "querystringify": "^2.1.1",
        "requires-port": "^1.0.0"
      }
    },
    "use": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
      "dev": true
    },
    "util-deprecate": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
      "dev": true
    },
    "utils-merge": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
      "dev": true
    },
    "uuid": {
      "version": "8.3.2",
      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
      "dev": true
    },
    "validate-npm-package-name": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz",
      "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=",
      "dev": true,
      "requires": {
        "builtins": "^1.0.3"
      }
    },
    "vary": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
      "dev": true
    },
    "verror": {
      "version": "1.10.0",
      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
      "dev": true,
      "requires": {
        "assert-plus": "^1.0.0",
        "core-util-is": "1.0.2",
        "extsprintf": "^1.2.0"
      }
    },
    "void-elements": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
      "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
      "dev": true
    },
    "watchpack": {
      "version": "2.3.1",
      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz",
      "integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==",
      "dev": true,
      "requires": {
        "glob-to-regexp": "^0.4.1",
        "graceful-fs": "^4.1.2"
      }
    },
    "wbuf": {
      "version": "1.7.3",
      "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
      "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
      "dev": true,
      "requires": {
        "minimalistic-assert": "^1.0.0"
      }
    },
    "wcwidth": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
      "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
      "dev": true,
      "requires": {
        "defaults": "^1.0.3"
      }
    },
    "webpack": {
      "version": "5.44.0",
      "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.44.0.tgz",
      "integrity": "sha512-I1S1w4QLoKmH19pX6YhYN0NiSXaWY8Ou00oA+aMcr9IUGeF5azns+IKBkfoAAG9Bu5zOIzZt/mN35OffBya8AQ==",
      "dev": true,
      "requires": {
        "@types/eslint-scope": "^3.7.0",
        "@types/estree": "^0.0.50",
        "@webassemblyjs/ast": "1.11.1",
        "@webassemblyjs/wasm-edit": "1.11.1",
        "@webassemblyjs/wasm-parser": "1.11.1",
        "acorn": "^8.4.1",
        "browserslist": "^4.14.5",
        "chrome-trace-event": "^1.0.2",
        "enhanced-resolve": "^5.8.0",
        "es-module-lexer": "^0.7.1",
        "eslint-scope": "5.1.1",
        "events": "^3.2.0",
        "glob-to-regexp": "^0.4.1",
        "graceful-fs": "^4.2.4",
        "json-parse-better-errors": "^1.0.2",
        "loader-runner": "^4.2.0",
        "mime-types": "^2.1.27",
        "neo-async": "^2.6.2",
        "schema-utils": "^3.0.0",
        "tapable": "^2.1.1",
        "terser-webpack-plugin": "^5.1.3",
        "watchpack": "^2.2.0",
        "webpack-sources": "^2.3.0"
      },
      "dependencies": {
        "ajv": {
          "version": "6.12.6",
          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
          "dev": true,
          "requires": {
            "fast-deep-equal": "^3.1.1",
            "fast-json-stable-stringify": "^2.0.0",
            "json-schema-traverse": "^0.4.1",
            "uri-js": "^4.2.2"
          }
        },
        "ajv-keywords": {
          "version": "3.5.2",
          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
          "dev": true,
          "requires": {}
        },
        "json-schema-traverse": {
          "version": "0.4.1",
          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
          "dev": true
        },
        "schema-utils": {
          "version": "3.1.1",
          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
          "dev": true,
          "requires": {
            "@types/json-schema": "^7.0.8",
            "ajv": "^6.12.5",
            "ajv-keywords": "^3.5.2"
          }
        },
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        },
        "webpack-sources": {
          "version": "2.3.1",
          "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz",
          "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==",
          "dev": true,
          "requires": {
            "source-list-map": "^2.0.1",
            "source-map": "^0.6.1"
          }
        }
      }
    },
    "webpack-dev-middleware": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.0.0.tgz",
      "integrity": "sha512-9zng2Z60pm6A98YoRcA0wSxw1EYn7B7y5owX/Tckyt9KGyULTkLtiavjaXlWqOMkM0YtqGgL3PvMOFgyFLq8vw==",
      "dev": true,
      "requires": {
        "colorette": "^1.2.2",
        "mem": "^8.1.1",
        "memfs": "^3.2.2",
        "mime-types": "^2.1.31",
        "range-parser": "^1.2.1",
        "schema-utils": "^3.0.0"
      },
      "dependencies": {
        "ajv": {
          "version": "6.12.6",
          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
          "dev": true,
          "requires": {
            "fast-deep-equal": "^3.1.1",
            "fast-json-stable-stringify": "^2.0.0",
            "json-schema-traverse": "^0.4.1",
            "uri-js": "^4.2.2"
          }
        },
        "ajv-keywords": {
          "version": "3.5.2",
          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
          "dev": true,
          "requires": {}
        },
        "json-schema-traverse": {
          "version": "0.4.1",
          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
          "dev": true
        },
        "schema-utils": {
          "version": "3.1.1",
          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
          "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
          "dev": true,
          "requires": {
            "@types/json-schema": "^7.0.8",
            "ajv": "^6.12.5",
            "ajv-keywords": "^3.5.2"
          }
        }
      }
    },
    "webpack-dev-server": {
      "version": "3.11.2",
      "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz",
      "integrity": "sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ==",
      "dev": true,
      "requires": {
        "ansi-html": "0.0.7",
        "bonjour": "^3.5.0",
        "chokidar": "^2.1.8",
        "compression": "^1.7.4",
        "connect-history-api-fallback": "^1.6.0",
        "debug": "^4.1.1",
        "del": "^4.1.1",
        "express": "^4.17.1",
        "html-entities": "^1.3.1",
        "http-proxy-middleware": "0.19.1",
        "import-local": "^2.0.0",
        "internal-ip": "^4.3.0",
        "ip": "^1.1.5",
        "is-absolute-url": "^3.0.3",
        "killable": "^1.0.1",
        "loglevel": "^1.6.8",
        "opn": "^5.5.0",
        "p-retry": "^3.0.1",
        "portfinder": "^1.0.26",
        "schema-utils": "^1.0.0",
        "selfsigned": "^1.10.8",
        "semver": "^6.3.0",
        "serve-index": "^1.9.1",
        "sockjs": "^0.3.21",
        "sockjs-client": "^1.5.0",
        "spdy": "^4.0.2",
        "strip-ansi": "^3.0.1",
        "supports-color": "^6.1.0",
        "url": "^0.11.0",
        "webpack-dev-middleware": "^3.7.2",
        "webpack-log": "^2.0.0",
        "ws": "^6.2.1",
        "yargs": "^13.3.2"
      },
      "dependencies": {
        "ajv": {
          "version": "6.12.6",
          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
          "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
          "dev": true,
          "requires": {
            "fast-deep-equal": "^3.1.1",
            "fast-json-stable-stringify": "^2.0.0",
            "json-schema-traverse": "^0.4.1",
            "uri-js": "^4.2.2"
          }
        },
        "ajv-keywords": {
          "version": "3.5.2",
          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
          "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
          "dev": true,
          "requires": {}
        },
        "ansi-regex": {
          "version": "2.1.1",
          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
          "dev": true
        },
        "anymatch": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
          "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
          "dev": true,
          "requires": {
            "micromatch": "^3.1.4",
            "normalize-path": "^2.1.1"
          },
          "dependencies": {
            "normalize-path": {
              "version": "2.1.1",
              "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
              "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
              "dev": true,
              "requires": {
                "remove-trailing-separator": "^1.0.1"
              }
            }
          }
        },
        "binary-extensions": {
          "version": "1.13.1",
          "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
          "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
          "dev": true
        },
        "braces": {
          "version": "2.3.2",
          "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
          "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
          "dev": true,
          "requires": {
            "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"
          },
          "dependencies": {
            "extend-shallow": {
              "version": "2.0.1",
              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
              "dev": true,
              "requires": {
                "is-extendable": "^0.1.0"
              }
            }
          }
        },
        "chokidar": {
          "version": "2.1.8",
          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
          "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
          "dev": true,
          "requires": {
            "anymatch": "^2.0.0",
            "async-each": "^1.0.1",
            "braces": "^2.3.2",
            "fsevents": "^1.2.7",
            "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"
          }
        },
        "cliui": {
          "version": "5.0.0",
          "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
          "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
          "dev": true,
          "requires": {
            "string-width": "^3.1.0",
            "strip-ansi": "^5.2.0",
            "wrap-ansi": "^5.1.0"
          },
          "dependencies": {
            "ansi-regex": {
              "version": "4.1.0",
              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
              "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
              "dev": true
            },
            "strip-ansi": {
              "version": "5.2.0",
              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
              "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
              "dev": true,
              "requires": {
                "ansi-regex": "^4.1.0"
              }
            }
          }
        },
        "emoji-regex": {
          "version": "7.0.3",
          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
          "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
          "dev": true
        },
        "fill-range": {
          "version": "4.0.0",
          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
          "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
          "dev": true,
          "requires": {
            "extend-shallow": "^2.0.1",
            "is-number": "^3.0.0",
            "repeat-string": "^1.6.1",
            "to-regex-range": "^2.1.0"
          },
          "dependencies": {
            "extend-shallow": {
              "version": "2.0.1",
              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
              "dev": true,
              "requires": {
                "is-extendable": "^0.1.0"
              }
            }
          }
        },
        "find-up": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
          "dev": true,
          "requires": {
            "locate-path": "^3.0.0"
          }
        },
        "fsevents": {
          "version": "1.2.13",
          "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
          "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
          "dev": true,
          "optional": true,
          "requires": {
            "bindings": "^1.5.0",
            "nan": "^2.12.1"
          }
        },
        "glob-parent": {
          "version": "3.1.0",
          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
          "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
          "dev": true,
          "requires": {
            "is-glob": "^3.1.0",
            "path-dirname": "^1.0.0"
          },
          "dependencies": {
            "is-glob": {
              "version": "3.1.0",
              "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
              "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
              "dev": true,
              "requires": {
                "is-extglob": "^2.1.0"
              }
            }
          }
        },
        "is-binary-path": {
          "version": "1.0.1",
          "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
          "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
          "dev": true,
          "requires": {
            "binary-extensions": "^1.0.0"
          }
        },
        "is-extendable": {
          "version": "0.1.1",
          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
          "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
          "dev": true
        },
        "is-fullwidth-code-point": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
          "dev": true
        },
        "is-number": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
          "dev": true,
          "requires": {
            "kind-of": "^3.0.2"
          },
          "dependencies": {
            "kind-of": {
              "version": "3.2.2",
              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
              "dev": true,
              "requires": {
                "is-buffer": "^1.1.5"
              }
            }
          }
        },
        "json-schema-traverse": {
          "version": "0.4.1",
          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
          "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
          "dev": true
        },
        "locate-path": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
          "dev": true,
          "requires": {
            "p-locate": "^3.0.0",
            "path-exists": "^3.0.0"
          }
        },
        "micromatch": {
          "version": "3.1.10",
          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
          "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
          "dev": true,
          "requires": {
            "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"
          }
        },
        "mkdirp": {
          "version": "0.5.5",
          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
          "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
          "dev": true,
          "requires": {
            "minimist": "^1.2.5"
          }
        },
        "p-limit": {
          "version": "2.3.0",
          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
          "dev": true,
          "requires": {
            "p-try": "^2.0.0"
          }
        },
        "p-locate": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
          "dev": true,
          "requires": {
            "p-limit": "^2.0.0"
          }
        },
        "path-exists": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
          "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
          "dev": true
        },
        "readable-stream": {
          "version": "2.3.7",
          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
          "dev": true,
          "requires": {
            "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": {
          "version": "2.2.1",
          "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
          "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
          "dev": true,
          "requires": {
            "graceful-fs": "^4.1.11",
            "micromatch": "^3.1.10",
            "readable-stream": "^2.0.2"
          }
        },
        "schema-utils": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
          "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
          "dev": true,
          "requires": {
            "ajv": "^6.1.0",
            "ajv-errors": "^1.0.0",
            "ajv-keywords": "^3.1.0"
          }
        },
        "semver": {
          "version": "6.3.0",
          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
          "dev": true
        },
        "string_decoder": {
          "version": "1.1.1",
          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
          "dev": true,
          "requires": {
            "safe-buffer": "~5.1.0"
          }
        },
        "string-width": {
          "version": "3.1.0",
          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
          "dev": true,
          "requires": {
            "emoji-regex": "^7.0.1",
            "is-fullwidth-code-point": "^2.0.0",
            "strip-ansi": "^5.1.0"
          },
          "dependencies": {
            "ansi-regex": {
              "version": "4.1.0",
              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
              "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
              "dev": true
            },
            "strip-ansi": {
              "version": "5.2.0",
              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
              "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
              "dev": true,
              "requires": {
                "ansi-regex": "^4.1.0"
              }
            }
          }
        },
        "strip-ansi": {
          "version": "3.0.1",
          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
          "dev": true,
          "requires": {
            "ansi-regex": "^2.0.0"
          }
        },
        "supports-color": {
          "version": "6.1.0",
          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
          "dev": true,
          "requires": {
            "has-flag": "^3.0.0"
          }
        },
        "to-regex-range": {
          "version": "2.1.1",
          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
          "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
          "dev": true,
          "requires": {
            "is-number": "^3.0.0",
            "repeat-string": "^1.6.1"
          }
        },
        "webpack-dev-middleware": {
          "version": "3.7.3",
          "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz",
          "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==",
          "dev": true,
          "requires": {
            "memory-fs": "^0.4.1",
            "mime": "^2.4.4",
            "mkdirp": "^0.5.1",
            "range-parser": "^1.2.1",
            "webpack-log": "^2.0.0"
          }
        },
        "wrap-ansi": {
          "version": "5.1.0",
          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
          "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
          "dev": true,
          "requires": {
            "ansi-styles": "^3.2.0",
            "string-width": "^3.0.0",
            "strip-ansi": "^5.0.0"
          },
          "dependencies": {
            "ansi-regex": {
              "version": "4.1.0",
              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
              "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
              "dev": true
            },
            "strip-ansi": {
              "version": "5.2.0",
              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
              "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
              "dev": true,
              "requires": {
                "ansi-regex": "^4.1.0"
              }
            }
          }
        },
        "ws": {
          "version": "6.2.2",
          "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
          "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
          "dev": true,
          "requires": {
            "async-limiter": "~1.0.0"
          }
        },
        "y18n": {
          "version": "4.0.3",
          "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
          "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
          "dev": true
        },
        "yargs": {
          "version": "13.3.2",
          "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
          "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
          "dev": true,
          "requires": {
            "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-parser": {
          "version": "13.1.2",
          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
          "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
          "dev": true,
          "requires": {
            "camelcase": "^5.0.0",
            "decamelize": "^1.2.0"
          }
        }
      }
    },
    "webpack-log": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
      "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
      "dev": true,
      "requires": {
        "ansi-colors": "^3.0.0",
        "uuid": "^3.3.2"
      },
      "dependencies": {
        "ansi-colors": {
          "version": "3.2.4",
          "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
          "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==",
          "dev": true
        },
        "uuid": {
          "version": "3.4.0",
          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
          "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
          "dev": true
        }
      }
    },
    "webpack-merge": {
      "version": "5.8.0",
      "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz",
      "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==",
      "dev": true,
      "requires": {
        "clone-deep": "^4.0.1",
        "wildcard": "^2.0.0"
      }
    },
    "webpack-sources": {
      "version": "1.4.3",
      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
      "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
      "dev": true,
      "requires": {
        "source-list-map": "^2.0.0",
        "source-map": "~0.6.1"
      },
      "dependencies": {
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "webpack-subresource-integrity": {
      "version": "1.5.2",
      "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.5.2.tgz",
      "integrity": "sha512-GBWYBoyalbo5YClwWop9qe6Zclp8CIXYGIz12OPclJhIrSplDxs1Ls1JDMH8xBPPrg1T6ISaTW9Y6zOrwEiAzw==",
      "dev": true,
      "requires": {
        "webpack-sources": "^1.3.0"
      }
    },
    "websocket-driver": {
      "version": "0.7.4",
      "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
      "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
      "dev": true,
      "requires": {
        "http-parser-js": ">=0.5.1",
        "safe-buffer": ">=5.1.0",
        "websocket-extensions": ">=0.1.1"
      }
    },
    "websocket-extensions": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
      "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
      "dev": true
    },
    "which": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
      "dev": true,
      "requires": {
        "isexe": "^2.0.0"
      }
    },
    "which-module": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
      "dev": true
    },
    "wide-align": {
      "version": "1.1.5",
      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
      "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
      "dev": true,
      "requires": {
        "string-width": "^1.0.2 || 2 || 3 || 4"
      }
    },
    "wildcard": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz",
      "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
      "dev": true
    },
    "wrap-ansi": {
      "version": "7.0.0",
      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
      "dev": true,
      "requires": {
        "ansi-styles": "^4.0.0",
        "string-width": "^4.1.0",
        "strip-ansi": "^6.0.0"
      },
      "dependencies": {
        "ansi-styles": {
          "version": "4.3.0",
          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
          "dev": true,
          "requires": {
            "color-convert": "^2.0.1"
          }
        },
        "color-convert": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
          "dev": true,
          "requires": {
            "color-name": "~1.1.4"
          }
        },
        "color-name": {
          "version": "1.1.4",
          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
          "dev": true
        }
      }
    },
    "wrappy": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
      "dev": true
    },
    "ws": {
      "version": "8.2.3",
      "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
      "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
      "dev": true,
      "requires": {}
    },
    "y18n": {
      "version": "5.0.8",
      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
      "dev": true
    },
    "yallist": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
      "dev": true
    },
    "yaml": {
      "version": "1.10.2",
      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
      "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
      "dev": true
    },
    "yargs": {
      "version": "17.3.1",
      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz",
      "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==",
      "dev": true,
      "requires": {
        "cliui": "^7.0.2",
        "escalade": "^3.1.1",
        "get-caller-file": "^2.0.5",
        "require-directory": "^2.1.1",
        "string-width": "^4.2.3",
        "y18n": "^5.0.5",
        "yargs-parser": "^21.0.0"
      }
    },
    "yargs-parser": {
      "version": "21.0.0",
      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz",
      "integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==",
      "dev": true
    },
    "yocto-queue": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
      "dev": true
    },
    "zone.js": {
      "version": "0.11.4",
      "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.11.4.tgz",
      "integrity": "sha512-DDh2Ab+A/B+9mJyajPjHFPWfYU1H+pdun4wnnk0OcQTNjem1XQSZ2CDW+rfZEUDjv5M19SBqAkjZi0x5wuB5Qw==",
      "requires": {
        "tslib": "^2.0.0"
      }
    }
  }
}

frontend/nginx.conf METASEP
events{}
http {
    include /etc/nginx/mime.types;
    server {
        listen 80 default_server;
        server_name _;
        root /usr/share/nginx/html;
        index index.html;
        location / {
            try_files $uri $uri/ /index.html;
        }
    }
}
frontend/karma.conf.js METASEP
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular-devkit/build-angular'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage'),
      require('@angular-devkit/build-angular/plugins/karma')
    ],
    client: {
      jasmine: {
        // you can add configuration options for Jasmine here
        // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
        // for example, you can disable the random execution with `random: false`
        // or set a specific seed with `seed: 4321`
      },
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    jasmineHtmlReporter: {
      suppressAll: true // removes the duplicated traces
    },
    coverageReporter: {
      dir: require('path').join(__dirname, './coverage/t4cclient'),
      subdir: '.',
      reporters: [
        { type: 'html' },
        { type: 'text-summary' }
      ]
    },
    reporters: ['progress', 'kjhtml'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: false,
    restartOnFileChange: true
  });
};

frontend/angular.json METASEP
{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "t4cclient": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:application": {
          "strict": true
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/t4cclient",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/custom-theme.scss",
              "src/styles.css"
            ],
            "optimization": {
              "fonts": false
            },
            "scripts": []
          },
          "configurations": {
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "outputHashing": "all"
            },
            "development": {
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true,
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.dev.ts"
                }
              ]
            }
          },
          "defaultConfiguration": "production"
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "configurations": {
            "production": {
              "browserTarget": "t4cclient:build:production"
            },
            "development": {
              "browserTarget": "t4cclient:build:development"
            }
          },
          "defaultConfiguration": "development"
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "t4cclient:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.css"
            ],
            "scripts": []
          }
        }
      }
    }
  },
  "defaultProject": "t4cclient"
}

frontend/README.md METASEP
# Frontend T4C Manager

## Development

Run 
```
ng serve --open
```

## Build it

1) Place a file `logo.svg` in the folder `assets`
2) Adjust the theme colors in the file `src/custom-theme.scss`. 
   The themes can be generated here: http://mcg.mbitson.com/

   Additionally, you have to adjust the styles in `src/styles.css`
3) Add the file `src/environments/environment.prod.ts` with the following content: 
    ```
    export const environment = {
        production: false,
        backend_url: '/api/v1',
        privacy_statement: 'https://example.com/privacy',
        imprint: 'https://example.com/imprint',
    };
    ```
4) 
    ```
    docker build -t t4c/client/frontend .
    ```

## Run it

```
docker run -p 8000:80 t4c/client/frontend
```

frontend/Makefile METASEP
dev: 
	ng serve --open
frontend/Dockerfile METASEP
FROM node:14 as build

COPY ./ /work/
WORKDIR /work
RUN npm install
RUN npm run build

FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf
COPY --from=build /work/dist/t4cclient /usr/share/nginx/html

frontend/.gitlab-ci.yml METASEP
include:
  - project: 'se-toolchain/ci-templates-docker'
    ref: v1.11.0
    file: 
      - '/gitlab-ci/angular/build.yml'
      - '/gitlab-ci/docker/upload-registry.yml'

angular-build: 
  stage: build
  extends: .angular-build

docker-registry:
  extends: .docker-registry
  variables: 
    DOCKER_IMAGE_NAME: "t4c/client/frontend"

frontend/.gitignore METASEP
# See http://help.github.com/ignore-files/ for more about ignoring files.

# compiled output
/dist
/tmp
/out-tsc
# Only exists if Bazel was run
/bazel-out

# dependencies
/node_modules

# profiling files
chrome-profiler-events*.json

# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*

# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings

# System Files
.DS_Store
Thumbs.db

/src/environments/environment.prod.ts
/src/environments/environment.dev.ts
frontend/.editorconfig METASEP
# Editor configuration, see https://editorconfig.org
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.ts]
quote_type = single

[*.md]
max_line_length = off
trim_trailing_whitespace = false

frontend/.dockerignore METASEP
dist
node_modules
Dockerfile

frontend/.browserslistrc METASEP
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries

# For the full list of supported browsers by the Angular framework, please see:
# https://angular.io/guide/browser-support

# You can see what browsers were selected by your queries by running:
#   npx browserslist

last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.

backend/setup.cfg METASEP
[metadata]
name = t4c-client-backend
version = 0.0.1
description = Backend for the T4C Client Manager to request T4C Docker Containers. 
author = Moritz Weber
author_email = moritz.weber@deutschebahn.com


[options]
packages = find:
install_requires =
    fastapi
    pydantic
    docker
    python-jose
    requests_oauthlib
    sqlalchemy
    psycopg2
    alembic
    kubernetes
    python-dateutil
    msal
    cachetools


[options.entry_points]
capellacollab.extensions.backups =
    ease = t4cclient.extensions.backups.ease
    jenkins = t4cclient.extensions.backups.jenkins
capellacollab.extensions.modelsources =
    git = t4cclient.extensions.modelsources.git
    t4c = t4cclient.extensions.modelsources.t4c
capellacollab.operators =
    k8s = t4cclient.core.operators.k8s:KubernetesOperator
    docker = t4cclient.core.operators.docker:DockerOperator
backend/pyproject.toml METASEP
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
backend/README.md METASEP
# Development

Preparation
===============
1) Install required packages: 
    ```
    pip install .
    pip install "uvicorn[standard]"
    ```
1) Create a folder config in the root directory of this project.
1) In the config folder, create a file `config.ini`. For all configuration keys, please check `t4cclient/config.py`.
1) Also, you might place a `pubkey.pem` in the config folder for OAUTH.
1) Setup a PostgreSQL Database and set the config key `DATABASE_URL` in the format `postgresql://scott:tiger@localhost:5432/mydatabase`


Run the project
===============

```
uvicorn t4cclient.__main__:app
```

Database migrations
===============

To manually migrate the database (in most cases this is not necessary as the database is automatically migrated on startup): 
```
cd t4cclient
alembic upgrade head
```

To create an upgrade script automatically (this will compare the current database state with the models): 
```
cd t4cclient
alembic revision --autogenerate -m "Commit message"
```

# Docker

## Build the image

Please run: 
```
docker build -t t4c/client/backend .
```

## Run the Container

```
docker run \
    -v path/to/pubkey.pem:/backend/config # Mount the OAUTH public key
    -e CONFIG_KEY=CONFIG_VALUE # Mount every config variable as environment variables (see `t4cclient/core/config.py`)
    t4c/client/backend
```
backend/Makefile METASEP
DB_PORT = 5432
VENV = .venv/bin

database: 
	docker start capella-collab-postgres || \
	docker run -d \
		--name capella-collab-postgres \
		-p $(DB_PORT):5432 \
		-e POSTGRES_PASSWORD=dev \
		-e POSTGRES_USER=dev \
		-e POSTGRES_DB=dev \
		postgres

python: 
	$(VENV)/uvicorn t4cclient.__main__:app --reload

dev: database python
	
cleanup: 
	docker stop capella-collab-postgres
	docker rm capella-collab-postgres
backend/Dockerfile METASEP
FROM buildpack-deps:bullseye

RUN apt-get update && \
    apt-get upgrade --yes && \
    apt-get install --yes \
    ca-certificates \
    python3 \
    python3-pip \
    unzip \
    libpq-dev \
    docker.io \
    kubernetes-client && rm -rf /var/lib/apt/lists/*

RUN pip install fastapi uvicorn
EXPOSE 80
COPY . /backend

WORKDIR /backend
RUN pip install .

CMD ["uvicorn", "t4cclient:app", "--host", "0.0.0.0", "--port", "80"]

backend/.gitlab-ci.yml METASEP
include:
  - project: "se-toolchain/ci-templates-docker"
    ref: v1.0.5
    file:
      - "/gitlab-ci/docker/upload-registry.yml"

stages: 
  - deploy
  - trigger

docker-registry:
  variables:
    DOCKER_IMAGE_NAME: "t4c/client/backend"
  extends: .push-to-registry-using-base-image

trigger-garbage-cleaner:
  only:
    - master
  stage: trigger
  trigger: se-toolchain/t4c-client/t4c-client-garbage-cleaner

backend/.gitignore METASEP
.idea
config/*
.history
**/__pycache__/
.vscode
.venv
*.egg-info
build
backend/.dockerignore METASEP
config

backend/setup.py METASEP
import setuptools

setuptools.setup()

helm/templates/NOTES.txt METASEP
█▀▄░█▀▄░░░█▀█░█▀▀░▀█▀░▀▀█░░░█▀█░█▀▀
█░█░█▀▄░░░█░█░█▀▀░░█░░▄▀░░░░█▀█░█░█
▀▀░░▀▀░░░░▀░▀░▀▀▀░░▀░░▀▀▀░░░▀░▀░▀▀▀

Thanks for using our tools! 

helm/commands/upgrade.sh METASEP
# Upgrade deployment

helm upgrade t4c-access \
    -f options.yaml \
    -f values.yaml \
    .
helm/commands/install.sh METASEP
#!/bin/bash
# Install deployment for the first time

# Halt the script on error
set -e

# Parse options.yaml to determine to find out if the database should be initialized
python -m venv .venv --system-site-packages --upgrade-deps
source .venv/bin/activate
pip install PyYAML

DEPLOY_DB=$(python3 commands/parse_yaml.py)

if [[ $DEPLOY_DB -eq 1 ]]
then 
    docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgres > config/initdb.sql
fi

# Install the helm chart
helm install t4c-access \
    --dry-run \
    -f options.yaml \
    -f values.yaml \
    .
README.md METASEP
# A web platform for collaboration on Capella (MBSE) projects

**Copyright 2021 DB Netz AG, licensed under Apache 2.0 License (see full text in LICENSE file)**

Turns local Capella experience into a browser-based collaboration platform for model-based projects. Designed to enable co-working across multiple organizations.
Here are some of the key features:

* Supports both git and TeamForCapella co-working models
* SSO via OAuth2
* No need to install or maintain local Capella clients - clients are made on demand in a underlaying Kubernetes cluster
* Access to projects and models is self-managed by project leads, model owners or delegates
* Within a project a user could have read or read/write access. Read-only users don't consume licenses in TeamForCapella projects
* Integration with git repository management for backup and workflow automation around the models

We have more exciting features on our roadmap, like integration of templating, planning and release management for model-derived artifacts (documents, interface definitions, spreadsheets, etc.)

# Getting started

## Requirements

Here is a short summary of what you would need to run this environment: TODO

## Running locally with k3d

To run this thing locally you'll need:
* a Linux machine
* [Docker](https://docs.docker.com/engine/install/ubuntu/)
* [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/)
* [helm](https://helm.sh/docs/intro/install/)
* [K3D](https://k3d.io/) - a lightweight k8s cluster simulator
* `nss-myhostname` to access local container registry - you can get in on Ubuntu via `sudo apt install libnss-myhostname`

When you have all that installed you can simply do the following:

```
git clone --recurse-submodules ...; cd capella-collab-manager
make create-cluster  # this creates cluster and container registry
MY_EMAIL=me@mydomain.com make deploy  # build and deploy the manager app
kubectl get pods --namespace=t4c-manager  # verify your deployment - components should be in "Running" state
```

TODO: it fails at this point, need to find a way to fix it
TODO

### Limitations

* Only works with Azure AD as authentication backend, create a small file `secrets.yaml` in this folder:

  ```yaml
  backend:
  oauth:
    authorizationEndpoint: https://login.microsoftonline.com/<tenant-id>
    usernameClaim: preferred_username
    
    client: 
      # OAUTH2 Client ID
      id: <client id, a.k.a. application id>
      # OAUTH2 Client Secret
      secret: <secret>
  ```

* When launching a Guacamole container, the local address (when testing on K3D) is wrong.
  Change the URL to point to port 8081.

## Running on a cluster

TODO

## TeamForCapella integration

TODO

# How it works

Here comes a brief intro into architecture of this thing (TODO)

# Contributing

TODO

Makefile METASEP

CLUSTER_NAME = mycluster
LOCAL_REGISTRY_NAME = localhost
CLUSTER_REGISTRY_NAME = myregistry.localhost
REGISTRY_PORT = 12345
RELEASE = dev-t4c-manager
NAMESPACE = t4c-manager
MY_EMAIL ?= me@example.com

all: backend frontend

build: backend frontend capella ease

backend:
	docker build -t t4c/client/backend -t $(LOCAL_REGISTRY_NAME):$(REGISTRY_PORT)/t4c/client/backend backend
	docker push $(LOCAL_REGISTRY_NAME):$(REGISTRY_PORT)/t4c/client/backend

frontend:
	docker build -t t4c/client/frontend -t $(LOCAL_REGISTRY_NAME):$(REGISTRY_PORT)/t4c/client/frontend frontend
	docker push $(LOCAL_REGISTRY_NAME):$(REGISTRY_PORT)/t4c/client/frontend

capella:
	docker build -t base capella-dockerimages/base
	docker build -t capella/base capella-dockerimages/capella
	docker build -t capella/remote -t $(LOCAL_REGISTRY_NAME):$(REGISTRY_PORT)/t4c/client/remote capella-dockerimages/remote
	docker push $(LOCAL_REGISTRY_NAME):$(REGISTRY_PORT)/t4c/client/remote

ease: 
	docker build -t capella/ease --build-arg BASE_IMAGE=capella/base --build-arg BUILD_TYPE=online capella-dockerimages/ease
	docker build -t capella/ease/remote --build-arg BASE_IMAGE=capella/ease capella-dockerimages/remote
	docker build -t $(LOCAL_REGISTRY_NAME):$(REGISTRY_PORT)/capella/readonly --build-arg BASE_IMAGE=capella/ease/remote capella-dockerimages/readonly
	docker push $(LOCAL_REGISTRY_NAME):$(REGISTRY_PORT)/capella/readonly

deploy: backend frontend capella ease helm-deploy

helm-deploy: 
	k3d cluster list $(CLUSTER_NAME) 2>&- || $(MAKE) create-cluster
	helm upgrade --install \
		--kube-context k3d-$(CLUSTER_NAME) \
		--create-namespace \
		--namespace $(NAMESPACE) \
		--values helm/values.yaml \
		$$(test -f secrets.yaml && echo "--values secrets.yaml") \
		--set docker.registry=k3d-$(CLUSTER_REGISTRY_NAME):$(REGISTRY_PORT) \
		--set database.backend.initialAdmin=$(MY_EMAIL) \
		--set general.port=8081 \
		--wait --timeout 4m \
		--debug \
		$(RELEASE) ./helm
	$(MAKE) .rollout .provision-guacamole .provision-backend

clear-backend-db: 
	kubectl delete deployment -n t4c-manager $(RELEASE)-backend-postgres
	kubectl delete pvc -n t4c-manager $(RELEASE)-volume-backend-postgres
	$(MAKE) helm-deploy

rollout: backend frontend
	$(MAKE) .rollout

.rollout: 
	kubectl --context k3d-$(CLUSTER_NAME) rollout restart deployment -n $(NAMESPACE) $(RELEASE)-backend
	kubectl --context k3d-$(CLUSTER_NAME) rollout restart deployment -n $(NAMESPACE) $(RELEASE)-frontend

undeploy:
	helm uninstall --kube-context k3d-$(CLUSTER_NAME) --namespace $(NAMESPACE) $(RELEASE)
	rm -f .provision-guacamole .provision-backend

create-cluster:
	type k3d || { echo "K3D is not installed, install k3d and run 'make create-cluster' again"; exit 1; }
	k3d registry list $(CLUSTER_REGISTRY_NAME) 2>&- || k3d registry create $(CLUSTER_REGISTRY_NAME) --port $(REGISTRY_PORT)
	k3d cluster list $(CLUSTER_NAME) 2>&- || k3d cluster create $(CLUSTER_NAME) \
		--registry-use k3d-$(CLUSTER_REGISTRY_NAME):$(REGISTRY_PORT) \
		--port "8081:80@loadbalancer"
	kubectl cluster-info

delete-cluster:
	k3d cluster list $(CLUSTER_NAME) 2>&- && k3d cluster delete $(CLUSTER_NAME)
	rm -f .provision-guacamole .provision-backend

.provision-guacamole:
	kubectl exec --namespace $(NAMESPACE) $$(kubectl get pod --namespace $(NAMESPACE) -l id=$(RELEASE)-deployment-guacamole-guacamole --no-headers | cut -f1 -d' ') -- /opt/guacamole/bin/initdb.sh --postgres | \
	kubectl exec -ti --namespace $(NAMESPACE) $$(kubectl get pod --namespace $(NAMESPACE) -l id=$(RELEASE)-deployment-guacamole-postgres --no-headers | cut -f1 -d' ') -- psql -U guacamole guacamole && \
	touch .provision-guacamole

.provision-backend:
	echo "insert into repository_user_association values ('$(MY_EMAIL)', 'default', 'WRITE', 'MANAGER');" | kubectl exec -ti --namespace $(NAMESPACE) $$(kubectl get pod --namespace $(NAMESPACE) -l id=$(RELEASE)-deployment-backend-postgres --no-headers | cut -f1 -d' ') -- psql -U backend backend && \
	touch .provision-backend

.PHONY: backend frontend capella deploy undeploy create-cluster delete-cluster persistent-volume

# Execute with `make -j2 dev`
dev: dev-frontend dev-backend
	
dev-frontend: 
	$(MAKE) -C frontend dev
dev-backend: 
	$(MAKE) -C backend dev

dev-cleanup: 
	$(MAKE) -C backend cleanup

backend-logs: 
	kubectl logs -f -n $(NAMESPACE) -l id=$(RELEASE)-deployment-backend
helm/commands/parse_yaml.py METASEP
import pathlib

import yaml

options = yaml.safe_load(pathlib.Path("options.yaml").open())

print(int(options["database"]["deploy"]))

helm/values.yaml METASEP
#########################################
### APPLICATION RELATED CONFIGURATION ###
#########################################


docker:
  # Registry for Docker Images, will be used as prefix for Docker Images
  registry: docker.io

  images:
    # Docker Image for the Frontend
    frontend: /t4c/client/frontend

    # Docker Image for the Backend
    backend: /t4c/client/backend

    # Docker Image for EASE
    ease: /t4c/client/ease

    workspaces: 
      # Docker Image for the Persistent Workspace Session
      persistent: /t4c/client/remote

      # Docker Image for the ReadOnly Workspace
      readonly: /capella/readonly

general: 
  # Base URL on which the service listens
  host: localhost
  port: 80
  scheme: http

database: 
  # Define whether the database should also be deployed
  # in the cluster or whether it already exists externally. 
  deploy: True

  # Database Configuration for Guacamole
  guacamole: 
    internal: 
      ###### IF database.deploy == True ######

      # Admin password of the database
      password: secret

    external: 
      ###### IF database.deploy == False ######

      # Select type of external database
      # Possible values: MYSQL | POSTGRES
      type: POSTGRES

      # Configure the hostname of the external database
      hostname: 

      # Configure the database name of the external database
      database: 

      # Configure the username of the external database
      username: 

      # Configure the password of the external database
      password: 

  # Database Configuration for the T4C Manager
  backend: 
    # Username of an initial admin user 
    # Is only set if the database is empty!
    initialAdmin: me@example.com

    internal: 
      ###### IF database.deploy == True ######

      # Admin password of the database
      password: secret

    external:
      ###### IF database.deploy == False ######

      # Provide URI to the datebase in the format: postgresql://user:password@url:port/db_name
      uri: postgresql://user:password@url:port/db_name

guacamole:
  # Credentials for the Guacamole Admin User
  username: guacadmin
  password: guacadmin

backend:
  oauth:
    # Endpoint that issues JWT Tokens
    tokenIssuanceEndpoint: tbd
    # Endpoint that authorizes the User
    authorizationEndpoint: tbd
    client:
      # OAUTH2 Client ID
      id: tbd
      # OAUTH2 Client Secret
      secret: tbd
    # Add Username claim
    usernameClaim: sub 

  garbageCleaner:
    cron: "*/10 * * * *"

  # Namespace in which the Session Deployments / Pods should be spawned.
  # IMPORTANT: The namespace has to exist already
  k8sSessionNamespace: t4c-sessions
  storageClassName: local-path
  storageAccessMode: ReadWriteOnce

t4cServer:
  # URL to access the REST APIs of the T4C Server

  apis:
    # API Base for usage and status endpoints 
    # The following endpoints have to be reachable: 
    # - <base>/usage/json
    # - <base>/status/json
    usageStats: http://localhost:8086

    # REST API Base for REST API including the prefix (CRUD for repositories, projects and users)
    # All REST endpoints have to reachable. 
    restAPI: http://localhost:8090/api/v1.0

  # Credentials to authenticate against the REST API endpoint (HTTPBasic)
  username: sampleUser
  password: samplePassword

  # IPv4 Address of the T4C Server
  host: localhost
  port: 2036
  licenseKey: 

jenkins:
  # Admin Credentials for Jenkins Instance
  username: tbd
  password: tbd

  # Base URL of the existing Jenkins Instance
  baseURL: tbd

git:
  # Git Credentials to fetch the Models from Git for the Read Only Workspaces.
  username: tbd
  password: tbd

  # E-Mail for Commits made by the created Backups Jobs
  email: tbd

  # Jenkins Git Credentials ID (Git Plugin)
  credentialID: tbd

  # Repository URL for Scripts used by the Jenkins Backup Job (dsh-tools)
  scriptRepoURL: tbd



########################################
### KUBERNETES RELATED CONFIGURATION ###
########################################

# replicaCount: 1

pullPolicy: Always

imagePullSecrets: []

# SecurityContext for Pods
securityContext:

# target: local | azure
target: local
helm/README.md METASEP
# Installation

## Requirements
The following tools have to be installed and have to be present in your `PATH`: 
- `kubectl` (Installed and configured for the target cluster/namespace)
- `helm` 
- `python3`
- `docker` (only if you'd like to deploy the database automatically in the cluster)

## Setup databases

### Guacamole Database: 
If you like to run your databases in the k8s cluster, please set `database.deploy: True` in the `options.yaml`. Everything is handled automatically then.

Guacamole supports the following database types: 

- MySQL
- PostgreSQL

To initialize the database, you have to run one of the following commands:

For PostgreSQL:
```
docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgres > initdb.sql
```

and for MySQL:
```
docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --mysql > initdb.sql
```

Please update the database with the the resulting SQL script. 
If you run your database in a docker container (`postgres` or `mysql`), you can easily mount the `initdb.sql` file to the `docker-entrypoint-initdb.d` directory inside the container. It will then be executed automatically on startup.

### T4C Manager Database: 
The T4C Manager supports all SQLAlchemy compatible databases.
It has been only tested with PostgreSQL, thus we highly recommend using PostgreSQL.
The backend comes with an automatic database version management and thus all tables are created and migrated automatically.

## Configuration

You have to set the variables according to the descriptions in the `options.yaml` and `values.yaml`.
The `options.yaml` contains all application specific variables, the `values.yaml` all Kubernetes specific variables. 

## Deployment 

For the first deployment, please run: 
```
./commands/install.sh
```

When you'd like to update configuration variables or like to upgrade to a newer version, please run: 
```
./commands/upgrade.sh
```

### Production

Create a namespaces to deploy the manager and sessions in:

```
helm upgrade --install --create-namespace prod-t4c-manager --namespace prod-t4c-manager -f options.prod.yaml -f values.yaml .
```

## Local development

To develop locally, you can use [K3D](https://k3d.io).

Set up a K8s environmena, a registry and a cluster:

```bash
k3d registry create myregistry.localhost --port 12345    
k3d cluster create ertms --registry-use k3d-myregistry.localhost:12345 --api-port 0.0.0.0:6550 --no-lb
```

Build the services and push them to the cluster registry:

```
docker build -t k3d-myregistry.localhost:12345/t4c/client/backend:latest .
docker push k3d-myregistry.localhost:12345/t4c/client/backend:latest      
```

Repeat for `t4c/client/frontend` (and Capella container?).

* Create an admin token to allow the T4C-manager-backend to allow to deploy Capella instances.
* Fix log-on credentials for Azure AD (client/application id and secret)

Make sure `commands/install.sh` is referring to `options.local.yml`.

```
k3d cluster edit ertms --add-port "8000:80@loadbalancer"
```

helm/Chart.yaml METASEP
apiVersion: v2
name: t4c-access-manager
description: T4C Access Manager with OnDemand Capella / T4C Client

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.2

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.0.0"

helm/.helmignore METASEP
.venv

helm/.gitignore METASEP
.venv
initdb.sql
p_options.yaml
helm/config/nginx.conf METASEP
pid /tmp/nginx.pid;
events{}
http {
    server {
        listen 8080 default_server; 
        server_name _;

        location /healthcheck {
            access_log off;
            return 200 "healthy";
        }

        location /guacamole {
            proxy_pass http://{{ .Release.Name }}-guacamole-guacamole:8080;
            proxy_buffering off;
        }

        location /api/v1/ {
            proxy_pass http://{{ .Release.Name }}-backend:80;
            proxy_redirect http://{{ .Release.Name }}-backend {{ .Values.general.scheme }}://$http_host;
            proxy_redirect http://{{ .Release.Name }}-backend:80 {{ .Values.general.scheme }}://$http_host;
        }

        location / {
            proxy_pass http://{{ .Release.Name }}-frontend:80;
        }
    }
}

helm/config/t4c2git.py METASEP

# onStartup: 0
"""EASE script to sync (one-directional) from a T4C Capella model to a Git model.

.. note::

    The module expects, that Eclipse/ Capella is set to English language.


.. seealso::

    The acronym EASE stands for "Eclipse Advanced Scripting Environment".
    Further information: https://www.eclipse.org/ease/

One can optionally set an environment variable named ``DEBUG`` to ``"1"`` to get
a debug level logging with more detailed information (module, function, line no).

Before this script can be run within an EASE context (see below), one must set an
environment variable named ``EASE_WORKSPACE`` pointing to a workspace directory that
will be created/ overwritten.

Then one executes the installed module ``pyease.ease.py`` using a Python3 interpreter to
create a workspace for the execution of Python EASE scripts:

.. code-block:: bash

    python3 -m pyease.ease


The script logs what it does into a log file named ``t4c2git.log`` in the workspace
defined in the environment variable ``EASE_WORKSPACE``.

How to run the current script in EASE is further described with step 2 below.

***************************************************
Three steps to get this Python module to do the job
***************************************************

Step 1
======

The following preconditions must be fulfilled on the computer running this module:

* A Python3 interpreter must be installed
* A Git client (including git-lfs) must be installed
* The current script must be available so that it can be executed
* A Capella client including a configured (license key
  ``DOBEO_LICENSE_SERVER_CONFIGURATION`` in the file
  ``/path/to/Capella/Contents/Eclipse/capella.ini``) T4C client must be available.
* In addition to the set of the common Capella plugins that are used at "Digitale
  Schiene Deutschland" there are other plugins needed and a list can be found on
  Confluence at
  https://rmt.jaas.service.deutschebahn.com/confluence/display/SSI/T4C+-+How+to+Script+Capella

Step 2
======

To get EASE doing the synchronisation for a model in T4C to GitLab:

The script will be run automatically when Capella is started in the workspace that has
been prepared (see above)

The following environment variables must be set:

* ``EASE_WORKSPACE`` (see step 2 from above)
* ``GIT_REPO_URL``
* ``GIT_REPO_BRANCH`` (e. g. ``nightly``)
* ``T4C_REPO_HOST`` (e.g. 10.107.242.175)
* ``T4C_REPO_PORT_NO`` (e.g. 2036)
* ``T4C_REPO_NAME``
* ``T4C_USERNAME``
* ``T4C_PASSWORD``

In the file ``capella.ini`` we need to set a JVM system property by ensuring the
following line some where in the ``.ini`` file:

.. code-block:: ini

    -Dorg.eclipse.swtbot.search.timeout=1000

Capella must then be started via:

.. code-block:: bash

    /path/to/capella -data $EASE_WORKSPACE

Capella will fire up and auto execute this script because of the magic comment
in line 1.

EASE will run through and shutdown Capella at the end.

"""
# Standard library:
import datetime
import os
import shutil
import subprocess
import sys
import typing as t
from pathlib import Path
from tempfile import gettempdir

MODULE_DIR: Path = Path(__file__).parents[0]

try:
    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402
except Exception:  # catching NameError does not work with EASE
    # Local modules are not found because EASE manipulates sys.path:
    # 3rd party:
    from eclipse.system.environment import getScriptEngine  # type: ignore

    MODULE_DIR = Path(str(getScriptEngine().getExecutedFile())).parent
    sys.path.insert(0, str(MODULE_DIR))

    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402

BOT: t.Any = ease.BOT
DEBUG = ease.DEBUG

logger = ease.logger
log_file_dir: Path = ease.workspace_path()
ease.log_to_file(
    log_file_path=os.environ.get("EASE_LOG_LOCATION", log_file_dir / "t4c2git.log")
)


def read_and_log_environment_variables() -> t.Tuple[str, ...]:
    """Read environment variables and log read values.

    Returns
    -------
    t.Tuple[str, ...]
        Tuple with variables that have been read from the environment

    """
    logger.info("Read parameters from environment variables...")
    git_repo_url: str = os.getenv("GIT_REPO_URL", "")
    git_repo_branch: str = os.getenv("GIT_REPO_BRANCH", "")
    t4c_repo_host: str = os.getenv("T4C_REPO_HOST", "")
    t4c_repo_port_no: str = os.getenv("T4C_REPO_PORT_NO", "")

    t4c_repo_name: str = os.getenv("T4C_REPO_NAME", "")
    t4c_project_name: str = os.getenv("T4C_PROJECT_NAME", "")

    t4c_username: str = os.getenv("T4C_USERNAME", "")
    t4c_password: str = os.getenv("T4C_PASSWORD", "")
    logger.info(f"\tGIT_REPO_URL         : '{git_repo_url}'")
    logger.info(f"\tGIT_REPO_BRANCH      : '{git_repo_branch}'")
    logger.info(f"\tT4C_REPO_HOST        : '{t4c_repo_host}'")
    logger.info(f"\tT4C_REPO_PORT_NO     : '{t4c_repo_port_no}'")
    logger.info(f"\tT4C_REPO_NAME        : '{t4c_repo_name}'")
    logger.info(f"\tT4C_PROJECT_NAME     : '{t4c_project_name}'")
    logger.info(f"\tT4C_USERNAME         : '{t4c_username}'")
    logger.info(
        "\tT4C_PASSWORD     : WILL NOT BE LOGGED HERE. Check env var 'T4C_PASSWORD'"
    )
    return (
        git_repo_url,
        git_repo_branch,
        t4c_repo_host,
        t4c_repo_port_no,
        t4c_repo_name,
        t4c_project_name,
        t4c_username,
        t4c_password,
    )


if __name__ == "__main__":
    ease.log_intro_messages()
    if BOT is None:
        raise exp.EaseNoSWTWorkbenchBotError
    (
        git_repo_url,
        git_repo_branch,
        t4c_repo_host,
        t4c_repo_port_no,
        t4c_repo_name,
        t4c_project_name,
        t4c_username,
        t4c_password,
infile
# onStartup: 0
"""EASE script to sync (one-directional) from a T4C Capella model to a Git model.

.. note::

    The module expects, that Eclipse/ Capella is set to English language.


.. seealso::

    The acronym EASE stands for "Eclipse Advanced Scripting Environment".
    Further information: https://www.eclipse.org/ease/

One can optionally set an environment variable named ``DEBUG`` to ``"1"`` to get
a debug level logging with more detailed information (module, function, line no).

Before this script can be run within an EASE context (see below), one must set an
environment variable named ``EASE_WORKSPACE`` pointing to a workspace directory that
will be created/ overwritten.

Then one executes the installed module ``pyease.ease.py`` using a Python3 interpreter to
create a workspace for the execution of Python EASE scripts:

.. code-block:: bash

    python3 -m pyease.ease


The script logs what it does into a log file named ``t4c2git.log`` in the workspace
defined in the environment variable ``EASE_WORKSPACE``.

How to run the current script in EASE is further described with step 2 below.

***************************************************
Three steps to get this Python module to do the job
***************************************************

Step 1
======

The following preconditions must be fulfilled on the computer running this module:

* A Python3 interpreter must be installed
* A Git client (including git-lfs) must be installed
* The current script must be available so that it can be executed
* A Capella client including a configured (license key
  ``DOBEO_LICENSE_SERVER_CONFIGURATION`` in the file
  ``/path/to/Capella/Contents/Eclipse/capella.ini``) T4C client must be available.
* In addition to the set of the common Capella plugins that are used at "Digitale
  Schiene Deutschland" there are other plugins needed and a list can be found on
  Confluence at
  https://rmt.jaas.service.deutschebahn.com/confluence/display/SSI/T4C+-+How+to+Script+Capella

Step 2
======

To get EASE doing the synchronisation for a model in T4C to GitLab:

The script will be run automatically when Capella is started in the workspace that has
been prepared (see above)

The following environment variables must be set:

* ``EASE_WORKSPACE`` (see step 2 from above)
* ``GIT_REPO_URL``
* ``GIT_REPO_BRANCH`` (e. g. ``nightly``)
* ``T4C_REPO_HOST`` (e.g. 10.107.242.175)
* ``T4C_REPO_PORT_NO`` (e.g. 2036)
* ``T4C_REPO_NAME``
* ``T4C_USERNAME``
* ``T4C_PASSWORD``

In the file ``capella.ini`` we need to set a JVM system property by ensuring the
following line some where in the ``.ini`` file:

.. code-block:: ini

    -Dorg.eclipse.swtbot.search.timeout=1000

Capella must then be started via:

.. code-block:: bash

    /path/to/capella -data $EASE_WORKSPACE

Capella will fire up and auto execute this script because of the magic comment
in line 1.

EASE will run through and shutdown Capella at the end.

"""
# Standard library:
import datetime
import os
import shutil
import subprocess
import sys
import typing as t
from pathlib import Path
from tempfile import gettempdir

MODULE_DIR: Path = Path(__file__).parents[0]

try:
    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402
except Exception:  # catching NameError does not work with EASE
    # Local modules are not found because EASE manipulates sys.path:
    # 3rd party:
    from eclipse.system.environment import getScriptEngine  # type: ignore

    MODULE_DIR = Path(str(getScriptEngine().getExecutedFile())).parent
    sys.path.insert(0, str(MODULE_DIR))

    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402

BOT: t.Any = ease.BOT
DEBUG = ease.DEBUG

logger = ease.logger
log_file_dir: Path = ease.workspace_path()
ease.log_to_file(
    log_file_path=os.environ.get("EASE_LOG_LOCATION", log_file_dir / "t4c2git.log")
)


def read_and_log_environment_variables() -> t.Tuple[str, ...]:
    """Read environment variables and log read values.

    Returns
    -------
    t.Tuple[str, ...]
        Tuple with variables that have been read from the environment

    """
    logger.info("Read parameters from environment variables...")
    git_repo_url: str = os.getenv("GIT_REPO_URL", "")
    git_repo_branch: str = os.getenv("GIT_REPO_BRANCH", "")
    t4c_repo_host: str = os.getenv("T4C_REPO_HOST", "")
    t4c_repo_port_no: str = os.getenv("T4C_REPO_PORT_NO", "")

    t4c_repo_name: str = os.getenv("T4C_REPO_NAME", "")
    t4c_project_name: str = os.getenv("T4C_PROJECT_NAME", "")

    t4c_username: str = os.getenv("T4C_USERNAME", "")
    t4c_password: str = os.getenv("T4C_PASSWORD", "")
    logger.info(f"\tGIT_REPO_URL         : '{git_repo_url}'")
    logger.info(f"\tGIT_REPO_BRANCH      : '{git_repo_branch}'")
    logger.info(f"\tT4C_REPO_HOST        : '{t4c_repo_host}'")
    logger.info(f"\tT4C_REPO_PORT_NO     : '{t4c_repo_port_no}'")
    logger.info(f"\tT4C_REPO_NAME        : '{t4c_repo_name}'")
    logger.info(f"\tT4C_PROJECT_NAME     : '{t4c_project_name}'")
    logger.info(f"\tT4C_USERNAME         : '{t4c_username}'")
    logger.info(
        "\tT4C_PASSWORD     : WILL NOT BE LOGGED HERE. Check env var 'T4C_PASSWORD'"
    )
    return (
        git_repo_url,
        git_repo_branch,
        t4c_repo_host,
        t4c_repo_port_no,
        t4c_repo_name,
        t4c_project_name,
        t4c_username,
        t4c_password,
    )


if __name__ == "__main__":
    ease.log_intro_messages()
    if BOT is None:
        raise exp.EaseNoSWTWorkbenchBotError
    (
        git_repo_url,
        git_repo_branch,
        t4c_repo_host,
        t4c_repo_port_no,
        t4c_repo_name,
        t4c_project_name,
        t4c_username,
        t4c_password,
    ) = read_and_log_environment_variables()

    logger.info(
        f"Name of project to one-way-synchronise (T4C to Git): '{t4c_project_name}'."
    )

    # When this script is run in a CI pipeline we want that generic exceptions
    # and the according traceback will be written into the log file.
    # Hence, the next try/ except block is a dirty hack to achieve that :-)
    try:
        # to have Capella GUI actions available:
        ease.open_eclipse_perspective("Capella")
        if DEBUG:
            # to have the view available for quick re-execution of this EASE script:
            ease.open_eclipse_view("Scripting", "Script Explorer")
            # to have the view in the foreground to look at logging output:
            ease.open_eclipse_view("General", "Console")

        tmp_git_clone_dir: Path = Path(gettempdir()) / t4c_project_name
        ease.import_model_from_remote_repository(
            t4c_repo_host=t4c_repo_host,
            t4c_repo_port_no=t4c_repo_port_no,
            t4c_repo_name=t4c_repo_name,
            t4c_project_name=t4c_project_name,
            t4c_username=t4c_username,
            t4c_password=t4c_password,
        )
        ease.clone_project_from_git(
            git_repo_url=git_repo_url,
            git_repo_branch=git_repo_branch,
            target_git_clone_dir=tmp_git_clone_dir,
            depth=None,
        )
        shutil.copytree(
            src=Path(f"/workspace/{t4c_project_name}"),
            dst=tmp_git_clone_dir,
            dirs_exist_ok=True,
        )
        try:
            cmd: list[str] = ["git", "add", "."]
            cmd_str: str = " ".join(cmd)
            logger.info(f"Execute command '{cmd_str}'...")
common
# onStartup: 0
"""EASE script to sync (one-directional) from a T4C Capella model to a Git model.

.. note::

    The module expects, that Eclipse/ Capella is set to English language.


.. seealso::

    The acronym EASE stands for "Eclipse Advanced Scripting Environment".
    Further information: https://www.eclipse.org/ease/

One can optionally set an environment variable named ``DEBUG`` to ``"1"`` to get
a debug level logging with more detailed information (module, function, line no).

Before this script can be run within an EASE context (see below), one must set an
environment variable named ``EASE_WORKSPACE`` pointing to a workspace directory that
will be created/ overwritten.

Then one executes the installed module ``pyease.ease.py`` using a Python3 interpreter to
create a workspace for the execution of Python EASE scripts:

.. code-block:: bash

    python3 -m pyease.ease


The script logs what it does into a log file named ``t4c2git.log`` in the workspace
defined in the environment variable ``EASE_WORKSPACE``.

How to run the current script in EASE is further described with step 2 below.

***************************************************
Three steps to get this Python module to do the job
***************************************************

Step 1
======

The following preconditions must be fulfilled on the computer running this module:

* A Python3 interpreter must be installed
* A Git client (including git-lfs) must be installed
* The current script must be available so that it can be executed
* A Capella client including a configured (license key
  ``DOBEO_LICENSE_SERVER_CONFIGURATION`` in the file
  ``/path/to/Capella/Contents/Eclipse/capella.ini``) T4C client must be available.
* In addition to the set of the common Capella plugins that are used at "Digitale
  Schiene Deutschland" there are other plugins needed and a list can be found on
  Confluence at
  https://rmt.jaas.service.deutschebahn.com/confluence/display/SSI/T4C+-+How+to+Script+Capella

Step 2
======

To get EASE doing the synchronisation for a model in T4C to GitLab:

The script will be run automatically when Capella is started in the workspace that has
been prepared (see above)

The following environment variables must be set:

* ``EASE_WORKSPACE`` (see step 2 from above)
* ``GIT_REPO_URL``
* ``GIT_REPO_BRANCH`` (e. g. ``nightly``)
* ``T4C_REPO_HOST`` (e.g. 10.107.242.175)
* ``T4C_REPO_PORT_NO`` (e.g. 2036)
* ``T4C_REPO_NAME``
* ``T4C_USERNAME``
* ``T4C_PASSWORD``

In the file ``capella.ini`` we need to set a JVM system property by ensuring the
following line some where in the ``.ini`` file:

.. code-block:: ini

    -Dorg.eclipse.swtbot.search.timeout=1000

Capella must then be started via:

.. code-block:: bash

    /path/to/capella -data $EASE_WORKSPACE

Capella will fire up and auto execute this script because of the magic comment
in line 1.

EASE will run through and shutdown Capella at the end.

"""
# Standard library:
import datetime
import os
import shutil
import subprocess
import sys
import typing as t
from pathlib import Path
from tempfile import gettempdir

MODULE_DIR: Path = Path(__file__).parents[0]

try:
    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402
except Exception:  # catching NameError does not work with EASE
    # Local modules are not found because EASE manipulates sys.path:
    # 3rd party:
    from eclipse.system.environment import getScriptEngine  # type: ignore

    MODULE_DIR = Path(str(getScriptEngine().getExecutedFile())).parent
    sys.path.insert(0, str(MODULE_DIR))

    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402

BOT: t.Any = ease.BOT
DEBUG = ease.DEBUG

logger = ease.logger
log_file_dir: Path = ease.workspace_path()
ease.log_to_file(
common
# onStartup: 0
"""EASE script to sync (one-directional) from a T4C Capella model to a Git model.

.. note::

    The module expects, that Eclipse/ Capella is set to English language.


.. seealso::

    The acronym EASE stands for "Eclipse Advanced Scripting Environment".
non_informative
non_informative
# onStartup: 0
"""EASE script to sync (one-directional) from a T4C Capella model to a Git model.

.. note::

    The module expects, that Eclipse/ Capella is set to English language.


.. seealso::

    The acronym EASE stands for "Eclipse Advanced Scripting Environment".
    Further information: https://www.eclipse.org/ease/

One can optionally set an environment variable named ``DEBUG`` to ``"1"`` to get
a debug level logging with more detailed information (module, function, line no).

Before this script can be run within an EASE context (see below), one must set an
environment variable named ``EASE_WORKSPACE`` pointing to a workspace directory that
will be created/ overwritten.

Then one executes the installed module ``pyease.ease.py`` using a Python3 interpreter to
non_informative
# onStartup: 0
"""EASE script to sync (one-directional) from a T4C Capella model to a Git model.

.. note::

    The module expects, that Eclipse/ Capella is set to English language.


.. seealso::

    The acronym EASE stands for "Eclipse Advanced Scripting Environment".
    Further information: https://www.eclipse.org/ease/

One can optionally set an environment variable named ``DEBUG`` to ``"1"`` to get
a debug level logging with more detailed information (module, function, line no).

Before this script can be run within an EASE context (see below), one must set an
environment variable named ``EASE_WORKSPACE`` pointing to a workspace directory that
will be created/ overwritten.

Then one executes the installed module ``pyease.ease.py`` using a Python3 interpreter to
create a workspace for the execution of Python EASE scripts:

.. code-block:: bash

    python3 -m pyease.ease


The script logs what it does into a log file named ``t4c2git.log`` in the workspace
defined in the environment variable ``EASE_WORKSPACE``.

How to run the current script in EASE is further described with step 2 below.

***************************************************
Three steps to get this Python module to do the job
***************************************************

Step 1
======

The following preconditions must be fulfilled on the computer running this module:

* A Python3 interpreter must be installed
* A Git client (including git-lfs) must be installed
* The current script must be available so that it can be executed
* A Capella client including a configured (license key
  ``DOBEO_LICENSE_SERVER_CONFIGURATION`` in the file
  ``/path/to/Capella/Contents/Eclipse/capella.ini``) T4C client must be available.
* In addition to the set of the common Capella plugins that are used at "Digitale
  Schiene Deutschland" there are other plugins needed and a list can be found on
  Confluence at
  https://rmt.jaas.service.deutschebahn.com/confluence/display/SSI/T4C+-+How+to+Script+Capella

Step 2
======

To get EASE doing the synchronisation for a model in T4C to GitLab:

The script will be run automatically when Capella is started in the workspace that has
been prepared (see above)

The following environment variables must be set:

* ``EASE_WORKSPACE`` (see step 2 from above)
* ``GIT_REPO_URL``
non_informative
# onStartup: 0
"""EASE script to sync (one-directional) from a T4C Capella model to a Git model.

.. note::

    The module expects, that Eclipse/ Capella is set to English language.


.. seealso::

    The acronym EASE stands for "Eclipse Advanced Scripting Environment".
    Further information: https://www.eclipse.org/ease/

One can optionally set an environment variable named ``DEBUG`` to ``"1"`` to get
a debug level logging with more detailed information (module, function, line no).

Before this script can be run within an EASE context (see below), one must set an
environment variable named ``EASE_WORKSPACE`` pointing to a workspace directory that
will be created/ overwritten.

Then one executes the installed module ``pyease.ease.py`` using a Python3 interpreter to
create a workspace for the execution of Python EASE scripts:

.. code-block:: bash

    python3 -m pyease.ease


The script logs what it does into a log file named ``t4c2git.log`` in the workspace
defined in the environment variable ``EASE_WORKSPACE``.

How to run the current script in EASE is further described with step 2 below.

***************************************************
Three steps to get this Python module to do the job
***************************************************

Step 1
======

The following preconditions must be fulfilled on the computer running this module:

* A Python3 interpreter must be installed
* A Git client (including git-lfs) must be installed
* The current script must be available so that it can be executed
* A Capella client including a configured (license key
  ``DOBEO_LICENSE_SERVER_CONFIGURATION`` in the file
  ``/path/to/Capella/Contents/Eclipse/capella.ini``) T4C client must be available.
* In addition to the set of the common Capella plugins that are used at "Digitale
  Schiene Deutschland" there are other plugins needed and a list can be found on
  Confluence at
  https://rmt.jaas.service.deutschebahn.com/confluence/display/SSI/T4C+-+How+to+Script+Capella

Step 2
======

To get EASE doing the synchronisation for a model in T4C to GitLab:

The script will be run automatically when Capella is started in the workspace that has
been prepared (see above)

The following environment variables must be set:

* ``EASE_WORKSPACE`` (see step 2 from above)
* ``GIT_REPO_URL``
* ``GIT_REPO_BRANCH`` (e. g. ``nightly``)
* ``T4C_REPO_HOST`` (e.g. 10.107.242.175)
* ``T4C_REPO_PORT_NO`` (e.g. 2036)
* ``T4C_REPO_NAME``
* ``T4C_USERNAME``
* ``T4C_PASSWORD``

In the file ``capella.ini`` we need to set a JVM system property by ensuring the
following line some where in the ``.ini`` file:

.. code-block:: ini

    -Dorg.eclipse.swtbot.search.timeout=1000

Capella must then be started via:

.. code-block:: bash

    /path/to/capella -data $EASE_WORKSPACE

Capella will fire up and auto execute this script because of the magic comment
in line 1.

EASE will run through and shutdown Capella at the end.

"""
# Standard library:
import datetime
import os
import shutil
import subprocess
import sys
import typing as t
from pathlib import Path
from tempfile import gettempdir

MODULE_DIR: Path = Path(__file__).parents[0]

try:
    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402
except Exception:  # catching NameError does not work with EASE
    # Local modules are not found because EASE manipulates sys.path:
    # 3rd party:
    from eclipse.system.environment import getScriptEngine  # type: ignore

    MODULE_DIR = Path(str(getScriptEngine().getExecutedFile())).parent
    sys.path.insert(0, str(MODULE_DIR))

    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402

BOT: t.Any = ease.BOT
DEBUG = ease.DEBUG

logger = ease.logger
log_file_dir: Path = ease.workspace_path()
ease.log_to_file(
    log_file_path=os.environ.get("EASE_LOG_LOCATION", log_file_dir / "t4c2git.log")
)


def read_and_log_environment_variables() -> t.Tuple[str, ...]:
    """Read environment variables and log read values.

    Returns
    -------
    t.Tuple[str, ...]
        Tuple with variables that have been read from the environment

    """
    logger.info("Read parameters from environment variables...")
    git_repo_url: str = os.getenv("GIT_REPO_URL", "")
    git_repo_branch: str = os.getenv("GIT_REPO_BRANCH", "")
    t4c_repo_host: str = os.getenv("T4C_REPO_HOST", "")
    t4c_repo_port_no: str = os.getenv("T4C_REPO_PORT_NO", "")

    t4c_repo_name: str = os.getenv("T4C_REPO_NAME", "")
    t4c_project_name: str = os.getenv("T4C_PROJECT_NAME", "")

    t4c_username: str = os.getenv("T4C_USERNAME", "")
    t4c_password: str = os.getenv("T4C_PASSWORD", "")
    logger.info(f"\tGIT_REPO_URL         : '{git_repo_url}'")
    logger.info(f"\tGIT_REPO_BRANCH      : '{git_repo_branch}'")
    logger.info(f"\tT4C_REPO_HOST        : '{t4c_repo_host}'")
    logger.info(f"\tT4C_REPO_PORT_NO     : '{t4c_repo_port_no}'")
    logger.info(f"\tT4C_REPO_NAME        : '{t4c_repo_name}'")
    logger.info(f"\tT4C_PROJECT_NAME     : '{t4c_project_name}'")
    logger.info(f"\tT4C_USERNAME         : '{t4c_username}'")
    logger.info(
        "\tT4C_PASSWORD     : WILL NOT BE LOGGED HERE. Check env var 'T4C_PASSWORD'"
    )
    return (
        git_repo_url,
        git_repo_branch,
        t4c_repo_host,
        t4c_repo_port_no,
        t4c_repo_name,
        t4c_project_name,
        t4c_username,
        t4c_password,
    )
non_informative
# onStartup: 0
"""EASE script to sync (one-directional) from a T4C Capella model to a Git model.

.. note::

    The module expects, that Eclipse/ Capella is set to English language.


.. seealso::

    The acronym EASE stands for "Eclipse Advanced Scripting Environment".
    Further information: https://www.eclipse.org/ease/

One can optionally set an environment variable named ``DEBUG`` to ``"1"`` to get
a debug level logging with more detailed information (module, function, line no).

Before this script can be run within an EASE context (see below), one must set an
environment variable named ``EASE_WORKSPACE`` pointing to a workspace directory that
will be created/ overwritten.

Then one executes the installed module ``pyease.ease.py`` using a Python3 interpreter to
create a workspace for the execution of Python EASE scripts:

.. code-block:: bash

    python3 -m pyease.ease


The script logs what it does into a log file named ``t4c2git.log`` in the workspace
defined in the environment variable ``EASE_WORKSPACE``.

How to run the current script in EASE is further described with step 2 below.

***************************************************
Three steps to get this Python module to do the job
***************************************************

Step 1
======

The following preconditions must be fulfilled on the computer running this module:

* A Python3 interpreter must be installed
* A Git client (including git-lfs) must be installed
* The current script must be available so that it can be executed
* A Capella client including a configured (license key
  ``DOBEO_LICENSE_SERVER_CONFIGURATION`` in the file
  ``/path/to/Capella/Contents/Eclipse/capella.ini``) T4C client must be available.
* In addition to the set of the common Capella plugins that are used at "Digitale
  Schiene Deutschland" there are other plugins needed and a list can be found on
  Confluence at
  https://rmt.jaas.service.deutschebahn.com/confluence/display/SSI/T4C+-+How+to+Script+Capella

Step 2
======

To get EASE doing the synchronisation for a model in T4C to GitLab:

The script will be run automatically when Capella is started in the workspace that has
been prepared (see above)

The following environment variables must be set:

* ``EASE_WORKSPACE`` (see step 2 from above)
* ``GIT_REPO_URL``
* ``GIT_REPO_BRANCH`` (e. g. ``nightly``)
* ``T4C_REPO_HOST`` (e.g. 10.107.242.175)
* ``T4C_REPO_PORT_NO`` (e.g. 2036)
* ``T4C_REPO_NAME``
* ``T4C_USERNAME``
* ``T4C_PASSWORD``

In the file ``capella.ini`` we need to set a JVM system property by ensuring the
following line some where in the ``.ini`` file:

.. code-block:: ini

    -Dorg.eclipse.swtbot.search.timeout=1000

Capella must then be started via:

.. code-block:: bash

    /path/to/capella -data $EASE_WORKSPACE

Capella will fire up and auto execute this script because of the magic comment
in line 1.

EASE will run through and shutdown Capella at the end.

"""
# Standard library:
import datetime
import os
import shutil
import subprocess
import sys
import typing as t
from pathlib import Path
from tempfile import gettempdir

MODULE_DIR: Path = Path(__file__).parents[0]

try:
    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402
except Exception:  # catching NameError does not work with EASE
    # Local modules are not found because EASE manipulates sys.path:
    # 3rd party:
    from eclipse.system.environment import getScriptEngine  # type: ignore

    MODULE_DIR = Path(str(getScriptEngine().getExecutedFile())).parent
    sys.path.insert(0, str(MODULE_DIR))

    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402

BOT: t.Any = ease.BOT
DEBUG = ease.DEBUG

logger = ease.logger
log_file_dir: Path = ease.workspace_path()
ease.log_to_file(
    log_file_path=os.environ.get("EASE_LOG_LOCATION", log_file_dir / "t4c2git.log")
)


def read_and_log_environment_variables() -> t.Tuple[str, ...]:
    """Read environment variables and log read values.

    Returns
    -------
    t.Tuple[str, ...]
        Tuple with variables that have been read from the environment

    """
    logger.info("Read parameters from environment variables...")
    git_repo_url: str = os.getenv("GIT_REPO_URL", "")
    git_repo_branch: str = os.getenv("GIT_REPO_BRANCH", "")
    t4c_repo_host: str = os.getenv("T4C_REPO_HOST", "")
    t4c_repo_port_no: str = os.getenv("T4C_REPO_PORT_NO", "")

    t4c_repo_name: str = os.getenv("T4C_REPO_NAME", "")
    t4c_project_name: str = os.getenv("T4C_PROJECT_NAME", "")

    t4c_username: str = os.getenv("T4C_USERNAME", "")
    t4c_password: str = os.getenv("T4C_PASSWORD", "")
    logger.info(f"\tGIT_REPO_URL         : '{git_repo_url}'")
    logger.info(f"\tGIT_REPO_BRANCH      : '{git_repo_branch}'")
    logger.info(f"\tT4C_REPO_HOST        : '{t4c_repo_host}'")
    logger.info(f"\tT4C_REPO_PORT_NO     : '{t4c_repo_port_no}'")
    logger.info(f"\tT4C_REPO_NAME        : '{t4c_repo_name}'")
    logger.info(f"\tT4C_PROJECT_NAME     : '{t4c_project_name}'")
    logger.info(f"\tT4C_USERNAME         : '{t4c_username}'")
    logger.info(
        "\tT4C_PASSWORD     : WILL NOT BE LOGGED HERE. Check env var 'T4C_PASSWORD'"
    )
    return (
        git_repo_url,
        git_repo_branch,
        t4c_repo_host,
        t4c_repo_port_no,
        t4c_repo_name,
        t4c_project_name,
        t4c_username,
        t4c_password,
    )


if __name__ == "__main__":
    ease.log_intro_messages()
    if BOT is None:
        raise exp.EaseNoSWTWorkbenchBotError
    (
        git_repo_url,
        git_repo_branch,
        t4c_repo_host,
random
# onStartup: 0
"""EASE script to sync (one-directional) from a T4C Capella model to a Git model.

.. note::

    The module expects, that Eclipse/ Capella is set to English language.


.. seealso::

    The acronym EASE stands for "Eclipse Advanced Scripting Environment".
    Further information: https://www.eclipse.org/ease/

One can optionally set an environment variable named ``DEBUG`` to ``"1"`` to get
a debug level logging with more detailed information (module, function, line no).

Before this script can be run within an EASE context (see below), one must set an
environment variable named ``EASE_WORKSPACE`` pointing to a workspace directory that
will be created/ overwritten.

Then one executes the installed module ``pyease.ease.py`` using a Python3 interpreter to
create a workspace for the execution of Python EASE scripts:

.. code-block:: bash

    python3 -m pyease.ease


The script logs what it does into a log file named ``t4c2git.log`` in the workspace
defined in the environment variable ``EASE_WORKSPACE``.

How to run the current script in EASE is further described with step 2 below.

***************************************************
Three steps to get this Python module to do the job
***************************************************

Step 1
======

The following preconditions must be fulfilled on the computer running this module:

* A Python3 interpreter must be installed
* A Git client (including git-lfs) must be installed
* The current script must be available so that it can be executed
* A Capella client including a configured (license key
  ``DOBEO_LICENSE_SERVER_CONFIGURATION`` in the file
  ``/path/to/Capella/Contents/Eclipse/capella.ini``) T4C client must be available.
* In addition to the set of the common Capella plugins that are used at "Digitale
  Schiene Deutschland" there are other plugins needed and a list can be found on
  Confluence at
  https://rmt.jaas.service.deutschebahn.com/confluence/display/SSI/T4C+-+How+to+Script+Capella

Step 2
======

To get EASE doing the synchronisation for a model in T4C to GitLab:

The script will be run automatically when Capella is started in the workspace that has
been prepared (see above)

The following environment variables must be set:

* ``EASE_WORKSPACE`` (see step 2 from above)
* ``GIT_REPO_URL``
* ``GIT_REPO_BRANCH`` (e. g. ``nightly``)
* ``T4C_REPO_HOST`` (e.g. 10.107.242.175)
* ``T4C_REPO_PORT_NO`` (e.g. 2036)
* ``T4C_REPO_NAME``
* ``T4C_USERNAME``
* ``T4C_PASSWORD``

In the file ``capella.ini`` we need to set a JVM system property by ensuring the
following line some where in the ``.ini`` file:

.. code-block:: ini

    -Dorg.eclipse.swtbot.search.timeout=1000

Capella must then be started via:

.. code-block:: bash

    /path/to/capella -data $EASE_WORKSPACE

Capella will fire up and auto execute this script because of the magic comment
in line 1.

EASE will run through and shutdown Capella at the end.

"""
# Standard library:
import datetime
import os
import shutil
import subprocess
import sys
import typing as t
from pathlib import Path
from tempfile import gettempdir

MODULE_DIR: Path = Path(__file__).parents[0]

try:
    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402
except Exception:  # catching NameError does not work with EASE
    # Local modules are not found because EASE manipulates sys.path:
    # 3rd party:
    from eclipse.system.environment import getScriptEngine  # type: ignore

    MODULE_DIR = Path(str(getScriptEngine().getExecutedFile())).parent
    sys.path.insert(0, str(MODULE_DIR))

    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402

BOT: t.Any = ease.BOT
DEBUG = ease.DEBUG

logger = ease.logger
log_file_dir: Path = ease.workspace_path()
ease.log_to_file(
    log_file_path=os.environ.get("EASE_LOG_LOCATION", log_file_dir / "t4c2git.log")
)


def read_and_log_environment_variables() -> t.Tuple[str, ...]:
    """Read environment variables and log read values.

    Returns
    -------
    t.Tuple[str, ...]
        Tuple with variables that have been read from the environment

    """
    logger.info("Read parameters from environment variables...")
    git_repo_url: str = os.getenv("GIT_REPO_URL", "")
    git_repo_branch: str = os.getenv("GIT_REPO_BRANCH", "")
    t4c_repo_host: str = os.getenv("T4C_REPO_HOST", "")
    t4c_repo_port_no: str = os.getenv("T4C_REPO_PORT_NO", "")

    t4c_repo_name: str = os.getenv("T4C_REPO_NAME", "")
    t4c_project_name: str = os.getenv("T4C_PROJECT_NAME", "")

    t4c_username: str = os.getenv("T4C_USERNAME", "")
    t4c_password: str = os.getenv("T4C_PASSWORD", "")
    logger.info(f"\tGIT_REPO_URL         : '{git_repo_url}'")
    logger.info(f"\tGIT_REPO_BRANCH      : '{git_repo_branch}'")
    logger.info(f"\tT4C_REPO_HOST        : '{t4c_repo_host}'")
    logger.info(f"\tT4C_REPO_PORT_NO     : '{t4c_repo_port_no}'")
    logger.info(f"\tT4C_REPO_NAME        : '{t4c_repo_name}'")
    logger.info(f"\tT4C_PROJECT_NAME     : '{t4c_project_name}'")
    logger.info(f"\tT4C_USERNAME         : '{t4c_username}'")
    logger.info(
        "\tT4C_PASSWORD     : WILL NOT BE LOGGED HERE. Check env var 'T4C_PASSWORD'"
    )
    return (
        git_repo_url,
        git_repo_branch,
        t4c_repo_host,
        t4c_repo_port_no,
        t4c_repo_name,
        t4c_project_name,
        t4c_username,
        t4c_password,
    )


if __name__ == "__main__":
    ease.log_intro_messages()
    if BOT is None:
random
# onStartup: 0
"""EASE script to sync (one-directional) from a T4C Capella model to a Git model.

.. note::

    The module expects, that Eclipse/ Capella is set to English language.


.. seealso::

    The acronym EASE stands for "Eclipse Advanced Scripting Environment".
    Further information: https://www.eclipse.org/ease/

One can optionally set an environment variable named ``DEBUG`` to ``"1"`` to get
a debug level logging with more detailed information (module, function, line no).

Before this script can be run within an EASE context (see below), one must set an
environment variable named ``EASE_WORKSPACE`` pointing to a workspace directory that
will be created/ overwritten.

Then one executes the installed module ``pyease.ease.py`` using a Python3 interpreter to
create a workspace for the execution of Python EASE scripts:

.. code-block:: bash

    python3 -m pyease.ease


The script logs what it does into a log file named ``t4c2git.log`` in the workspace
defined in the environment variable ``EASE_WORKSPACE``.

How to run the current script in EASE is further described with step 2 below.

***************************************************
Three steps to get this Python module to do the job
***************************************************

Step 1
======

The following preconditions must be fulfilled on the computer running this module:

* A Python3 interpreter must be installed
* A Git client (including git-lfs) must be installed
* The current script must be available so that it can be executed
* A Capella client including a configured (license key
  ``DOBEO_LICENSE_SERVER_CONFIGURATION`` in the file
  ``/path/to/Capella/Contents/Eclipse/capella.ini``) T4C client must be available.
* In addition to the set of the common Capella plugins that are used at "Digitale
  Schiene Deutschland" there are other plugins needed and a list can be found on
  Confluence at
  https://rmt.jaas.service.deutschebahn.com/confluence/display/SSI/T4C+-+How+to+Script+Capella

Step 2
======

To get EASE doing the synchronisation for a model in T4C to GitLab:

The script will be run automatically when Capella is started in the workspace that has
been prepared (see above)

The following environment variables must be set:

* ``EASE_WORKSPACE`` (see step 2 from above)
* ``GIT_REPO_URL``
* ``GIT_REPO_BRANCH`` (e. g. ``nightly``)
* ``T4C_REPO_HOST`` (e.g. 10.107.242.175)
* ``T4C_REPO_PORT_NO`` (e.g. 2036)
* ``T4C_REPO_NAME``
* ``T4C_USERNAME``
* ``T4C_PASSWORD``

In the file ``capella.ini`` we need to set a JVM system property by ensuring the
following line some where in the ``.ini`` file:

.. code-block:: ini

    -Dorg.eclipse.swtbot.search.timeout=1000

Capella must then be started via:

.. code-block:: bash

    /path/to/capella -data $EASE_WORKSPACE

Capella will fire up and auto execute this script because of the magic comment
in line 1.

EASE will run through and shutdown Capella at the end.

"""
# Standard library:
import datetime
import os
import shutil
import subprocess
import sys
import typing as t
from pathlib import Path
from tempfile import gettempdir

MODULE_DIR: Path = Path(__file__).parents[0]

try:
    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402
except Exception:  # catching NameError does not work with EASE
    # Local modules are not found because EASE manipulates sys.path:
    # 3rd party:
    from eclipse.system.environment import getScriptEngine  # type: ignore

    MODULE_DIR = Path(str(getScriptEngine().getExecutedFile())).parent
    sys.path.insert(0, str(MODULE_DIR))

    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402

BOT: t.Any = ease.BOT
DEBUG = ease.DEBUG

logger = ease.logger
log_file_dir: Path = ease.workspace_path()
ease.log_to_file(
    log_file_path=os.environ.get("EASE_LOG_LOCATION", log_file_dir / "t4c2git.log")
)


def read_and_log_environment_variables() -> t.Tuple[str, ...]:
    """Read environment variables and log read values.

    Returns
    -------
    t.Tuple[str, ...]
        Tuple with variables that have been read from the environment

    """
    logger.info("Read parameters from environment variables...")
    git_repo_url: str = os.getenv("GIT_REPO_URL", "")
    git_repo_branch: str = os.getenv("GIT_REPO_BRANCH", "")
    t4c_repo_host: str = os.getenv("T4C_REPO_HOST", "")
    t4c_repo_port_no: str = os.getenv("T4C_REPO_PORT_NO", "")

    t4c_repo_name: str = os.getenv("T4C_REPO_NAME", "")
    t4c_project_name: str = os.getenv("T4C_PROJECT_NAME", "")

    t4c_username: str = os.getenv("T4C_USERNAME", "")
    t4c_password: str = os.getenv("T4C_PASSWORD", "")
    logger.info(f"\tGIT_REPO_URL         : '{git_repo_url}'")
    logger.info(f"\tGIT_REPO_BRANCH      : '{git_repo_branch}'")
    logger.info(f"\tT4C_REPO_HOST        : '{t4c_repo_host}'")
    logger.info(f"\tT4C_REPO_PORT_NO     : '{t4c_repo_port_no}'")
    logger.info(f"\tT4C_REPO_NAME        : '{t4c_repo_name}'")
    logger.info(f"\tT4C_PROJECT_NAME     : '{t4c_project_name}'")
    logger.info(f"\tT4C_USERNAME         : '{t4c_username}'")
    logger.info(
        "\tT4C_PASSWORD     : WILL NOT BE LOGGED HERE. Check env var 'T4C_PASSWORD'"
    )
    return (
        git_repo_url,
        git_repo_branch,
        t4c_repo_host,
        t4c_repo_port_no,
        t4c_repo_name,
        t4c_project_name,
        t4c_username,
        t4c_password,
    )


if __name__ == "__main__":
    ease.log_intro_messages()
    if BOT is None:
        raise exp.EaseNoSWTWorkbenchBotError
    (
        git_repo_url,
        git_repo_branch,
        t4c_repo_host,
        t4c_repo_port_no,
        t4c_repo_name,
        t4c_project_name,
        t4c_username,
        t4c_password,
    ) = read_and_log_environment_variables()

    logger.info(
        f"Name of project to one-way-synchronise (T4C to Git): '{t4c_project_name}'."
    )

    # When this script is run in a CI pipeline we want that generic exceptions
    # and the according traceback will be written into the log file.
    # Hence, the next try/ except block is a dirty hack to achieve that :-)
    try:
        # to have Capella GUI actions available:
        ease.open_eclipse_perspective("Capella")
        if DEBUG:
            # to have the view available for quick re-execution of this EASE script:
            ease.open_eclipse_view("Scripting", "Script Explorer")
            # to have the view in the foreground to look at logging output:
            ease.open_eclipse_view("General", "Console")

        tmp_git_clone_dir: Path = Path(gettempdir()) / t4c_project_name
        ease.import_model_from_remote_repository(
            t4c_repo_host=t4c_repo_host,
            t4c_repo_port_no=t4c_repo_port_no,
            t4c_repo_name=t4c_repo_name,
            t4c_project_name=t4c_project_name,
            t4c_username=t4c_username,
            t4c_password=t4c_password,
        )
        ease.clone_project_from_git(
            git_repo_url=git_repo_url,
            git_repo_branch=git_repo_branch,
            target_git_clone_dir=tmp_git_clone_dir,
            depth=None,
        )
        shutil.copytree(
            src=Path(f"/workspace/{t4c_project_name}"),
            dst=tmp_git_clone_dir,
            dirs_exist_ok=True,
        )
random
# onStartup: 0
"""EASE script to sync (one-directional) from a T4C Capella model to a Git model.

.. note::

    The module expects, that Eclipse/ Capella is set to English language.


.. seealso::

    The acronym EASE stands for "Eclipse Advanced Scripting Environment".
    Further information: https://www.eclipse.org/ease/

One can optionally set an environment variable named ``DEBUG`` to ``"1"`` to get
a debug level logging with more detailed information (module, function, line no).

Before this script can be run within an EASE context (see below), one must set an
environment variable named ``EASE_WORKSPACE`` pointing to a workspace directory that
will be created/ overwritten.

Then one executes the installed module ``pyease.ease.py`` using a Python3 interpreter to
create a workspace for the execution of Python EASE scripts:

.. code-block:: bash

    python3 -m pyease.ease


The script logs what it does into a log file named ``t4c2git.log`` in the workspace
defined in the environment variable ``EASE_WORKSPACE``.

How to run the current script in EASE is further described with step 2 below.

***************************************************
Three steps to get this Python module to do the job
***************************************************

Step 1
======

The following preconditions must be fulfilled on the computer running this module:

* A Python3 interpreter must be installed
* A Git client (including git-lfs) must be installed
* The current script must be available so that it can be executed
* A Capella client including a configured (license key
  ``DOBEO_LICENSE_SERVER_CONFIGURATION`` in the file
  ``/path/to/Capella/Contents/Eclipse/capella.ini``) T4C client must be available.
* In addition to the set of the common Capella plugins that are used at "Digitale
  Schiene Deutschland" there are other plugins needed and a list can be found on
  Confluence at
  https://rmt.jaas.service.deutschebahn.com/confluence/display/SSI/T4C+-+How+to+Script+Capella

Step 2
======

To get EASE doing the synchronisation for a model in T4C to GitLab:

The script will be run automatically when Capella is started in the workspace that has
been prepared (see above)

The following environment variables must be set:

* ``EASE_WORKSPACE`` (see step 2 from above)
* ``GIT_REPO_URL``
* ``GIT_REPO_BRANCH`` (e. g. ``nightly``)
* ``T4C_REPO_HOST`` (e.g. 10.107.242.175)
* ``T4C_REPO_PORT_NO`` (e.g. 2036)
* ``T4C_REPO_NAME``
* ``T4C_USERNAME``
* ``T4C_PASSWORD``

In the file ``capella.ini`` we need to set a JVM system property by ensuring the
following line some where in the ``.ini`` file:

.. code-block:: ini

    -Dorg.eclipse.swtbot.search.timeout=1000

Capella must then be started via:

.. code-block:: bash

    /path/to/capella -data $EASE_WORKSPACE

Capella will fire up and auto execute this script because of the magic comment
in line 1.

EASE will run through and shutdown Capella at the end.

"""
# Standard library:
import datetime
import os
import shutil
import subprocess
import sys
import typing as t
from pathlib import Path
from tempfile import gettempdir

MODULE_DIR: Path = Path(__file__).parents[0]

try:
    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402
except Exception:  # catching NameError does not work with EASE
    # Local modules are not found because EASE manipulates sys.path:
    # 3rd party:
    from eclipse.system.environment import getScriptEngine  # type: ignore

    MODULE_DIR = Path(str(getScriptEngine().getExecutedFile())).parent
    sys.path.insert(0, str(MODULE_DIR))

    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402

BOT: t.Any = ease.BOT
DEBUG = ease.DEBUG

logger = ease.logger
log_file_dir: Path = ease.workspace_path()
ease.log_to_file(
    log_file_path=os.environ.get("EASE_LOG_LOCATION", log_file_dir / "t4c2git.log")
)


def read_and_log_environment_variables() -> t.Tuple[str, ...]:
    """Read environment variables and log read values.

    Returns
    -------
    t.Tuple[str, ...]
        Tuple with variables that have been read from the environment

    """
    logger.info("Read parameters from environment variables...")
    git_repo_url: str = os.getenv("GIT_REPO_URL", "")
    git_repo_branch: str = os.getenv("GIT_REPO_BRANCH", "")
    t4c_repo_host: str = os.getenv("T4C_REPO_HOST", "")
    t4c_repo_port_no: str = os.getenv("T4C_REPO_PORT_NO", "")

    t4c_repo_name: str = os.getenv("T4C_REPO_NAME", "")
    t4c_project_name: str = os.getenv("T4C_PROJECT_NAME", "")

    t4c_username: str = os.getenv("T4C_USERNAME", "")
    t4c_password: str = os.getenv("T4C_PASSWORD", "")
    logger.info(f"\tGIT_REPO_URL         : '{git_repo_url}'")
    logger.info(f"\tGIT_REPO_BRANCH      : '{git_repo_branch}'")
    logger.info(f"\tT4C_REPO_HOST        : '{t4c_repo_host}'")
    logger.info(f"\tT4C_REPO_PORT_NO     : '{t4c_repo_port_no}'")
    logger.info(f"\tT4C_REPO_NAME        : '{t4c_repo_name}'")
    logger.info(f"\tT4C_PROJECT_NAME     : '{t4c_project_name}'")
    logger.info(f"\tT4C_USERNAME         : '{t4c_username}'")
    logger.info(
        "\tT4C_PASSWORD     : WILL NOT BE LOGGED HERE. Check env var 'T4C_PASSWORD'"
    )
    return (
        git_repo_url,
        git_repo_branch,
        t4c_repo_host,
        t4c_repo_port_no,
        t4c_repo_name,
        t4c_project_name,
        t4c_username,
        t4c_password,
    )


if __name__ == "__main__":
    ease.log_intro_messages()
    if BOT is None:
        raise exp.EaseNoSWTWorkbenchBotError
    (
        git_repo_url,
        git_repo_branch,
        t4c_repo_host,
        t4c_repo_port_no,
        t4c_repo_name,
        t4c_project_name,
        t4c_username,
        t4c_password,
    ) = read_and_log_environment_variables()

    logger.info(
        f"Name of project to one-way-synchronise (T4C to Git): '{t4c_project_name}'."
    )

    # When this script is run in a CI pipeline we want that generic exceptions
    # and the according traceback will be written into the log file.
    # Hence, the next try/ except block is a dirty hack to achieve that :-)
    try:
        # to have Capella GUI actions available:
random
# onStartup: 0
"""EASE script to sync (one-directional) from a T4C Capella model to a Git model.

.. note::

    The module expects, that Eclipse/ Capella is set to English language.


.. seealso::

    The acronym EASE stands for "Eclipse Advanced Scripting Environment".
    Further information: https://www.eclipse.org/ease/

One can optionally set an environment variable named ``DEBUG`` to ``"1"`` to get
a debug level logging with more detailed information (module, function, line no).

Before this script can be run within an EASE context (see below), one must set an
environment variable named ``EASE_WORKSPACE`` pointing to a workspace directory that
will be created/ overwritten.

Then one executes the installed module ``pyease.ease.py`` using a Python3 interpreter to
create a workspace for the execution of Python EASE scripts:

.. code-block:: bash

    python3 -m pyease.ease


The script logs what it does into a log file named ``t4c2git.log`` in the workspace
defined in the environment variable ``EASE_WORKSPACE``.

How to run the current script in EASE is further described with step 2 below.

***************************************************
Three steps to get this Python module to do the job
***************************************************

Step 1
======

The following preconditions must be fulfilled on the computer running this module:

* A Python3 interpreter must be installed
* A Git client (including git-lfs) must be installed
* The current script must be available so that it can be executed
* A Capella client including a configured (license key
  ``DOBEO_LICENSE_SERVER_CONFIGURATION`` in the file
  ``/path/to/Capella/Contents/Eclipse/capella.ini``) T4C client must be available.
* In addition to the set of the common Capella plugins that are used at "Digitale
  Schiene Deutschland" there are other plugins needed and a list can be found on
  Confluence at
  https://rmt.jaas.service.deutschebahn.com/confluence/display/SSI/T4C+-+How+to+Script+Capella

Step 2
======

To get EASE doing the synchronisation for a model in T4C to GitLab:

The script will be run automatically when Capella is started in the workspace that has
been prepared (see above)

The following environment variables must be set:

* ``EASE_WORKSPACE`` (see step 2 from above)
* ``GIT_REPO_URL``
* ``GIT_REPO_BRANCH`` (e. g. ``nightly``)
* ``T4C_REPO_HOST`` (e.g. 10.107.242.175)
* ``T4C_REPO_PORT_NO`` (e.g. 2036)
* ``T4C_REPO_NAME``
* ``T4C_USERNAME``
* ``T4C_PASSWORD``

In the file ``capella.ini`` we need to set a JVM system property by ensuring the
following line some where in the ``.ini`` file:

.. code-block:: ini

    -Dorg.eclipse.swtbot.search.timeout=1000

Capella must then be started via:

.. code-block:: bash

    /path/to/capella -data $EASE_WORKSPACE

Capella will fire up and auto execute this script because of the magic comment
in line 1.

EASE will run through and shutdown Capella at the end.

"""
# Standard library:
import datetime
import os
import shutil
import subprocess
import sys
import typing as t
from pathlib import Path
from tempfile import gettempdir

MODULE_DIR: Path = Path(__file__).parents[0]

try:
    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402
except Exception:  # catching NameError does not work with EASE
    # Local modules are not found because EASE manipulates sys.path:
    # 3rd party:
    from eclipse.system.environment import getScriptEngine  # type: ignore

    MODULE_DIR = Path(str(getScriptEngine().getExecutedFile())).parent
    sys.path.insert(0, str(MODULE_DIR))

    # 1st party:
    import pyease.ease as ease  # noqa: E402
    import pyease.easeexceptions as exp  # noqa: E402

BOT: t.Any = ease.BOT
DEBUG = ease.DEBUG

logger = ease.logger
log_file_dir: Path = ease.workspace_path()
ease.log_to_file(
    log_file_path=os.environ.get("EASE_LOG_LOCATION", log_file_dir / "t4c2git.log")
)


def read_and_log_environment_variables() -> t.Tuple[str, ...]:
    """Read environment variables and log read values.

    Returns
    -------
    t.Tuple[str, ...]
        Tuple with variables that have been read from the environment

    """
    logger.info("Read parameters from environment variables...")
    git_repo_url: str = os.getenv("GIT_REPO_URL", "")
    git_repo_branch: str = os.getenv("GIT_REPO_BRANCH", "")
    t4c_repo_host: str = os.getenv("T4C_REPO_HOST", "")
    t4c_repo_port_no: str = os.getenv("T4C_REPO_PORT_NO", "")

    t4c_repo_name: str = os.getenv("T4C_REPO_NAME", "")
    t4c_project_name: str = os.getenv("T4C_PROJECT_NAME", "")

    t4c_username: str = os.getenv("T4C_USERNAME", "")
    t4c_password: str = os.getenv("T4C_PASSWORD", "")
    logger.info(f"\tGIT_REPO_URL         : '{git_repo_url}'")
    logger.info(f"\tGIT_REPO_BRANCH      : '{git_repo_branch}'")
    logger.info(f"\tT4C_REPO_HOST        : '{t4c_repo_host}'")
    logger.info(f"\tT4C_REPO_PORT_NO     : '{t4c_repo_port_no}'")
    logger.info(f"\tT4C_REPO_NAME        : '{t4c_repo_name}'")
    logger.info(f"\tT4C_PROJECT_NAME     : '{t4c_project_name}'")
    logger.info(f"\tT4C_USERNAME         : '{t4c_username}'")
    logger.info(
        "\tT4C_PASSWORD     : WILL NOT BE LOGGED HERE. Check env var 'T4C_PASSWORD'"
    )
    return (
        git_repo_url,
        git_repo_branch,
        t4c_repo_host,
        t4c_repo_port_no,
        t4c_repo_name,
        t4c_project_name,
        t4c_username,
        t4c_password,
    )


if __name__ == "__main__":
    ease.log_intro_messages()
    if BOT is None:
        raise exp.EaseNoSWTWorkbenchBotError
    (
        git_repo_url,
        git_repo_branch,
        t4c_repo_host,
        t4c_repo_port_no,
        t4c_repo_name,
        t4c_project_name,
        t4c_username,
        t4c_password,
    ) = read_and_log_environment_variables()

    logger.info(
        f"Name of project to one-way-synchronise (T4C to Git): '{t4c_project_name}'."
    )

    # When this script is run in a CI pipeline we want that generic exceptions
    # and the according traceback will be written into the log file.
    # Hence, the next try/ except block is a dirty hack to achieve that :-)
    try:
        # to have Capella GUI actions available:
        ease.open_eclipse_perspective("Capella")
        if DEBUG:
            # to have the view available for quick re-execution of this EASE script:
            ease.open_eclipse_view("Scripting", "Script Explorer")
            # to have the view in the foreground to look at logging output:
            ease.open_eclipse_view("General", "Console")

        tmp_git_clone_dir: Path = Path(gettempdir()) / t4c_project_name
        ease.import_model_from_remote_repository(
            t4c_repo_host=t4c_repo_host,
            t4c_repo_port_no=t4c_repo_port_no,
            t4c_repo_name=t4c_repo_name,
            t4c_project_name=t4c_project_name,
            t4c_username=t4c_username,
            t4c_password=t4c_password,
        )
        ease.clone_project_from_git(
            git_repo_url=git_repo_url,
            git_repo_branch=git_repo_branch,
            target_git_clone_dir=tmp_git_clone_dir,
            depth=None,
        )
        shutil.copytree(
            src=Path(f"/workspace/{t4c_project_name}"),
            dst=tmp_git_clone_dir,
            dirs_exist_ok=True,
random
    ) = read_and_log_environment_variables()             subprocess.run(     log_file_path=os.environ.get("EASE_LOG_LOCATION", log_file_dir / "t4c2git.log")     Further information: https://www.eclipse.org/ease/ # onStartup: 0 create a workspace for the execution of Python EASE scripts: * ``GIT_REPO_BRANCH`` (e. g. ``nightly``)         t4c_repo_port_no,         raise exp.EaseNoSWTWorkbenchBotError         try:         ease.open_eclipse_perspective("Capella")         )