Skip to content

Commit

Permalink
SRT Release (#1728)
Browse files Browse the repository at this point in the history
* Add the route changes (#1723)

Co-authored-by: RiteshHMCTS <[email protected]>

* update library to fix vulnerabilities (#1658)

* update library to fix vulnerabilities

update library to fix vulnerabilities

Upgrade of ng-packagr to latest version highlighted. Fixed issue
 with Property 'formGroup' will overwrite the base property in 'AbstractFieldWriteComponent'.palette/complex/write-complex-field.component.ts, palette/collection/write-collection-field.component.ts,
palette/case-flag/write-case-flag-field.component.ts, /palette/address/write-address-field.component.ts

* Update npmpublish.yml

* update nicky-lenaers/ngx-scroll-to

* updated ngx-pagination

* update ngx-md

* revert update to pagination-controls and ngx-md

* update library and fixed failing test

* update ngx-md

* Update package.json

* code tidy

* package version update

* change ng-packagr version

* update

* revert to version 15.2.2

* version update

* update ng-packagr to version ^17.3.0

* debug issue

* testing

* ng-packagr 16.2.3

* cve update

* testing

* Update search-result.module.ts

* Update tsconfig.json

* Update yarn-audit-known-issues

* update package.json

* update package.json

* Update tsconfig.json

* Update yarn.lock

* fix sonar issue

---------

Co-authored-by: RiteshHMCTS <[email protected]>

* EXUI-1695 - Add function to check DynamicMultiSelectList has list_items (#1714)

* Add function to check DynamicMultiSelectList has list_items

* Update version name, Add unit test for new function, Change IF statement to Ternary in ensureDynamicMultiSelectListPopulated

* Add tests for field-type-sanitiser, fix for CYA page not showing dynamicMultiSelectList

---------

Co-authored-by: RiteshHMCTS <[email protected]>

* version updated

* version updated

* Fix/ex UI 330 markdown security (#1707)

* fix: sanitise markdown links on input and textarea

* Update form-validators.service.ts

* Update form-validators.service.ts

* updated regex based on sonarcloud recommendation

* Code update

* version update

* code tidy

* optimise regex

* revert back regex pattern

* fix: resolved issue with validator not working correctly

* Fix issue to broken test

* version update

* Update yarn-audit-known-issues

* Update form-validators.service.ts

* return url to text without turning it into a link

* version update

* update package.json

* Update yarn.lock

* Revert "update package.json"

* version update

* Add error handling (#1681)

* Add error handling

* First additional test change

* Add additional test

* Add additional test

---------

Co-authored-by: RiteshHMCTS <[email protected]>

* exui-1184 (#1670)

* exui-1184

* exui-1184

* exui-1184

* revert changes

* revert changes

* remove hidden pages fields from fromgroup

* rectified change

* rectified the code

* version updated

* Make accessibility change (#1701)

* Make accessibility change

* Update case-file-view-folder.component.html

* Update case-full-access-view.component.html

---------

Co-authored-by: RiteshHMCTS <[email protected]>

* document upload error reworked (#1689)

* document upload error reworked

* code review comment fix

* changed return message

* version number change

* added msg as constant

* error return

---------

Co-authored-by: RiteshHMCTS <[email protected]>

* Task/1194 security issue (#1687)

* error message added for rate limit for document uploads

* Update http-error.model.ts

* Update http-error.model.spec.ts

* version set to  "7.0.13",

* commented out code causing issue

* testing the changes

* cev update

* Update yarn-audit-known-issues

* Update write-document-field.component.ts

---------

Co-authored-by: Ritesh Dsouza <[email protected]>

* version updated

* unit test coverage

* more unit test

* unit test

* fixed issue with component not rendering internal links.

* version 7.0.23-pre-release-markdown

* fixed sonar issue

* Fix external link issue

* Update markdown.component.ts

* Update sonar-project.properties

---------

Co-authored-by: connorpgpmcelroy <[email protected]>
Co-authored-by: RiteshHMCTS <[email protected]>
Co-authored-by: OgunyemiO <[email protected]>
Co-authored-by: Ritesh Dsouza <[email protected]>
Co-authored-by: OgunyemiO <[email protected]>

* version updated

* Update form-validators.service.ts (#1732)

* version updated

* version updated

---------

Co-authored-by: connorpgpmcelroy <[email protected]>
Co-authored-by: Olu <[email protected]>
Co-authored-by: Josh-HMCTS <[email protected]>
Co-authored-by: OgunyemiO <[email protected]>
Co-authored-by: OgunyemiO <[email protected]>
  • Loading branch information
6 people authored May 30, 2024
1 parent 9c457e1 commit ab6c774
Show file tree
Hide file tree
Showing 51 changed files with 2,876 additions and 2,875 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hmcts/ccd-case-ui-toolkit",
"version": "7.0.37",
"version": "7.0.38",
"engines": {
"node": ">=18.17.0"
},
Expand Down Expand Up @@ -75,7 +75,7 @@
"govuk-frontend": "^4.2.0",
"json-server": "^0.15.1",
"lz-string": "^1.5.0",
"marked": "^0.7.0",
"marked": "^12.0.0",
"mem": "^6.0.0",
"minimist": "1.2.3",
"moment": "^2.29.1",
Expand Down Expand Up @@ -164,7 +164,7 @@
"mocha": "^8.1.1",
"multidep": "2.0.2",
"ng-mocks": "^14.1.1",
"ng-packagr": "^14.2.2",
"ng-packagr": "15.2.2",
"ng2-mock-component": "^0.1.1",
"ngx-device-detector": "^1.3.0",
"nyc": "^13.0.1",
Expand Down
2 changes: 1 addition & 1 deletion projects/ccd-case-ui-toolkit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hmcts/ccd-case-ui-toolkit",
"version": "7.0.37",
"version": "7.0.38",
"engines": {
"node": ">=18.17.0"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import '../../components/typography';
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_shims';
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_conditionals';
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_measurements';
@import 'govuk_frontend_toolkit/stylesheets/_shims';
@import 'govuk_frontend_toolkit/stylesheets/_conditionals';
@import 'govuk_frontend_toolkit/stylesheets/_measurements';

$darkgray: #231F20;
$gray: #ECEDEE;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import '../../typography.scss';
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_shims';
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_conditionals';
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_measurements';
@import 'govuk_frontend_toolkit/stylesheets/_shims';
@import 'govuk_frontend_toolkit/stylesheets/_conditionals';
@import 'govuk_frontend_toolkit/stylesheets/_measurements';

$black: #000000;
$white: #FFFFFF;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import '../../typography';
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_shims';
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_conditionals';
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_measurements';
@import 'govuk_frontend_toolkit/stylesheets/_shims';
@import 'govuk_frontend_toolkit/stylesheets/_conditionals';
@import 'govuk_frontend_toolkit/stylesheets/_measurements';

$black: #000000;
$white: #FFFFFF;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import '../../typography.scss';
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_shims';
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_conditionals';
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_measurements';
@import 'govuk_frontend_toolkit/stylesheets/_shims';
@import 'govuk_frontend_toolkit/stylesheets/_conditionals';
@import 'govuk_frontend_toolkit/stylesheets/_measurements';

$blue: #005ea5;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@import '../../typography';
@import "node_modules/govuk_frontend_toolkit/stylesheets/_shims";
@import "node_modules/govuk_frontend_toolkit/stylesheets/_grid_layout";
@import "govuk_frontend_toolkit/stylesheets/_shims";
@import "govuk_frontend_toolkit/stylesheets/_grid_layout";

@mixin phase-banner() {
padding-top: 10px;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_colours.scss';
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_conditionals.scss';
@import 'govuk_frontend_toolkit/stylesheets/_colours.scss';
@import 'govuk_frontend_toolkit/stylesheets/_conditionals.scss';

/*
Tabs
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_colours.scss';
@import 'node_modules/govuk_frontend_toolkit/stylesheets/_typography';
@import 'govuk_frontend_toolkit/stylesheets/_colours.scss';
@import 'govuk_frontend_toolkit/stylesheets/_typography';

@mixin core-24pt($line-height: calc(30 / 24), $line-height-640: calc(24 / 20), $tabular-numbers: false, $font-weight: 400) {
$font-size: 24pt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
CaseFieldService,
FieldsUtils,
FormErrorService,
FormValidatorsService,
FormValueService,
OrderService,
ProfileNotifier,
Expand Down Expand Up @@ -104,6 +105,7 @@ describe('CaseEditSubmitComponent', () => {
let orderService: OrderService;
let profileNotifier: ProfileNotifier;
let casesReferencePipe: jasmine.SpyObj<CaseReferencePipe>;
let formValidatorsService: jasmine.SpyObj<FormValidatorsService>;
const caseField1: CaseField = aCaseField('field1', 'field1', 'Text', 'OPTIONAL', 4);
const caseField2: CaseField = aCaseField('field2', 'field2', 'Text', 'OPTIONAL', 3, null, false, true);
const caseField3: CaseField = aCaseField('field3', 'field3', 'Text', 'OPTIONAL', 2);
Expand Down Expand Up @@ -342,7 +344,7 @@ describe('CaseEditSubmitComponent', () => {
};
formErrorService = createSpyObj<FormErrorService>('formErrorService', ['mapFieldErrors']);
formValueService = createSpyObj<FormValueService>('formValueService', ['sanitise']);

formValidatorsService = createSpyObj<FormValidatorsService>('formValidatorsService', ['addMarkDownValidators']);
spyOn(caseEditComponent, 'navigateToPage');
spyOn(caseEditComponent, 'cancel');
spyOn(caseEditComponent, 'submitForm');
Expand All @@ -368,6 +370,7 @@ describe('CaseEditSubmitComponent', () => {
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{ provide: FormValidatorsService, useValue: formValidatorsService },
{ provide: CaseEditComponent, useValue: caseEditComponent },
{ provide: FormValueService, useValue: formValueService },
{ provide: FormErrorService, useValue: formErrorService },
Expand All @@ -376,6 +379,7 @@ describe('CaseEditSubmitComponent', () => {
{ provide: CaseReferencePipe, useValue: casesReferencePipe },
{ provide: ActivatedRoute, useValue: mockRoute },
{ provide: OrderService, useValue: orderService },
{ provide: OrderService, useValue: orderService },
{ provide: ProfileNotifier, useValue: profileNotifier },
{ provide: SessionStorageService, useValue: sessionStorageService },
{ provide: Router, useValue: mockRouter },
Expand Down Expand Up @@ -802,6 +806,7 @@ describe('CaseEditSubmitComponent', () => {
};
formErrorService = createSpyObj<FormErrorService>('formErrorService', ['mapFieldErrors']);
formValueService = createSpyObj<FormValueService>('formValueService', ['sanitise']);
formValidatorsService = createSpyObj<FormValidatorsService>('formValidatorsService', ['addMarkDownValidators']);

spyOn(caseEditComponent, 'navigateToPage');
spyOn(caseEditComponent, 'cancel');
Expand All @@ -827,6 +832,7 @@ describe('CaseEditSubmitComponent', () => {
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{ provide: FormValidatorsService, useValue: formValidatorsService },
{ provide: CaseEditComponent, useValue: caseEditComponent },
{ provide: FormValueService, useValue: formValueService },
{ provide: FormErrorService, useValue: formErrorService },
Expand Down Expand Up @@ -958,6 +964,7 @@ describe('CaseEditSubmitComponent', () => {
};
formErrorService = createSpyObj<FormErrorService>('formErrorService', ['mapFieldErrors']);
formValueService = createSpyObj<FormValueService>('formValueService', ['sanitise']);
formValidatorsService = createSpyObj<FormValidatorsService>('formValidatorsService', ['addMarkDownValidators']);

spyOn(caseEditComponent, 'navigateToPage');
spyOn(caseEditComponent, 'cancel');
Expand Down Expand Up @@ -985,6 +992,7 @@ describe('CaseEditSubmitComponent', () => {
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{ provide: FormValidatorsService, useValue: formValidatorsService },
{ provide: CaseEditComponent, useValue: caseEditComponent },
{ provide: FormValueService, useValue: formValueService },
{ provide: FormErrorService, useValue: formErrorService },
Expand All @@ -1008,6 +1016,9 @@ describe('CaseEditSubmitComponent', () => {

describe('submit', () => {
it('should call caseEdits submitForm', () => {
comp.summary = new FormControl('ValidSummaryValue');
comp.description = new FormControl('ValidDescriptionValue');

comp.submit();
expect(caseEditComponent.submitForm).toHaveBeenCalled();
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { AbstractControl, FormGroup } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';
import { CaseEventTrigger, CaseField, Profile } from '../../../domain';
import { Task } from '../../../domain/work-allocation/Task';
import {
CaseFieldService,
FieldsUtils,
FormValidatorsService,
OrderService,
ProfileNotifier,
ProfileNotifier
} from '../../../services';
import { CallbackErrorsComponent, CallbackErrorsContext } from '../../error';
import { PaletteContext } from '../../palette';
Expand Down Expand Up @@ -37,6 +38,10 @@ export class CaseEditSubmitComponent implements OnInit, OnDestroy {
public pageTitle: string;
public metadataFieldsObject: object;
public allFieldsValues: any;
public summary: AbstractControl;
public description: AbstractControl;
public eventSummaryLabel: string = 'Event summary';
public eventDescriptionLabel: string = 'Event description';

public static readonly SHOW_SUMMARY_CONTENT_COMPARE_FUNCTION = (a: CaseField, b: CaseField): number => {
const aCaseField = a.show_summary_content_option === 0 || a.show_summary_content_option;
Expand All @@ -50,7 +55,7 @@ export class CaseEditSubmitComponent implements OnInit, OnDestroy {
return -1;
}
return a.show_summary_content_option - b.show_summary_content_option;
}
};

public get isDisabled(): boolean {
// EUI-3452.
Expand All @@ -67,11 +72,12 @@ export class CaseEditSubmitComponent implements OnInit, OnDestroy {
private readonly route: ActivatedRoute,
private readonly orderService: OrderService,
private readonly profileNotifier: ProfileNotifier,
private readonly formValidatorsService: FormValidatorsService
) {
}

public ngOnInit(): void {
this.profileSubscription = this.profileNotifier.profile.subscribe(_ => this.profile = _);
this.profileSubscription = this.profileNotifier.profile.subscribe((_) => this.profile = _);
this.eventTrigger = this.caseEdit.eventTrigger;
this.triggerText = this.eventTrigger.end_button_label || CallbackErrorsComponent.TRIGGER_TEXT_SUBMIT;
this.editForm = this.caseEdit.form;
Expand All @@ -80,15 +86,18 @@ export class CaseEditSubmitComponent implements OnInit, OnDestroy {
this.caseEdit.isSubmitting = false;
this.contextFields = this.getCaseFields();
this.metadataFieldsObject = this.caseEdit?.caseDetails?.metadataFields?.
reduce((o, key) => Object.assign(o, {[key.id]: key.value}), {});
reduce((o, key) => Object.assign(o, { [key.id]: key.value }), {});
this.allFieldsValues = Object.assign(this.metadataFieldsObject ? this.metadataFieldsObject : {}, this.editForm.getRawValue().data);
// Indicates if the submission is for a Case Flag, as opposed to a "regular" form submission, by the presence of
// a FlagLauncher field in the event trigger
this.caseEdit.isCaseFlagSubmission =
this.eventTrigger.case_fields.some(caseField => FieldsUtils.isCaseFieldOfType(caseField, ['FlagLauncher']));
this.eventTrigger.case_fields.some((caseField) => FieldsUtils.isCaseFieldOfType(caseField, ['FlagLauncher']));
this.caseEdit.isLinkedCasesSubmission =
this.eventTrigger.case_fields.some(caseField => FieldsUtils.isCaseFieldOfType(caseField, ['ComponentLauncher']));
this.pageTitle = this.getPageTitle();

this.summary = this.formValidatorsService.addMarkDownValidators(this.editForm, 'event.summary');
this.description = this.formValidatorsService.addMarkDownValidators(this.editForm, 'event.description');
}

public ngOnDestroy(): void {
Expand All @@ -99,12 +108,14 @@ export class CaseEditSubmitComponent implements OnInit, OnDestroy {
}

public submit(): void {
this.caseEdit.submitForm({
eventTrigger: this.eventTrigger,
form: this.editForm,
submit: this.caseEdit.submit,
caseDetails: this.caseEdit.caseDetails,
});
if (this.summary.valid && this.description.valid) {
this.caseEdit.submitForm({
eventTrigger: this.eventTrigger,
form: this.editForm,
submit: this.caseEdit.submit,
caseDetails: this.caseEdit.caseDetails
});
}
}

public onEventCanBeCompleted(eventCanBeCompleted: boolean): void {
Expand All @@ -113,7 +124,7 @@ export class CaseEditSubmitComponent implements OnInit, OnDestroy {
eventCanBeCompleted,
caseDetails: this.caseEdit.caseDetails,
form: this.editForm,
submit: this.caseEdit.submit,
submit: this.caseEdit.submit
});
}

Expand Down Expand Up @@ -197,7 +208,7 @@ export class CaseEditSubmitComponent implements OnInit, OnDestroy {
}

public readOnlySummaryFieldsToDisplayExists(): boolean {
return this.eventTrigger.case_fields.some(field => field.show_summary_content_option >= 0);
return this.eventTrigger.case_fields.some((field) => field.show_summary_content_option >= 0);
}

public showEventNotes(): boolean {
Expand All @@ -214,7 +225,7 @@ export class CaseEditSubmitComponent implements OnInit, OnDestroy {

private getLastPageShown(): WizardPage {
let lastPage: WizardPage;
this.wizard.reverse().forEach(page => {
this.wizard.reverse().forEach((page) => {
if (!lastPage && this.isShown(page)) {
lastPage = page;
}
Expand All @@ -236,7 +247,7 @@ export class CaseEditSubmitComponent implements OnInit, OnDestroy {

public isShown(page: WizardPage): boolean {
const fields = this.fieldsUtils
.mergeCaseFieldsAndFormFields(this.eventTrigger.case_fields, this.editForm.controls['data'].value);
.mergeCaseFieldsAndFormFields(this.eventTrigger.case_fields, this.editForm.controls.data.value);
return page.parsedShowCondition.match(fields);
}

Expand All @@ -247,7 +258,7 @@ export class CaseEditSubmitComponent implements OnInit, OnDestroy {
private sortFieldsByShowSummaryContent(fields: CaseField[]): CaseField[] {
return this.orderService
.sort(fields, CaseEditSubmitComponent.SHOW_SUMMARY_CONTENT_COMPARE_FUNCTION)
.filter(cf => cf.show_summary_content_option);
.filter((cf) => cf.show_summary_content_option);
}

private getCaseFields(): CaseField[] {
Expand All @@ -270,9 +281,8 @@ export class CaseEditSubmitComponent implements OnInit, OnDestroy {
public getCancelText(): string {
if (this.eventTrigger.can_save_draft) {
return 'Return to case list';
} else {
return 'Cancel';
}
return 'Cancel';
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,24 @@ <h2 class="heading-h2">{{pageTitle | rpxTranslate }}</h2>
<ng-container *ngIf="showEventNotes()">
<fieldset id="fieldset-event" formGroupName="event">
<legend style="display: none;"></legend>
<div class="form-group">
<div class="form-group" [ngClass]="{'form-group-error': !!summary && !summary.valid && (summary.dirty || summary.touched)}">
<label for="field-trigger-summary" class="form-label">
Event summary (optional)
<span class="form-hint">A few words describing the purpose of the event.</span>
</label>
<input type="text" id="field-trigger-summary" class="form-control bottom-30 width-50" formControlName="summary" maxlength="1024">
<span class="error-message" *ngIf="summary?.errors && (summary.dirty || summary.touched)">
{{summary.errors | ccdFirstError: eventSummaryLabel | rpxTranslate}}
</span>
<input type="text" id="field-trigger-summary" class="form-control bottom-30 width-50"
[ngClass]="{'govuk-input--error': summary?.errors && (summary.dirty || summary.touched)}" formControlName="summary" maxlength="1024">
</div>
<div class="form-group">
<div class="form-group" [ngClass]="{'form-group-error': !!description && !description.valid && (description.dirty || description.touched)}">
<label for="field-trigger-description" class="form-label">Event description (optional)</label>
<span class="error-message" *ngIf="description?.errors && (description.dirty || description.touched)">
{{description.errors | ccdFirstError: eventDescriptionLabel | rpxTranslate}}
</span>
<textarea id="field-trigger-description" class="form-control bottom-30 width-50" formControlName="description"
maxlength="65536"></textarea>
[ngClass]="{'govuk-input--error': description?.errors && (description.dirty || description.touched)}" maxlength="65536"></textarea>
</div>
</fieldset>
</ng-container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import createSpyObj = jasmine.createSpyObj;

describe('CaseworkerService', () => {
const API_URL = 'http://aggregated.ccd.reform';
const CASE_WORKER_URL = `${API_URL}/retrieveCaseWorkersForServices`;
const CASE_WORKER_URL = `${API_URL}/caseworker/getUsersByServiceName`;
const CASE_WORKER_1: Caseworker = {
idamId: '4321-4321-4321-4321',
firstName: 'Test',
Expand Down Expand Up @@ -41,7 +41,7 @@ describe('CaseworkerService', () => {
caseworkerService.getCaseworkers(serviceId)
.subscribe()
.add(() => {
expect(httpService.post).toHaveBeenCalledWith(CASE_WORKER_URL, {serviceIds: [serviceId]});
expect(httpService.post).toHaveBeenCalledWith(CASE_WORKER_URL, {services: [serviceId]});
});
}));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ export class CaseworkerService {
}

public getCaseworkers(serviceId): Observable<CaseworkersByService[]> {
const url = `${this.appConfig.getWorkAllocationApiUrl()}/retrieveCaseWorkersForServices`;
const url = `${this.appConfig.getWorkAllocationApiUrl()}/caseworker/getUsersByServiceName`;
return this.http
.post(url, { serviceIds: [serviceId]})
.post(url, { services: [serviceId]})
.pipe(
catchError(error => {
this.errorService.setError(error);
Expand Down
Loading

0 comments on commit ab6c774

Please sign in to comment.