修改国际化
parent
9b6e8feabf
commit
122b50e114
|
@ -1,6 +1,7 @@
|
|||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
|
@ -12,8 +13,13 @@ namespace IRaCIS.Core.API
|
|||
{
|
||||
public class ApiResponseHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
{
|
||||
public ApiResponseHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
|
||||
public IStringLocalizer _localizer;
|
||||
public ApiResponseHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
|
||||
IStringLocalizer localizer,
|
||||
ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
|
||||
{
|
||||
_localizer = localizer;
|
||||
|
||||
}
|
||||
|
||||
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
|
@ -24,14 +30,16 @@ namespace IRaCIS.Core.API
|
|||
{
|
||||
Response.ContentType = "application/json";
|
||||
Response.StatusCode = StatusCodes.Status401Unauthorized;
|
||||
await Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk("您无权访问该接口", ApiResponseCodeEnum.NoToken)));
|
||||
//---您无权访问该接口
|
||||
await Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["ApiResponse_NoAccess"], ApiResponseCodeEnum.NoToken)));
|
||||
}
|
||||
|
||||
protected override async Task HandleForbiddenAsync(AuthenticationProperties properties)
|
||||
{
|
||||
Response.ContentType = "application/json";
|
||||
Response.StatusCode = StatusCodes.Status403Forbidden;
|
||||
await Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk("您的权限不允许进行该操作",ApiResponseCodeEnum.HaveTokenNotAccess)));
|
||||
//---您的权限不允许进行该操作
|
||||
await Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk(_localizer["ApiResponse_Permission"],ApiResponseCodeEnum.HaveTokenNotAccess)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,12 @@ namespace IRaCIS.Core.Application.Filter
|
|||
|
||||
public class ModelActionFilter : ActionFilterAttribute, IActionFilter
|
||||
{
|
||||
public IStringLocalizer _localizer;
|
||||
public ModelActionFilter(IStringLocalizer localizer)
|
||||
{
|
||||
_localizer = localizer;
|
||||
}
|
||||
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
if (!context.ModelState.IsValid)
|
||||
|
@ -23,7 +29,7 @@ namespace IRaCIS.Core.Application.Filter
|
|||
.ToArray();
|
||||
|
||||
//---提供给接口的参数无效。
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk("Invalid parameters provided for the API." + JsonConvert.SerializeObject( validationErrors)));
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ModelAction_InvalidAPIParameter"] + JsonConvert.SerializeObject( validationErrors)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace IRaCIS.Core.Application.Filter
|
||||
|
@ -10,9 +11,12 @@ namespace IRaCIS.Core.Application.Filter
|
|||
{
|
||||
private readonly ILogger<ProjectExceptionFilter> _logger;
|
||||
|
||||
public ProjectExceptionFilter(ILogger<ProjectExceptionFilter> logger)
|
||||
public IStringLocalizer _localizer;
|
||||
|
||||
public ProjectExceptionFilter(IStringLocalizer localizer, ILogger<ProjectExceptionFilter> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_localizer = localizer;
|
||||
}
|
||||
public void OnException(ExceptionContext context)
|
||||
{
|
||||
|
@ -23,7 +27,7 @@ namespace IRaCIS.Core.Application.Filter
|
|||
if (context.Exception.GetType().Name == "DbUpdateConcurrencyException")
|
||||
{
|
||||
//---并发更新,当前不允许该操作
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk("Concurrent update, operation not allowed at this time." + context.Exception.Message));
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ProjectException_ConcurrentUpdateNotAllowed"] + context.Exception.Message));
|
||||
}
|
||||
|
||||
if (context.Exception.GetType() == typeof(BusinessValidationFailedException))
|
||||
|
@ -36,7 +40,7 @@ namespace IRaCIS.Core.Application.Filter
|
|||
}
|
||||
else
|
||||
{
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk("程序异常,请联系开发人员。" + (context.Exception.InnerException is null ? (context.Exception.Message /*+ context.Exception.StackTrace*/)
|
||||
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (context.Exception.InnerException is null ? (context.Exception.Message /*+ context.Exception.StackTrace*/)
|
||||
: (context.Exception.InnerException?.Message /*+ context.Exception.InnerException?.StackTrace*/)), ApiResponseCodeEnum.ProgramException));
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
"test{0}{1}": "英文本地化{0}{1}",
|
||||
"RequiredAttribute": "{0} is required",
|
||||
|
||||
// ------------------------------------------------------------_ServiceExtensions--------------------------------------------------------------------
|
||||
//ApiResponseHandler
|
||||
"ApiResponse_NoAccess": "You do not have access to this API",
|
||||
"ApiResponse_Permission": "Your permission does not allow you to perform this operation",
|
||||
|
||||
// ------------------------------------------------------------Controllers--------------------------------------------------------------------
|
||||
//FinancialChangeController
|
||||
"Financial_ChargeSettled": "Expenses have been settled and workload can not be reset.",
|
||||
|
@ -89,6 +94,8 @@
|
|||
"ReadingQuestion_ExcludeWithDependency": "The displayed dependent parent problem and the required dependent problem are the same, but the answers are mutually exclusive, operation failed.",
|
||||
"ReadingQuestion_CircularDependency": "Calculation dependency has looped!",
|
||||
//ReadingPeriodSetService
|
||||
"ReadingPeriodSet_NameDup": "Reading period name duplicate, operation failed",
|
||||
"ReadingPeriodSet_Global": "Reading period name cannot be Global",
|
||||
"ReadingPeriodSet_AlreadyAdded": "{0} has already added the review period, cannot set it effective.",
|
||||
"ReadingPeriodSet_TaskCompletedCannotRevoke": "The current standard review has generated tasks and the review is completed, revoke failed.",
|
||||
"ReadingPeriodSet_LastVisit": "Last visit.",
|
||||
|
@ -182,6 +189,8 @@
|
|||
"Mail_AccountCreationReminder": "[from Extensive Imaging IRC] A reminder about creating an account",
|
||||
"Mail_AccountPasswordResetReminder": "[from Film IRC] A reminder about resetting account passwords",
|
||||
"Mail_InvitationEmail": "[from Extensive Imaging IRC][{0}]Invitation",
|
||||
//SystemMonitor
|
||||
"SysMon_JsonConfig": "Parsing the Json file configuration failed",
|
||||
|
||||
// ------------------------------------------------------------Doctor--------------------------------------------------------------------
|
||||
//DoctorService
|
||||
|
@ -421,6 +430,7 @@
|
|||
//TrialConfigService
|
||||
"TrialConfig_JudgeTaskFail": "There are judge questions that the conditions for generating judge reading task are not configured, and the operation has failed!",
|
||||
"TrialConfig_StdConfigMissing": "Questions are not configured under the current standard.",
|
||||
"TrialConfig_AddEvalReq": "Selected additional evaluation, must check additional evaluation type",
|
||||
"TrialConfig_SignTemplateMissing": "This operation requires electronic signature confirmation, but the signature template for this scenario is not found in the system.",
|
||||
"TrialConfig_ProjectEnded": "The trial project has ended or stopped, and configuration changes are not allowed.",
|
||||
"TrialConfig_NoImageAuditQuestion": "No image quality control review question is currently added. Please add the image quality control review question first, and then confirm.",
|
||||
|
@ -545,6 +555,12 @@
|
|||
|
||||
// ------------------------------------------------------------IRaCIS.Core.Domain--------------------------------------------------------------------
|
||||
//Trial
|
||||
"Trial_number": "The serial number consists of five digits. The first two digits are the center number and the last three digits are the serial number. The serial number must be the same as that recorded by the EDC"
|
||||
"Trial_number": "The serial number consists of five digits. The first two digits are the center number and the last three digits are the serial number. The serial number must be the same as that recorded by the EDC",
|
||||
|
||||
// ------------------------------------------------------------IRaCIS.Core.Infrastructure--------------------------------------------------------------------
|
||||
//ResponseOutput
|
||||
"RO_BizObjNotExistsOrParamIncorrect": "The business object{0} does not exist in the database, or was deleted by someone else, or an incorrect parameter query caused",
|
||||
"RO_ExpectChangeButNoEffect": "Expect a change, but the database data has not changed",
|
||||
"RO_SaveFailed": "Saved failed"
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
"test{0}{1}": "中文本地化{0}{1}",
|
||||
"RequiredAttribute": "{0} 字段是必须的",
|
||||
|
||||
// ------------------------------------------------------------_ServiceExtensions--------------------------------------------------------------------
|
||||
//ApiResponseHandler
|
||||
"ApiResponse_NoAccess": "您无权访问该接口",
|
||||
"ApiResponse_Permission": "您的权限不允许进行该操作",
|
||||
|
||||
// ------------------------------------------------------------Controllers--------------------------------------------------------------------
|
||||
//FinancialChangeController
|
||||
"Financial_ChargeSettled": "费用已经结算,无法重置工作量",
|
||||
|
@ -89,6 +94,8 @@
|
|||
"ReadingQuestion_ExcludeWithDependency": "显示依赖父问题和必填依赖的问题为同一个,但答案互斥,操作失败",
|
||||
"ReadingQuestion_CircularDependency": "计算依赖循环了!",
|
||||
//ReadingPeriodSetService
|
||||
"ReadingPeriodSet_NameDup": "阅片期名称重复,操作失败",
|
||||
"ReadingPeriodSet_Global": "阅片期名称不能为Global",
|
||||
"ReadingPeriodSet_AlreadyAdded": "{0}已经添加过阅片期,无法设置生效",
|
||||
"ReadingPeriodSet_TaskCompletedCannotRevoke": "当前标准阅片已生成任务并且阅片完成,撤销失败。",
|
||||
"ReadingPeriodSet_LastVisit": "末次访视",
|
||||
|
@ -182,6 +189,8 @@
|
|||
"Mail_AccountCreationReminder": "[来自展影IRC] 关于创建账户的提醒",
|
||||
"Mail_AccountPasswordResetReminder": "[来自展影IRC] 关于重置账户密码的提醒",
|
||||
"Mail_InvitationEmail": "[来自展影IRC] [{0}]邀请信",
|
||||
//SystemMonitor
|
||||
"SysMon_JsonConfig": "解析Json文件配置出现问题",
|
||||
|
||||
// ------------------------------------------------------------Doctor--------------------------------------------------------------------
|
||||
//DoctorService
|
||||
|
@ -421,6 +430,7 @@
|
|||
//TrialConfigService
|
||||
"TrialConfig_JudgeTaskFail": "有裁判问题未配置产生裁判阅片任务的条件,操作失败!",
|
||||
"TrialConfig_StdConfigMissing": "当前标准下未配置问题",
|
||||
"TrialConfig_AddEvalReq": "选择了附加评估,必须勾选附加评估类型",
|
||||
"TrialConfig_SignTemplateMissing": "该操作需要电子签名确认,但未在系统中找到该场景的签名模板。",
|
||||
"TrialConfig_ProjectEnded": "该项目已结束或停止,不允许修改配置。",
|
||||
"TrialConfig_NoImageAuditQuestion": "当前未添加影像质控审核问题。请先添加影像质控审核问题,再进行确认。",
|
||||
|
@ -545,6 +555,12 @@
|
|||
|
||||
// ------------------------------------------------------------IRaCIS.Core.Domain--------------------------------------------------------------------
|
||||
//Trial
|
||||
"Trial_number": "编号由5位数字组成,前2位为中心编号,后3位为顺序号,请与EDC录入的编号保持一致"
|
||||
"Trial_number": "编号由5位数字组成,前2位为中心编号,后3位为顺序号,请与EDC录入的编号保持一致",
|
||||
|
||||
// ------------------------------------------------------------IRaCIS.Core.Infrastructure--------------------------------------------------------------------
|
||||
//ResponseOutput
|
||||
"RO_BizObjNotExistsOrParamIncorrect": "业务对象{0}在数据库中不存在,或被他人删除,或参数查询不正确导致",
|
||||
"RO_ExpectChangeButNoEffect": "期望发生更改,但数据库数据没有更改",
|
||||
"RO_SaveFailed": "保存失败"
|
||||
|
||||
}
|
||||
|
|
|
@ -64,7 +64,8 @@ namespace IRaCIS.Core.Application.Service.Common
|
|||
catch (Exception e)
|
||||
{
|
||||
|
||||
throw new BusinessValidationFailedException("解析Json文件配置出现问题:"+e.Message);
|
||||
//---解析Json文件配置出现问题
|
||||
throw new BusinessValidationFailedException(_localizer["SysMon_JsonConfig"]+e.Message);
|
||||
}
|
||||
|
||||
//默认存储的路径
|
||||
|
|
|
@ -985,7 +985,8 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
}
|
||||
else
|
||||
{
|
||||
return ResponseOutput.NotOk("项目配置为单审,不满足SubmmitState:已提交 或者 AuditState:待审核/审核中, 不允许领取,请刷新界面");
|
||||
// ---项目配置为单审,不满足Submmit State:已提交 或者 Audit State:待审核/审核中, 不允许领取,请刷新界面
|
||||
return ResponseOutput.NotOk(_localizer["QCOperation_NoSingleAudit"]);
|
||||
}
|
||||
}
|
||||
else if (trialConfig.QCProcessEnum == TrialQCProcess.DoubleAudit)
|
||||
|
@ -2075,8 +2076,8 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId,
|
||||
u => new SubjectVisit() { ForwardState = ForwardStateEnum.ForwardFailed });
|
||||
|
||||
|
||||
return ResponseOutput.NotOk("转发影像失败: " + e.Message);
|
||||
// --转发影像失败
|
||||
return ResponseOutput.NotOk(_localizer["QCOperation_ForwardingFailed"] + e.Message);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -72,11 +72,13 @@ namespace IRaCIS.Application.Services
|
|||
if (await _readingPeriodSetRepository.AnyAsync(x => x.Id != addOrEditReadingPeriodSet.Id && x.IsTakeEffect != ReadingPeriodStatus.Revocation
|
||||
&& x.TrialId == addOrEditReadingPeriodSet.TrialId && x.ReadingPeriodName == addOrEditReadingPeriodSet.ReadingPeriodName && x.TrialReadingCriterionId == addOrEditReadingPeriodSet.TrialReadingCriterionId))
|
||||
{
|
||||
return ResponseOutput.NotOk("阅片期名称重复,操作失败");
|
||||
//---阅片期名称重复,操作失败
|
||||
return ResponseOutput.NotOk(_localizer["ReadingPeriodSet_NameDup"]);
|
||||
}
|
||||
if (addOrEditReadingPeriodSet.ReadingPeriodName == "Global")
|
||||
{
|
||||
return ResponseOutput.NotOk("阅片期名称不能为Global");
|
||||
//---阅片期名称不能为Global
|
||||
return ResponseOutput.NotOk(_localizer["ReadingPeriodSet_Global"]);
|
||||
}
|
||||
if (addOrEditReadingPeriodSet.Id == null)
|
||||
{
|
||||
|
|
|
@ -442,7 +442,8 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
|
||||
if (await _trialSiteSurveyRepository.AnyAsync(t => t.Id == trialSiteSurveyId && t.State == TrialSiteSurveyEnum.PMCreatedAndLock))
|
||||
{
|
||||
return ResponseOutput.NotOk("中心调研表已锁定,不允许操作");
|
||||
//---中心调研已锁定,不允许操作。
|
||||
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_Locked"]);
|
||||
}
|
||||
|
||||
var success = await _trialSiteSurveyRepository.BatchDeleteNoTrackingAsync(t => t.Id == trialSiteSurveyId);
|
||||
|
@ -561,7 +562,8 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
|
||||
if (await _repository.AnyAsync<TrialSiteSurvey>(t => t.State == TrialSiteSurveyEnum.PMCreatedAndLock && t.Id == trialSiteSurveyId))
|
||||
{
|
||||
return ResponseOutput.NotOk("中心调研表已锁定,不允许操作。");
|
||||
//---中心调研已锁定,不允许操作。
|
||||
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_Locked"]);
|
||||
}
|
||||
|
||||
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM)
|
||||
|
@ -668,7 +670,8 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
{
|
||||
if (await _repository.AnyAsync<TrialSiteSurvey>(t => t.State == TrialSiteSurveyEnum.PMCreatedAndLock && t.Id == trialSiteSurveyId))
|
||||
{
|
||||
return ResponseOutput.NotOk("中心调研表已锁定,不允许操作。");
|
||||
//---中心调研已锁定,不允许操作。
|
||||
return ResponseOutput.NotOk(_localizer["TrialSiteSurvey_Locked"]);
|
||||
}
|
||||
|
||||
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.SPM || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CPM)
|
||||
|
|
|
@ -624,7 +624,8 @@ namespace IRaCIS.Core.Application
|
|||
|
||||
if (inDto.TrialCriterionAdditionalAssessmentTypeList.All(t => t.IsSelected != true))
|
||||
{
|
||||
throw new BusinessValidationFailedException("选择了附加评估,必须勾选附加评估类型");
|
||||
//---选择了附加评估,必须勾选附加评估类型
|
||||
throw new BusinessValidationFailedException(_localizer["TrialConfig_AddEvalReq"]);
|
||||
}
|
||||
|
||||
var trialId = _readingQuestionTrialRepository.Where(t => t.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId).Select(t => t.TrialId).FirstOrDefault();
|
||||
|
|
|
@ -184,7 +184,8 @@ namespace IRaCIS.Application.Services
|
|||
{
|
||||
if (await _repository.AnyAsync<TrialSiteUser>(t => t.UserId == trialUser.UserId && t.TrialId == trialUser.TrialId))
|
||||
{
|
||||
return ResponseOutput.NotOk("Participant has participated in site maintenance");
|
||||
// ----人员已加入现场维护
|
||||
return ResponseOutput.NotOk(_localizer["TrialMaint_PersonnelJoined"]);
|
||||
}
|
||||
|
||||
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.IQC)
|
||||
|
|
|
@ -111,7 +111,8 @@ namespace IRaCIS.Application.Services
|
|||
|
||||
if (!await _trialRepository.Where(t => t.Id == visitPlan.TrialId).IgnoreQueryFilters().AnyAsync(t => t.TrialStatusStr == StaticData.TrialState.TrialOngoing || t.TrialStatusStr == StaticData.TrialState.TrialInitializing))
|
||||
{
|
||||
throw new BusinessValidationFailedException("只有当项目状态为:初始化或进行中时,可以操作。 ");
|
||||
//---只有当项目状态为:初始化或进行中时,可以操作。
|
||||
throw new BusinessValidationFailedException(_localizer["VisitPlan_OnlyInitOrOngoing"]);
|
||||
}
|
||||
|
||||
var visitPlanList = await _visitStageRepository.Where(t => t.TrialId == visitPlan.TrialId, ignoreQueryFilters: true)
|
||||
|
|
|
@ -429,7 +429,9 @@ namespace IRaCIS.Core.Infra.EFCore
|
|||
{
|
||||
if (updateFilter == null)
|
||||
{
|
||||
throw new ArgumentException("更新过滤条件不允许为空", nameof(updateFilter));
|
||||
|
||||
|
||||
throw new ArgumentException("The update filter condition cannot be empty", nameof(updateFilter));
|
||||
}
|
||||
var query = ignoreQueryFilter ? _dbContext.Set<T>().AsNoTracking().IgnoreQueryFilters() : _dbContext.Set<T>().AsNoTracking();
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ namespace IRaCIS.Core.Infra.EFCore
|
|||
{
|
||||
if (updateFilter == null)
|
||||
{
|
||||
throw new ArgumentException("更新过滤条件不允许为空", nameof(updateFilter));
|
||||
throw new ArgumentException("The update filter condition cannot be empty", nameof(updateFilter));
|
||||
}
|
||||
var query = ignoreQueryFilter ? _dbSet.AsNoTracking().IgnoreQueryFilters() : _dbSet.AsNoTracking();
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace IRaCIS.Core.Infrastructure.Extention
|
|||
|
||||
if (isMultiSortFiled&& sortArray==default)
|
||||
{
|
||||
throw new System.Exception("必须指定排序字段");
|
||||
throw new System.Exception("The sort field must be specified");
|
||||
}
|
||||
|
||||
if (pageNumber <= 0)
|
||||
|
|
|
@ -169,7 +169,7 @@ namespace IRaCIS.Core.Infrastructure.Extention
|
|||
|
||||
public static IResponseOutput<string> DBNotExistIfNUll(object businessObject)
|
||||
{
|
||||
return new ResponseOutput<string>().NotOk($"The business object{businessObject.GetType().Name} does not exist in the database, or was deleted by someone else, or an incorrect parameter query caused");
|
||||
return new ResponseOutput<string>().NotOk("The business object{businessObject.GetType().Name} does not exist in the database, or was deleted by someone else, or an incorrect parameter query caused");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -77,6 +77,8 @@ namespace Zhaoxi.NET6.AuthenticationCenter.Controllers
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
return ResponseOutput.NotOk("Token获取失败");
|
||||
}
|
||||
}
|
||||
|
|
BIN
后端提示语.xlsx
BIN
后端提示语.xlsx
Binary file not shown.
Loading…
Reference in New Issue