Browse Source

feat: 修复ADB和AT操作CommandHandler中缺少IUnitOfWork SaveChangesAsync调用

- 为CreateAdbOperationCommandHandler添加IUnitOfWork依赖和SaveChangesAsync调用
- 为UpdateAdbOperationCommandHandler添加IUnitOfWork依赖和SaveChangesAsync调用
- 为DeleteAdbOperationCommandHandler添加IUnitOfWork依赖和SaveChangesAsync调用
- 为CreateAtOperationCommandHandler添加IUnitOfWork依赖和SaveChangesAsync调用
- 为UpdateAtOperationCommandHandler添加IUnitOfWork依赖和SaveChangesAsync调用
- 为DeleteAtOperationCommandHandler添加IUnitOfWork依赖和SaveChangesAsync调用

修复DDD设计原则违反问题,确保数据被正确持久化到数据库,支持事务管理和异常处理。
feature/x1-web-request
root 4 months ago
parent
commit
5d0566e397
  1. 9
      src/X1.Application/Features/AdbOperations/Commands/CreateAdbOperation/CreateAdbOperationCommandHandler.cs
  2. 9
      src/X1.Application/Features/AdbOperations/Commands/DeleteAdbOperation/DeleteAdbOperationCommandHandler.cs
  3. 5
      src/X1.Application/Features/AdbOperations/Commands/UpdateAdbOperation/UpdateAdbOperationCommand.cs
  4. 21
      src/X1.Application/Features/AdbOperations/Commands/UpdateAdbOperation/UpdateAdbOperationCommandHandler.cs
  5. 9
      src/X1.Application/Features/AtOperations/Commands/CreateAtOperation/CreateAtOperationCommandHandler.cs
  6. 9
      src/X1.Application/Features/AtOperations/Commands/DeleteAtOperation/DeleteAtOperationCommandHandler.cs
  7. 13
      src/X1.Application/Features/AtOperations/Commands/UpdateAtOperation/UpdateAtOperationCommandHandler.cs
  8. 16
      src/X1.Domain/Entities/Terminal/AdbOperation.cs
  9. 4
      src/X1.Infrastructure/Configurations/Terminal/AdbOperationConfiguration.cs
  10. 1625
      src/X1.Infrastructure/Migrations/20250820020118_UpdateAdbOperationPathNullable.Designer.cs
  11. 44
      src/X1.Infrastructure/Migrations/20250820020118_UpdateAdbOperationPathNullable.cs
  12. 3
      src/X1.Infrastructure/Migrations/AppDbContextModelSnapshot.cs
  13. 4
      src/X1.WebAPI/Properties/launchSettings.json
  14. 469
      src/X1.WebUI/package-lock.json
  15. 3
      src/X1.WebUI/src/constants/api.ts
  16. 442
      src/X1.WebUI/src/pages/adb-operations/AdbOperationDrawer.tsx
  17. 355
      src/X1.WebUI/src/pages/adb-operations/AdbOperationForm.tsx
  18. 72
      src/X1.WebUI/src/pages/adb-operations/AdbOperationsView.tsx
  19. 66
      src/X1.WebUI/src/services/adbOperationsService.ts
  20. 392
      src/X1.WebUI/yarn.lock
  21. 1493
      src/modify.md

9
src/X1.Application/Features/AdbOperations/Commands/CreateAdbOperation/CreateAdbOperationCommandHandler.cs

@ -2,6 +2,7 @@ using CellularManagement.Domain.Common;
using CellularManagement.Domain.Entities.Terminal;
using CellularManagement.Domain.Repositories.Terminal;
using CellularManagement.Domain.Services;
using CellularManagement.Domain.Repositories.Base;
using MediatR;
using Microsoft.Extensions.Logging;
@ -15,15 +16,18 @@ public class CreateAdbOperationCommandHandler : IRequestHandler<CreateAdbOperati
private readonly IAdbOperationRepository _adbOperationRepository;
private readonly ILogger<CreateAdbOperationCommandHandler> _logger;
private readonly ICurrentUserService _currentUserService;
private readonly IUnitOfWork _unitOfWork;
public CreateAdbOperationCommandHandler(
IAdbOperationRepository adbOperationRepository,
ILogger<CreateAdbOperationCommandHandler> logger,
ICurrentUserService currentUserService)
ICurrentUserService currentUserService,
IUnitOfWork unitOfWork)
{
_adbOperationRepository = adbOperationRepository;
_logger = logger;
_currentUserService = currentUserService;
_unitOfWork = unitOfWork;
}
public async Task<OperationResult<CreateAdbOperationResponse>> Handle(
@ -52,6 +56,9 @@ public class CreateAdbOperationCommandHandler : IRequestHandler<CreateAdbOperati
// 保存到数据库
var savedOperation = await _adbOperationRepository.AddOperationAsync(adbOperation, cancellationToken);
// 确保数据被持久化到数据库
await _unitOfWork.SaveChangesAsync(cancellationToken);
// 构建响应
var response = new CreateAdbOperationResponse

9
src/X1.Application/Features/AdbOperations/Commands/DeleteAdbOperation/DeleteAdbOperationCommandHandler.cs

@ -1,4 +1,5 @@
using CellularManagement.Domain.Repositories.Terminal;
using CellularManagement.Domain.Repositories.Base;
using MediatR;
using Microsoft.Extensions.Logging;
using CellularManagement.Domain.Common;
@ -11,13 +12,16 @@ public class DeleteAdbOperationCommandHandler : IRequestHandler<DeleteAdbOperati
{
private readonly IAdbOperationRepository _adbOperationRepository;
private readonly ILogger<DeleteAdbOperationCommandHandler> _logger;
private readonly IUnitOfWork _unitOfWork;
public DeleteAdbOperationCommandHandler(
IAdbOperationRepository adbOperationRepository,
ILogger<DeleteAdbOperationCommandHandler> logger)
ILogger<DeleteAdbOperationCommandHandler> logger,
IUnitOfWork unitOfWork)
{
_adbOperationRepository = adbOperationRepository;
_logger = logger;
_unitOfWork = unitOfWork;
}
public async Task<OperationResult<bool>> Handle(
@ -38,6 +42,9 @@ public class DeleteAdbOperationCommandHandler : IRequestHandler<DeleteAdbOperati
// 删除ADB操作
await _adbOperationRepository.DeleteOperationAsync(request.Id, cancellationToken);
// 确保数据被持久化到数据库
await _unitOfWork.SaveChangesAsync(cancellationToken);
_logger.LogInformation("ADB操作删除成功,ID: {Id}", request.Id);

5
src/X1.Application/Features/AdbOperations/Commands/UpdateAdbOperation/UpdateAdbOperationCommand.cs

@ -13,11 +13,6 @@ public class UpdateAdbOperationCommand : IRequest<OperationResult<UpdateAdbOpera
/// </summary>
public string Id { get; set; } = string.Empty;
/// <summary>
/// 设备ID
/// </summary>
public string DeviceId { get; set; } = string.Empty;
/// <summary>
/// 执行的ADB命令
/// </summary>

21
src/X1.Application/Features/AdbOperations/Commands/UpdateAdbOperation/UpdateAdbOperationCommandHandler.cs

@ -1,5 +1,6 @@
using CellularManagement.Domain.Repositories.Terminal;
using CellularManagement.Domain.Services;
using CellularManagement.Domain.Repositories.Base;
using MediatR;
using Microsoft.Extensions.Logging;
using CellularManagement.Domain.Common;
@ -14,23 +15,26 @@ public class UpdateAdbOperationCommandHandler : IRequestHandler<UpdateAdbOperati
private readonly IAdbOperationRepository _adbOperationRepository;
private readonly ILogger<UpdateAdbOperationCommandHandler> _logger;
private readonly ICurrentUserService _currentUserService;
private readonly IUnitOfWork _unitOfWork;
public UpdateAdbOperationCommandHandler(
IAdbOperationRepository adbOperationRepository,
ILogger<UpdateAdbOperationCommandHandler> logger,
ICurrentUserService currentUserService)
ICurrentUserService currentUserService,
IUnitOfWork unitOfWork)
{
_adbOperationRepository = adbOperationRepository;
_logger = logger;
_currentUserService = currentUserService;
_unitOfWork = unitOfWork;
}
public async Task<OperationResult<UpdateAdbOperationResponse>> Handle(
UpdateAdbOperationCommand request,
CancellationToken cancellationToken)
{
_logger.LogInformation("开始更新ADB操作,ID: {Id}, 设备ID: {DeviceId}, 命令: {Command}, 路径: {Path}",
request.Id, request.DeviceId, request.Command, request.Path);
_logger.LogInformation("开始更新ADB操作,ID: {Id}, 命令: {Command}, 路径: {Path}",
request.Id, request.Command, request.Path);
try
{
@ -45,9 +49,9 @@ public class UpdateAdbOperationCommandHandler : IRequestHandler<UpdateAdbOperati
// 获取当前用户
var currentUser = _currentUserService.GetCurrentUserId();
// 更新ADB操作
// 更新ADB操作(不传递DeviceId,因为不允许修改)
existingOperation.Update(
request.DeviceId,
existingOperation.DeviceId, // 使用现有的DeviceId,不允许修改
request.Command,
request.Description,
request.Path,
@ -59,6 +63,9 @@ public class UpdateAdbOperationCommandHandler : IRequestHandler<UpdateAdbOperati
// 保存到数据库
_adbOperationRepository.UpdateOperation(existingOperation);
// 确保数据被持久化到数据库
await _unitOfWork.SaveChangesAsync(cancellationToken);
// 构建响应
var response = new UpdateAdbOperationResponse
@ -85,8 +92,8 @@ public class UpdateAdbOperationCommandHandler : IRequestHandler<UpdateAdbOperati
}
catch (Exception ex)
{
_logger.LogError(ex, "ADB操作更新失败,ID: {Id}, 设备ID: {DeviceId}, 命令: {Command}",
request.Id, request.DeviceId, request.Command);
_logger.LogError(ex, "ADB操作更新失败,ID: {Id}, 命令: {Command}",
request.Id, request.Command);
return OperationResult<UpdateAdbOperationResponse>.CreateFailure("更新ADB操作时发生错误");
}
}

9
src/X1.Application/Features/AtOperations/Commands/CreateAtOperation/CreateAtOperationCommandHandler.cs

@ -2,6 +2,7 @@ using CellularManagement.Domain.Common;
using CellularManagement.Domain.Entities.Terminal;
using CellularManagement.Domain.Repositories.Terminal;
using CellularManagement.Domain.Services;
using CellularManagement.Domain.Repositories.Base;
using MediatR;
using Microsoft.Extensions.Logging;
@ -15,15 +16,18 @@ public class CreateAtOperationCommandHandler : IRequestHandler<CreateAtOperation
private readonly IAtOperationRepository _atOperationRepository;
private readonly ILogger<CreateAtOperationCommandHandler> _logger;
private readonly ICurrentUserService _currentUserService;
private readonly IUnitOfWork _unitOfWork;
public CreateAtOperationCommandHandler(
IAtOperationRepository atOperationRepository,
ILogger<CreateAtOperationCommandHandler> logger,
ICurrentUserService currentUserService)
ICurrentUserService currentUserService,
IUnitOfWork unitOfWork)
{
_atOperationRepository = atOperationRepository;
_logger = logger;
_currentUserService = currentUserService;
_unitOfWork = unitOfWork;
}
public async Task<OperationResult<CreateAtOperationResponse>> Handle(
@ -55,6 +59,9 @@ public class CreateAtOperationCommandHandler : IRequestHandler<CreateAtOperation
// 保存到数据库
var savedOperation = await _atOperationRepository.AddOperationAsync(atOperation, cancellationToken);
// 确保数据被持久化到数据库
await _unitOfWork.SaveChangesAsync(cancellationToken);
// 构建响应
var response = new CreateAtOperationResponse

9
src/X1.Application/Features/AtOperations/Commands/DeleteAtOperation/DeleteAtOperationCommandHandler.cs

@ -1,5 +1,6 @@
using CellularManagement.Domain.Common;
using CellularManagement.Domain.Repositories.Terminal;
using CellularManagement.Domain.Repositories.Base;
using MediatR;
using Microsoft.Extensions.Logging;
@ -12,13 +13,16 @@ public class DeleteAtOperationCommandHandler : IRequestHandler<DeleteAtOperation
{
private readonly IAtOperationRepository _atOperationRepository;
private readonly ILogger<DeleteAtOperationCommandHandler> _logger;
private readonly IUnitOfWork _unitOfWork;
public DeleteAtOperationCommandHandler(
IAtOperationRepository atOperationRepository,
ILogger<DeleteAtOperationCommandHandler> logger)
ILogger<DeleteAtOperationCommandHandler> logger,
IUnitOfWork unitOfWork)
{
_atOperationRepository = atOperationRepository;
_logger = logger;
_unitOfWork = unitOfWork;
}
public async Task<OperationResult<bool>> Handle(
@ -39,6 +43,9 @@ public class DeleteAtOperationCommandHandler : IRequestHandler<DeleteAtOperation
// 删除AT操作
await _atOperationRepository.DeleteOperationAsync(request.Id, cancellationToken);
// 确保数据被持久化到数据库
await _unitOfWork.SaveChangesAsync(cancellationToken);
_logger.LogInformation("AT操作删除成功,ID: {Id}", request.Id);

13
src/X1.Application/Features/AtOperations/Commands/UpdateAtOperation/UpdateAtOperationCommandHandler.cs

@ -1,6 +1,7 @@
using CellularManagement.Domain.Common;
using CellularManagement.Domain.Repositories.Terminal;
using CellularManagement.Domain.Services;
using CellularManagement.Domain.Repositories.Base;
using MediatR;
using Microsoft.Extensions.Logging;
@ -14,15 +15,18 @@ public class UpdateAtOperationCommandHandler : IRequestHandler<UpdateAtOperation
private readonly IAtOperationRepository _atOperationRepository;
private readonly ILogger<UpdateAtOperationCommandHandler> _logger;
private readonly ICurrentUserService _currentUserService;
private readonly IUnitOfWork _unitOfWork;
public UpdateAtOperationCommandHandler(
IAtOperationRepository atOperationRepository,
ILogger<UpdateAtOperationCommandHandler> logger,
ICurrentUserService currentUserService)
ICurrentUserService currentUserService,
IUnitOfWork unitOfWork)
{
_atOperationRepository = atOperationRepository;
_logger = logger;
_currentUserService = currentUserService;
_unitOfWork = unitOfWork;
}
public async Task<OperationResult<UpdateAtOperationResponse>> Handle(
@ -62,6 +66,9 @@ public class UpdateAtOperationCommandHandler : IRequestHandler<UpdateAtOperation
// 保存到数据库
_atOperationRepository.UpdateOperation(existingOperation);
// 确保数据被持久化到数据库
await _unitOfWork.SaveChangesAsync(cancellationToken);
// 构建响应
var response = new UpdateAtOperationResponse
@ -91,8 +98,8 @@ public class UpdateAtOperationCommandHandler : IRequestHandler<UpdateAtOperation
}
catch (Exception ex)
{
_logger.LogError(ex, "AT操作更新失败,ID: {Id}, 设备ID: {DeviceId}",
request.Id, request.DeviceId);
_logger.LogError(ex, "AT操作更新失败,ID: {Id}, 设备ID: {DeviceId}, 端口: {Port}",
request.Id, request.DeviceId, request.Port);
return OperationResult<UpdateAtOperationResponse>.CreateFailure("更新AT操作时发生错误");
}
}

16
src/X1.Domain/Entities/Terminal/AdbOperation.cs

@ -85,8 +85,9 @@ public class AdbOperation : AuditableEntity
if (string.IsNullOrWhiteSpace(description))
throw new ArgumentException("操作描述不能为空", nameof(description));
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("路径不能为空", nameof(path));
// 当启用绝对路径时,路径不能为空
if (useAbsolutePath && string.IsNullOrWhiteSpace(path))
throw new ArgumentException("启用绝对路径时,路径不能为空", nameof(path));
if (string.IsNullOrWhiteSpace(createdBy))
throw new ArgumentException("创建人不能为空", nameof(createdBy));
@ -138,14 +139,19 @@ public class AdbOperation : AuditableEntity
if (string.IsNullOrWhiteSpace(deviceId))
throw new ArgumentException("设备ID不能为空", nameof(deviceId));
// 设备ID不允许修改
if (!string.Equals(DeviceId, deviceId.Trim(), StringComparison.OrdinalIgnoreCase))
throw new ArgumentException("设备ID不允许修改", nameof(deviceId));
if (string.IsNullOrWhiteSpace(command))
throw new ArgumentException("ADB命令不能为空", nameof(command));
if (string.IsNullOrWhiteSpace(description))
throw new ArgumentException("操作描述不能为空", nameof(description));
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("路径不能为空", nameof(path));
// 当启用绝对路径时,路径不能为空
if (useAbsolutePath && string.IsNullOrWhiteSpace(path))
throw new ArgumentException("启用绝对路径时,路径不能为空", nameof(path));
if (string.IsNullOrWhiteSpace(updatedBy))
throw new ArgumentException("更新人不能为空", nameof(updatedBy));
@ -153,7 +159,7 @@ public class AdbOperation : AuditableEntity
if (waitTimeMs < 0)
throw new ArgumentException("等待时间不能为负数", nameof(waitTimeMs));
DeviceId = deviceId.Trim();
// 不更新DeviceId,保持原有值
Command = command.Trim();
Description = description.Trim();
Path = path.Trim();

4
src/X1.Infrastructure/Configurations/Terminal/AdbOperationConfiguration.cs

@ -41,9 +41,9 @@ public class AdbOperationConfiguration : IEntityTypeConfiguration<AdbOperation>
// 路径字段
builder.Property(x => x.Path)
.IsRequired()
.IsRequired(false)
.HasMaxLength(500)
.HasComment("命令执行时所依赖的路径");
.HasComment("命令执行时所依赖的路径(当启用绝对路径时必填)");
// 绝对路径字段
builder.Property(x => x.UseAbsolutePath)

1625
src/X1.Infrastructure/Migrations/20250820020118_UpdateAdbOperationPathNullable.Designer.cs

File diff suppressed because it is too large

44
src/X1.Infrastructure/Migrations/20250820020118_UpdateAdbOperationPathNullable.cs

@ -0,0 +1,44 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace X1.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class UpdateAdbOperationPathNullable : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Path",
table: "tb_adboperations",
type: "character varying(500)",
maxLength: 500,
nullable: true,
comment: "命令执行时所依赖的路径(当启用绝对路径时必填)",
oldClrType: typeof(string),
oldType: "character varying(500)",
oldMaxLength: 500,
oldComment: "命令执行时所依赖的路径");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Path",
table: "tb_adboperations",
type: "character varying(500)",
maxLength: 500,
nullable: false,
defaultValue: "",
comment: "命令执行时所依赖的路径",
oldClrType: typeof(string),
oldType: "character varying(500)",
oldMaxLength: 500,
oldNullable: true,
oldComment: "命令执行时所依赖的路径(当启用绝对路径时必填)");
}
}
}

3
src/X1.Infrastructure/Migrations/AppDbContextModelSnapshot.cs

@ -1034,10 +1034,9 @@ namespace X1.Infrastructure.Migrations
.HasComment("是否启用");
b.Property<string>("Path")
.IsRequired()
.HasMaxLength(500)
.HasColumnType("character varying(500)")
.HasComment("命令执行时所依赖的路径");
.HasComment("命令执行时所依赖的路径(当启用绝对路径时必填)");
b.Property<byte[]>("ScreenshotData")
.HasColumnType("BYTEA")

4
src/X1.WebAPI/Properties/launchSettings.json

@ -24,8 +24,8 @@
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7268;http://localhost:5000;https://192.168.1.233:7268;http://192.168.1.233:5000",
//"applicationUrl": "https://localhost:7268;http://localhost:5000",
//"applicationUrl": "https://localhost:7268;http://localhost:5000;https://192.168.1.233:7268;http://192.168.1.233:5000",
"applicationUrl": "https://localhost:7268;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}

469
src/X1.WebUI/package-lock.json

@ -48,6 +48,7 @@
"react-hook-form": "^7.50.0",
"react-icons": "^5.5.0",
"react-router-dom": "^6.22.0",
"reactflow": "^11.11.4",
"recoil": "^0.7.7",
"tailwind-merge": "^2.2.1",
"tailwindcss-animate": "^1.0.7",
@ -2023,6 +2024,102 @@
"integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==",
"license": "MIT"
},
"node_modules/@reactflow/background": {
"version": "11.3.14",
"resolved": "https://registry.npmmirror.com/@reactflow/background/-/background-11.3.14.tgz",
"integrity": "sha512-Gewd7blEVT5Lh6jqrvOgd4G6Qk17eGKQfsDXgyRSqM+CTwDqRldG2LsWN4sNeno6sbqVIC2fZ+rAUBFA9ZEUDA==",
"dependencies": {
"@reactflow/core": "11.11.4",
"classcat": "^5.0.3",
"zustand": "^4.4.1"
},
"peerDependencies": {
"react": ">=17",
"react-dom": ">=17"
}
},
"node_modules/@reactflow/controls": {
"version": "11.2.14",
"resolved": "https://registry.npmmirror.com/@reactflow/controls/-/controls-11.2.14.tgz",
"integrity": "sha512-MiJp5VldFD7FrqaBNIrQ85dxChrG6ivuZ+dcFhPQUwOK3HfYgX2RHdBua+gx+40p5Vw5It3dVNp/my4Z3jF0dw==",
"dependencies": {
"@reactflow/core": "11.11.4",
"classcat": "^5.0.3",
"zustand": "^4.4.1"
},
"peerDependencies": {
"react": ">=17",
"react-dom": ">=17"
}
},
"node_modules/@reactflow/core": {
"version": "11.11.4",
"resolved": "https://registry.npmmirror.com/@reactflow/core/-/core-11.11.4.tgz",
"integrity": "sha512-H4vODklsjAq3AMq6Np4LE12i1I4Ta9PrDHuBR9GmL8uzTt2l2jh4CiQbEMpvMDcp7xi4be0hgXj+Ysodde/i7Q==",
"dependencies": {
"@types/d3": "^7.4.0",
"@types/d3-drag": "^3.0.1",
"@types/d3-selection": "^3.0.3",
"@types/d3-zoom": "^3.0.1",
"classcat": "^5.0.3",
"d3-drag": "^3.0.0",
"d3-selection": "^3.0.0",
"d3-zoom": "^3.0.0",
"zustand": "^4.4.1"
},
"peerDependencies": {
"react": ">=17",
"react-dom": ">=17"
}
},
"node_modules/@reactflow/minimap": {
"version": "11.7.14",
"resolved": "https://registry.npmmirror.com/@reactflow/minimap/-/minimap-11.7.14.tgz",
"integrity": "sha512-mpwLKKrEAofgFJdkhwR5UQ1JYWlcAAL/ZU/bctBkuNTT1yqV+y0buoNVImsRehVYhJwffSWeSHaBR5/GJjlCSQ==",
"dependencies": {
"@reactflow/core": "11.11.4",
"@types/d3-selection": "^3.0.3",
"@types/d3-zoom": "^3.0.1",
"classcat": "^5.0.3",
"d3-selection": "^3.0.0",
"d3-zoom": "^3.0.0",
"zustand": "^4.4.1"
},
"peerDependencies": {
"react": ">=17",
"react-dom": ">=17"
}
},
"node_modules/@reactflow/node-resizer": {
"version": "2.2.14",
"resolved": "https://registry.npmmirror.com/@reactflow/node-resizer/-/node-resizer-2.2.14.tgz",
"integrity": "sha512-fwqnks83jUlYr6OHcdFEedumWKChTHRGw/kbCxj0oqBd+ekfs+SIp4ddyNU0pdx96JIm5iNFS0oNrmEiJbbSaA==",
"dependencies": {
"@reactflow/core": "11.11.4",
"classcat": "^5.0.4",
"d3-drag": "^3.0.0",
"d3-selection": "^3.0.0",
"zustand": "^4.4.1"
},
"peerDependencies": {
"react": ">=17",
"react-dom": ">=17"
}
},
"node_modules/@reactflow/node-toolbar": {
"version": "1.3.14",
"resolved": "https://registry.npmmirror.com/@reactflow/node-toolbar/-/node-toolbar-1.3.14.tgz",
"integrity": "sha512-rbynXQnH/xFNu4P9H+hVqlEUafDCkEoCy0Dg9mG22Sg+rY/0ck6KkrAQrYrTgXusd+cEJOMK0uOOFCK2/5rSGQ==",
"dependencies": {
"@reactflow/core": "11.11.4",
"classcat": "^5.0.3",
"zustand": "^4.4.1"
},
"peerDependencies": {
"react": ">=17",
"react-dom": ">=17"
}
},
"node_modules/@remix-run/router": {
"version": "1.23.0",
"resolved": "https://registry.npmmirror.com/@remix-run/router/-/router-1.23.0.tgz",
@ -2136,6 +2233,228 @@
"@babel/types": "^7.20.7"
}
},
"node_modules/@types/d3": {
"version": "7.4.3",
"resolved": "https://registry.npmmirror.com/@types/d3/-/d3-7.4.3.tgz",
"integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==",
"dependencies": {
"@types/d3-array": "*",
"@types/d3-axis": "*",
"@types/d3-brush": "*",
"@types/d3-chord": "*",
"@types/d3-color": "*",
"@types/d3-contour": "*",
"@types/d3-delaunay": "*",
"@types/d3-dispatch": "*",
"@types/d3-drag": "*",
"@types/d3-dsv": "*",
"@types/d3-ease": "*",
"@types/d3-fetch": "*",
"@types/d3-force": "*",
"@types/d3-format": "*",
"@types/d3-geo": "*",
"@types/d3-hierarchy": "*",
"@types/d3-interpolate": "*",
"@types/d3-path": "*",
"@types/d3-polygon": "*",
"@types/d3-quadtree": "*",
"@types/d3-random": "*",
"@types/d3-scale": "*",
"@types/d3-scale-chromatic": "*",
"@types/d3-selection": "*",
"@types/d3-shape": "*",
"@types/d3-time": "*",
"@types/d3-time-format": "*",
"@types/d3-timer": "*",
"@types/d3-transition": "*",
"@types/d3-zoom": "*"
}
},
"node_modules/@types/d3-array": {
"version": "3.2.1",
"resolved": "https://registry.npmmirror.com/@types/d3-array/-/d3-array-3.2.1.tgz",
"integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="
},
"node_modules/@types/d3-axis": {
"version": "3.0.6",
"resolved": "https://registry.npmmirror.com/@types/d3-axis/-/d3-axis-3.0.6.tgz",
"integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==",
"dependencies": {
"@types/d3-selection": "*"
}
},
"node_modules/@types/d3-brush": {
"version": "3.0.6",
"resolved": "https://registry.npmmirror.com/@types/d3-brush/-/d3-brush-3.0.6.tgz",
"integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==",
"dependencies": {
"@types/d3-selection": "*"
}
},
"node_modules/@types/d3-chord": {
"version": "3.0.6",
"resolved": "https://registry.npmmirror.com/@types/d3-chord/-/d3-chord-3.0.6.tgz",
"integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg=="
},
"node_modules/@types/d3-color": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/@types/d3-color/-/d3-color-3.1.3.tgz",
"integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="
},
"node_modules/@types/d3-contour": {
"version": "3.0.6",
"resolved": "https://registry.npmmirror.com/@types/d3-contour/-/d3-contour-3.0.6.tgz",
"integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==",
"dependencies": {
"@types/d3-array": "*",
"@types/geojson": "*"
}
},
"node_modules/@types/d3-delaunay": {
"version": "6.0.4",
"resolved": "https://registry.npmmirror.com/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz",
"integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw=="
},
"node_modules/@types/d3-dispatch": {
"version": "3.0.7",
"resolved": "https://registry.npmmirror.com/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz",
"integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA=="
},
"node_modules/@types/d3-drag": {
"version": "3.0.7",
"resolved": "https://registry.npmmirror.com/@types/d3-drag/-/d3-drag-3.0.7.tgz",
"integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==",
"dependencies": {
"@types/d3-selection": "*"
}
},
"node_modules/@types/d3-dsv": {
"version": "3.0.7",
"resolved": "https://registry.npmmirror.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz",
"integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g=="
},
"node_modules/@types/d3-ease": {
"version": "3.0.2",
"resolved": "https://registry.npmmirror.com/@types/d3-ease/-/d3-ease-3.0.2.tgz",
"integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="
},
"node_modules/@types/d3-fetch": {
"version": "3.0.7",
"resolved": "https://registry.npmmirror.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz",
"integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==",
"dependencies": {
"@types/d3-dsv": "*"
}
},
"node_modules/@types/d3-force": {
"version": "3.0.10",
"resolved": "https://registry.npmmirror.com/@types/d3-force/-/d3-force-3.0.10.tgz",
"integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw=="
},
"node_modules/@types/d3-format": {
"version": "3.0.4",
"resolved": "https://registry.npmmirror.com/@types/d3-format/-/d3-format-3.0.4.tgz",
"integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g=="
},
"node_modules/@types/d3-geo": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/@types/d3-geo/-/d3-geo-3.1.0.tgz",
"integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==",
"dependencies": {
"@types/geojson": "*"
}
},
"node_modules/@types/d3-hierarchy": {
"version": "3.1.7",
"resolved": "https://registry.npmmirror.com/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz",
"integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg=="
},
"node_modules/@types/d3-interpolate": {
"version": "3.0.4",
"resolved": "https://registry.npmmirror.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
"integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
"dependencies": {
"@types/d3-color": "*"
}
},
"node_modules/@types/d3-path": {
"version": "3.1.1",
"resolved": "https://registry.npmmirror.com/@types/d3-path/-/d3-path-3.1.1.tgz",
"integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg=="
},
"node_modules/@types/d3-polygon": {
"version": "3.0.2",
"resolved": "https://registry.npmmirror.com/@types/d3-polygon/-/d3-polygon-3.0.2.tgz",
"integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA=="
},
"node_modules/@types/d3-quadtree": {
"version": "3.0.6",
"resolved": "https://registry.npmmirror.com/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz",
"integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg=="
},
"node_modules/@types/d3-random": {
"version": "3.0.3",
"resolved": "https://registry.npmmirror.com/@types/d3-random/-/d3-random-3.0.3.tgz",
"integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ=="
},
"node_modules/@types/d3-scale": {
"version": "4.0.9",
"resolved": "https://registry.npmmirror.com/@types/d3-scale/-/d3-scale-4.0.9.tgz",
"integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==",
"dependencies": {
"@types/d3-time": "*"
}
},
"node_modules/@types/d3-scale-chromatic": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz",
"integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ=="
},
"node_modules/@types/d3-selection": {
"version": "3.0.11",
"resolved": "https://registry.npmmirror.com/@types/d3-selection/-/d3-selection-3.0.11.tgz",
"integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w=="
},
"node_modules/@types/d3-shape": {
"version": "3.1.7",
"resolved": "https://registry.npmmirror.com/@types/d3-shape/-/d3-shape-3.1.7.tgz",
"integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==",
"dependencies": {
"@types/d3-path": "*"
}
},
"node_modules/@types/d3-time": {
"version": "3.0.4",
"resolved": "https://registry.npmmirror.com/@types/d3-time/-/d3-time-3.0.4.tgz",
"integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g=="
},
"node_modules/@types/d3-time-format": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/@types/d3-time-format/-/d3-time-format-4.0.3.tgz",
"integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg=="
},
"node_modules/@types/d3-timer": {
"version": "3.0.2",
"resolved": "https://registry.npmmirror.com/@types/d3-timer/-/d3-timer-3.0.2.tgz",
"integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="
},
"node_modules/@types/d3-transition": {
"version": "3.0.9",
"resolved": "https://registry.npmmirror.com/@types/d3-transition/-/d3-transition-3.0.9.tgz",
"integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==",
"dependencies": {
"@types/d3-selection": "*"
}
},
"node_modules/@types/d3-zoom": {
"version": "3.0.8",
"resolved": "https://registry.npmmirror.com/@types/d3-zoom/-/d3-zoom-3.0.8.tgz",
"integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==",
"dependencies": {
"@types/d3-interpolate": "*",
"@types/d3-selection": "*"
}
},
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz",
@ -2143,6 +2462,11 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/geojson": {
"version": "7946.0.16",
"resolved": "https://registry.npmmirror.com/@types/geojson/-/geojson-7946.0.16.tgz",
"integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg=="
},
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz",
@ -2862,6 +3186,11 @@
"url": "https://polar.sh/cva"
}
},
"node_modules/classcat": {
"version": "5.0.5",
"resolved": "https://registry.npmmirror.com/classcat/-/classcat-5.0.5.tgz",
"integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w=="
},
"node_modules/cli-cursor": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/cli-cursor/-/cli-cursor-4.0.0.tgz",
@ -2997,6 +3326,102 @@
"devOptional": true,
"license": "MIT"
},
"node_modules/d3-color": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/d3-color/-/d3-color-3.1.0.tgz",
"integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-dispatch": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
"integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-drag": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/d3-drag/-/d3-drag-3.0.0.tgz",
"integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
"dependencies": {
"d3-dispatch": "1 - 3",
"d3-selection": "3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-ease": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-ease/-/d3-ease-3.0.1.tgz",
"integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-interpolate": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
"integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
"dependencies": {
"d3-color": "1 - 3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-selection": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/d3-selection/-/d3-selection-3.0.0.tgz",
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-timer": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-timer/-/d3-timer-3.0.1.tgz",
"integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
"engines": {
"node": ">=12"
}
},
"node_modules/d3-transition": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/d3-transition/-/d3-transition-3.0.1.tgz",
"integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
"dependencies": {
"d3-color": "1 - 3",
"d3-dispatch": "1 - 3",
"d3-ease": "1 - 3",
"d3-interpolate": "1 - 3",
"d3-timer": "1 - 3"
},
"engines": {
"node": ">=12"
},
"peerDependencies": {
"d3-selection": "2 - 3"
}
},
"node_modules/d3-zoom": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/d3-zoom/-/d3-zoom-3.0.0.tgz",
"integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
"dependencies": {
"d3-dispatch": "1 - 3",
"d3-drag": "2 - 3",
"d3-interpolate": "1 - 3",
"d3-selection": "2 - 3",
"d3-transition": "2 - 3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/data-uri-to-buffer": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
@ -5366,6 +5791,23 @@
}
}
},
"node_modules/reactflow": {
"version": "11.11.4",
"resolved": "https://registry.npmmirror.com/reactflow/-/reactflow-11.11.4.tgz",
"integrity": "sha512-70FOtJkUWH3BAOsN+LU9lCrKoKbtOPnz2uq0CV2PLdNSwxTXOhCbsZr50GmZ+Rtw3jx8Uv7/vBFtCGixLfd4Og==",
"dependencies": {
"@reactflow/background": "11.3.14",
"@reactflow/controls": "11.2.14",
"@reactflow/core": "11.11.4",
"@reactflow/minimap": "11.7.14",
"@reactflow/node-resizer": "2.2.14",
"@reactflow/node-toolbar": "1.3.14"
},
"peerDependencies": {
"react": ">=17",
"react-dom": ">=17"
}
},
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz",
@ -6429,6 +6871,33 @@
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/zustand": {
"version": "4.5.7",
"resolved": "https://registry.npmmirror.com/zustand/-/zustand-4.5.7.tgz",
"integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==",
"dependencies": {
"use-sync-external-store": "^1.2.2"
},
"engines": {
"node": ">=12.7.0"
},
"peerDependencies": {
"@types/react": ">=16.8",
"immer": ">=9.0.6",
"react": ">=16.8"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"immer": {
"optional": true
},
"react": {
"optional": true
}
}
}
}
}

3
src/X1.WebUI/src/constants/api.ts

@ -9,6 +9,9 @@ export const API_PATHS = {
// AT操作相关
AT_OPERATIONS: '/at-operations',
// ADB操作相关
ADB_OPERATIONS: '/adb-operations',
// 协议相关
PROTOCOLS: '/protocolversions',
PROTOCOL_LOGS: '/protocolLogs',

442
src/X1.WebUI/src/pages/adb-operations/AdbOperationDrawer.tsx

@ -0,0 +1,442 @@
import React, { useEffect, useState } from 'react';
import { AdbOperation, CreateAdbOperationRequest, UpdateAdbOperationRequest } from '@/services/adbOperationsService';
import { Drawer, DrawerHeader, DrawerContent, DrawerFooter } from '@/components/ui/drawer';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Checkbox } from '@/components/ui/checkbox';
import { getTerminalDevices, TerminalDevice } from '@/services/terminalDeviceService';
import { Plus, Trash2, X } from 'lucide-react';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
interface CommandItem {
command: string;
waitTimeMs: number;
}
interface AdbOperationDrawerProps {
open: boolean;
onOpenChange: (open: boolean) => void;
onSubmit: (data: CreateAdbOperationRequest | UpdateAdbOperationRequest) => Promise<void>;
initialData?: AdbOperation;
isEdit?: boolean;
isSubmitting?: boolean;
}
export default function AdbOperationDrawer({
open,
onOpenChange,
onSubmit,
initialData,
isEdit = false,
isSubmitting = false
}: AdbOperationDrawerProps) {
// 解析初始命令数据
const parseInitialCommands = (): CommandItem[] => {
if (initialData?.command) {
try {
return JSON.parse(initialData.command);
} catch {
// 如果不是JSON格式,当作单条命令处理
return [{ command: initialData.command, waitTimeMs: initialData.waitTimeMs || 0 }];
}
}
return [{ command: '', waitTimeMs: 0 }];
};
const [commands, setCommands] = useState<CommandItem[]>(parseInitialCommands());
const [formData, setFormData] = useState<CreateAdbOperationRequest>({
command: '',
description: '',
path: '',
useAbsolutePath: false,
isEnabled: true,
waitTimeMs: 0,
deviceId: ''
});
const [errors, setErrors] = useState<Record<string, string>>({});
const [devices, setDevices] = useState<TerminalDevice[]>([]);
const [loadingDevices, setLoadingDevices] = useState(false);
// 当抽屉打开时,初始化表单数据
useEffect(() => {
if (open) {
if (initialData && isEdit) {
const parsedCommands = parseInitialCommands();
setCommands(parsedCommands);
setFormData({
command: initialData.command || '',
description: initialData.description || '',
path: initialData.path || '',
useAbsolutePath: initialData.useAbsolutePath ?? false,
isEnabled: initialData.isEnabled ?? true,
waitTimeMs: initialData.waitTimeMs || 0,
deviceId: initialData.deviceId || ''
});
} else {
// 重置表单
setCommands([{ command: '', waitTimeMs: 0 }]);
setFormData({
command: '',
description: '',
path: '',
useAbsolutePath: false,
isEnabled: true,
waitTimeMs: 0,
deviceId: ''
});
}
setErrors({});
}
}, [open, initialData, isEdit]);
// 加载设备列表
useEffect(() => {
if (open) {
const loadDevices = async () => {
setLoadingDevices(true);
try {
const result = await getTerminalDevices({ pageSize: 100 }); // 获取所有设备
if (result.isSuccess && result.data) {
setDevices(result.data.terminalDevices || []);
}
} catch (error) {
console.error('加载设备列表失败:', error);
} finally {
setLoadingDevices(false);
}
};
loadDevices();
}
}, [open]);
// 更新命令列表
const updateCommands = (newCommands: CommandItem[]) => {
setCommands(newCommands);
// 将命令列表转换为JSON字符串
const commandJson = JSON.stringify(newCommands);
setFormData(prev => ({ ...prev, command: commandJson }));
};
// 添加新命令
const addCommand = () => {
updateCommands([...commands, { command: '', waitTimeMs: 0 }]);
};
// 删除命令
const removeCommand = (index: number) => {
if (commands.length > 1) {
const newCommands = commands.filter((_, i) => i !== index);
updateCommands(newCommands);
}
};
// 更新单个命令
const updateCommand = (index: number, field: keyof CommandItem, value: string | number) => {
const newCommands = [...commands];
newCommands[index] = { ...newCommands[index], [field]: value };
updateCommands(newCommands);
};
// 表单验证
const validateForm = (): boolean => {
const newErrors: Record<string, string> = {};
// 验证设备ID
if (!formData.deviceId.trim()) {
newErrors.deviceId = '请选择设备';
}
// 验证命令列表
if (commands.length === 0) {
newErrors.commands = '至少需要一条ADB命令';
} else {
for (let i = 0; i < commands.length; i++) {
if (!commands[i].command.trim()) {
newErrors[`command_${i}`] = `${i + 1}条命令不能为空`;
}
if (commands[i].waitTimeMs < 0) {
newErrors[`waitTime_${i}`] = `${i + 1}条命令的等待时间不能为负数`;
}
}
}
// 验证ADB路径 - 只有在使用绝对路径时才必填
if (formData.useAbsolutePath && !formData.path.trim()) {
newErrors.path = '使用绝对路径时必须指定ADB路径';
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (isSubmitting) return;
if (!validateForm()) {
return;
}
// 提交前清理数据
const submitData = {
...formData,
command: formData.command, // 已经是JSON字符串
description: formData.description.trim(),
path: formData.path.trim()
};
await onSubmit(submitData);
};
const handleInputChange = (field: keyof CreateAdbOperationRequest, value: string | number | boolean) => {
setFormData(prev => ({ ...prev, [field]: value }));
// 清除对应字段的错误
if (errors[field]) {
setErrors(prev => ({ ...prev, [field]: '' }));
}
};
return (
<Drawer open={open} onOpenChange={onOpenChange}>
<div className="flex flex-col h-full">
<DrawerHeader className="flex-shrink-0">
<div className="flex items-center justify-between w-full">
<h2 className="text-lg font-semibold">
{isEdit ? '编辑ADB操作' : '创建ADB操作'}
</h2>
<Button
variant="ghost"
size="sm"
onClick={() => onOpenChange(false)}
className="h-8 w-8 p-0"
>
<X className="h-4 w-4" />
</Button>
</div>
</DrawerHeader>
<form onSubmit={handleSubmit} className="flex flex-col flex-1 min-h-0">
<DrawerContent className="flex flex-col flex-1 min-h-0 p-0 overflow-hidden">
{/* 固定区域:设备选择 */}
<div className="space-y-2 flex-shrink-0 p-4 pb-2">
<Label className="text-sm font-medium">
<span className="text-red-500">*</span>
</Label>
<Select
value={formData.deviceId}
onValueChange={(value) => handleInputChange('deviceId', value)}
disabled={isSubmitting || loadingDevices}
>
<SelectTrigger className={errors.deviceId ? 'border-red-500 focus:border-red-500' : ''}>
<SelectValue placeholder="请选择设备" />
</SelectTrigger>
<SelectContent>
{devices.map((device) => (
<SelectItem key={device.serial} value={device.serial}>
{device.alias || device.name} - {device.brand} ({device.serial})
</SelectItem>
))}
</SelectContent>
</Select>
{errors.deviceId && (
<p className="text-sm text-red-500">{errors.deviceId}</p>
)}
<p className="text-xs text-muted-foreground">
ADB操作的设备ID将与TerminalDevice的Serial字段关联
</p>
</div>
{/* 命令列表区域 */}
<div className={`px-4 ${commands.length > 2 ? 'flex-1 min-h-0 flex flex-col' : ''}`}>
<div className="flex items-center justify-between flex-shrink-0 mb-2">
<Label className="text-sm font-medium">
ADB命令列表 <span className="text-red-500">*</span>
</Label>
<Button
type="button"
variant="outline"
size="sm"
onClick={addCommand}
disabled={isSubmitting}
className="flex items-center gap-1"
>
<Plus className="h-4 w-4" />
</Button>
</div>
{errors.commands && (
<p className="text-sm text-red-500 flex-shrink-0 mb-2">{errors.commands}</p>
)}
{/* 命令列表区域 - 根据命令数量决定是否可滚动 */}
<div className={commands.length > 2 ? 'flex-1 overflow-y-auto' : ''}>
<div className={`space-y-3 ${commands.length > 2 ? 'pr-2' : ''}`}>
{commands.map((cmd, index) => (
<div key={index} className="flex gap-3 items-start p-3 border rounded-lg bg-background">
<div className="flex-1 space-y-3">
<div>
<Label className="text-xs text-muted-foreground">
{index + 1}
</Label>
<Input
value={cmd.command}
onChange={e => updateCommand(index, 'command', e.target.value)}
placeholder="例如: adb devices, adb shell ls, adb install app.apk"
disabled={isSubmitting}
className={errors[`command_${index}`] ? 'border-red-500 focus:border-red-500' : ''}
/>
{errors[`command_${index}`] && (
<p className="text-sm text-red-500">{errors[`command_${index}`]}</p>
)}
</div>
<div>
<Label className="text-xs text-muted-foreground">
()
</Label>
<Input
type="number"
min="0"
step="100"
value={cmd.waitTimeMs}
onChange={e => updateCommand(index, 'waitTimeMs', parseInt(e.target.value) || 0)}
placeholder="例如: 1000"
disabled={isSubmitting}
className={errors[`waitTime_${index}`] ? 'border-red-500 focus:border-red-500' : ''}
/>
{errors[`waitTime_${index}`] && (
<p className="text-sm text-red-500">{errors[`waitTime_${index}`]}</p>
)}
</div>
</div>
{commands.length > 1 && (
<Button
type="button"
variant="outline"
size="sm"
onClick={() => removeCommand(index)}
disabled={isSubmitting}
className="text-red-500 hover:text-red-700 flex-shrink-0"
>
<Trash2 className="h-4 w-4" />
</Button>
)}
</div>
))}
</div>
</div>
<p className="text-xs text-muted-foreground flex-shrink-0 mt-2">
ADB命令
</p>
</div>
{/* 固定区域:其他表单字段 */}
<div className="space-y-4 flex-shrink-0 p-4 pt-2">
{/* 操作描述 */}
<div className="space-y-2">
<Label htmlFor="description" className="text-sm font-medium">
</Label>
<Textarea
id="description"
value={formData.description}
onChange={e => handleInputChange('description', e.target.value)}
placeholder="请描述此ADB操作的用途和功能(可选)"
rows={3}
disabled={isSubmitting}
/>
<p className="text-xs text-muted-foreground">
便
</p>
</div>
{/* ADB路径 */}
<div className="space-y-2">
<Label htmlFor="path" className="text-sm font-medium">
ADB路径 {formData.useAbsolutePath && <span className="text-red-500">*</span>}
</Label>
<Input
id="path"
value={formData.path}
onChange={e => handleInputChange('path', e.target.value)}
placeholder="例如: /usr/local/bin/adb, C:\adb\adb.exe(可选)"
disabled={isSubmitting}
className={errors.path ? 'border-red-500 focus:border-red-500' : ''}
/>
{errors.path && (
<p className="text-xs text-red-500">{errors.path}</p>
)}
<p className="text-xs text-muted-foreground">
ADB可执行文件的完整路径使
</p>
</div>
{/* 选项设置 */}
<div className="space-y-4">
<div className="flex items-center space-x-2">
<Checkbox
id="useAbsolutePath"
checked={formData.useAbsolutePath}
onCheckedChange={(checked) =>
handleInputChange('useAbsolutePath', checked as boolean)
}
disabled={isSubmitting}
/>
<Label htmlFor="useAbsolutePath" className="text-sm font-medium">
使
</Label>
</div>
<p className="text-xs text-muted-foreground ml-6">
使使
</p>
<div className="flex items-center space-x-2">
<Checkbox
id="isEnabled"
checked={formData.isEnabled}
onCheckedChange={(checked) =>
handleInputChange('isEnabled', checked as boolean)
}
disabled={isSubmitting}
/>
<Label htmlFor="isEnabled" className="text-sm font-medium">
ADB操作
</Label>
</div>
<p className="text-xs text-muted-foreground ml-6">
</p>
</div>
</div>
</DrawerContent>
<DrawerFooter className="flex-shrink-0">
<Button
type="button"
variant="outline"
onClick={() => onOpenChange(false)}
disabled={isSubmitting}
>
</Button>
<Button
type="submit"
disabled={isSubmitting}
className="bg-primary text-primary-foreground hover:bg-primary/90"
>
{isSubmitting ? '保存中...' : (isEdit ? '更新' : '创建')}
</Button>
</DrawerFooter>
</form>
</div>
</Drawer>
);
}

355
src/X1.WebUI/src/pages/adb-operations/AdbOperationForm.tsx

@ -1,355 +0,0 @@
import React from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Checkbox } from '@/components/ui/checkbox';
import { CreateAdbOperationRequest, UpdateAdbOperationRequest } from '@/services/adbOperationsService';
import { getTerminalDevices, TerminalDevice } from '@/services/terminalDeviceService';
import { Plus, Trash2 } from 'lucide-react';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
interface CommandItem {
command: string;
waitTimeMs: number;
}
interface AdbOperationFormProps {
onSubmit: (data: CreateAdbOperationRequest | UpdateAdbOperationRequest) => void;
initialData?: Partial<CreateAdbOperationRequest>;
isEdit?: boolean;
isSubmitting?: boolean;
}
export default function AdbOperationForm({
onSubmit,
initialData,
isEdit = false,
isSubmitting = false
}: AdbOperationFormProps) {
// 解析初始命令数据
const parseInitialCommands = (): CommandItem[] => {
if (initialData?.command) {
try {
return JSON.parse(initialData.command);
} catch {
// 如果不是JSON格式,当作单条命令处理
return [{ command: initialData.command, waitTimeMs: initialData.waitTimeMs || 0 }];
}
}
return [{ command: '', waitTimeMs: 0 }];
};
const [commands, setCommands] = React.useState<CommandItem[]>(parseInitialCommands());
const [formData, setFormData] = React.useState<CreateAdbOperationRequest>({
command: initialData?.command || '',
description: initialData?.description || '',
path: initialData?.path || '',
useAbsolutePath: initialData?.useAbsolutePath ?? false,
isEnabled: initialData?.isEnabled ?? true,
waitTimeMs: initialData?.waitTimeMs || 0,
deviceId: initialData?.deviceId || ''
});
const [errors, setErrors] = React.useState<Record<string, string>>({});
const [devices, setDevices] = React.useState<TerminalDevice[]>([]);
const [loadingDevices, setLoadingDevices] = React.useState(false);
// 加载设备列表
React.useEffect(() => {
const loadDevices = async () => {
setLoadingDevices(true);
try {
const result = await getTerminalDevices({ pageSize: 100 }); // 获取所有设备
if (result.isSuccess && result.data) {
setDevices(result.data.terminalDevices || []);
}
} catch (error) {
console.error('加载设备列表失败:', error);
} finally {
setLoadingDevices(false);
}
};
loadDevices();
}, []);
// 更新命令列表
const updateCommands = (newCommands: CommandItem[]) => {
setCommands(newCommands);
// 将命令列表转换为JSON字符串
const commandJson = JSON.stringify(newCommands);
setFormData(prev => ({ ...prev, command: commandJson }));
};
// 添加新命令
const addCommand = () => {
updateCommands([...commands, { command: '', waitTimeMs: 0 }]);
};
// 删除命令
const removeCommand = (index: number) => {
if (commands.length > 1) {
const newCommands = commands.filter((_, i) => i !== index);
updateCommands(newCommands);
}
};
// 更新单个命令
const updateCommand = (index: number, field: keyof CommandItem, value: string | number) => {
const newCommands = [...commands];
newCommands[index] = { ...newCommands[index], [field]: value };
updateCommands(newCommands);
};
// 表单验证
const validateForm = (): boolean => {
const newErrors: Record<string, string> = {};
// 验证设备ID
if (!formData.deviceId.trim()) {
newErrors.deviceId = '请选择设备';
}
// 验证命令列表
if (commands.length === 0) {
newErrors.commands = '至少需要一条ADB命令';
} else {
for (let i = 0; i < commands.length; i++) {
if (!commands[i].command.trim()) {
newErrors[`command_${i}`] = `${i + 1}条命令不能为空`;
}
if (commands[i].waitTimeMs < 0) {
newErrors[`waitTime_${i}`] = `${i + 1}条命令的等待时间不能为负数`;
}
}
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (isSubmitting) return; // 防止重复提交
if (!validateForm()) {
return;
}
// 提交前清理数据
const submitData = {
...formData,
command: formData.command, // 已经是JSON字符串
description: formData.description.trim(),
path: formData.path.trim()
};
onSubmit(submitData);
};
const handleInputChange = (field: keyof CreateAdbOperationRequest, value: string | number | boolean) => {
setFormData(prev => ({ ...prev, [field]: value }));
// 清除对应字段的错误
if (errors[field]) {
setErrors(prev => ({ ...prev, [field]: '' }));
}
};
return (
<form onSubmit={handleSubmit} className="space-y-6">
{/* 设备选择 */}
<div className="space-y-2">
<Label className="text-sm font-medium">
<span className="text-red-500">*</span>
</Label>
<Select
value={formData.deviceId}
onValueChange={(value) => handleInputChange('deviceId', value)}
disabled={isSubmitting || loadingDevices}
>
<SelectTrigger className={errors.deviceId ? 'border-red-500 focus:border-red-500' : ''}>
<SelectValue placeholder="请选择设备" />
</SelectTrigger>
<SelectContent>
{devices.map((device) => (
<SelectItem key={device.serial} value={device.serial}>
{device.alias || device.name} - {device.brand} ({device.serial})
</SelectItem>
))}
</SelectContent>
</Select>
{errors.deviceId && (
<p className="text-sm text-red-500">{errors.deviceId}</p>
)}
<p className="text-xs text-muted-foreground">
ADB操作的设备ID将与TerminalDevice的Serial字段关联
</p>
</div>
{/* 命令列表 */}
<div className="space-y-4">
<div className="flex items-center justify-between">
<Label className="text-sm font-medium">
ADB命令列表 <span className="text-red-500">*</span>
</Label>
<Button
type="button"
variant="outline"
size="sm"
onClick={addCommand}
disabled={isSubmitting}
className="flex items-center gap-1"
>
<Plus className="h-4 w-4" />
</Button>
</div>
{errors.commands && (
<p className="text-sm text-red-500">{errors.commands}</p>
)}
<div className="space-y-3">
{commands.map((cmd, index) => (
<div key={index} className="flex gap-3 items-start p-3 border rounded-lg">
<div className="flex-1 space-y-3">
<div>
<Label className="text-xs text-muted-foreground">
{index + 1}
</Label>
<Input
value={cmd.command}
onChange={e => updateCommand(index, 'command', e.target.value)}
placeholder="例如: adb devices, adb shell ls, adb install app.apk"
disabled={isSubmitting}
className={errors[`command_${index}`] ? 'border-red-500 focus:border-red-500' : ''}
/>
{errors[`command_${index}`] && (
<p className="text-sm text-red-500">{errors[`command_${index}`]}</p>
)}
</div>
<div>
<Label className="text-xs text-muted-foreground">
()
</Label>
<Input
type="number"
min="0"
step="100"
value={cmd.waitTimeMs}
onChange={e => updateCommand(index, 'waitTimeMs', parseInt(e.target.value) || 0)}
placeholder="例如: 1000"
disabled={isSubmitting}
className={errors[`waitTime_${index}`] ? 'border-red-500 focus:border-red-500' : ''}
/>
{errors[`waitTime_${index}`] && (
<p className="text-sm text-red-500">{errors[`waitTime_${index}`]}</p>
)}
</div>
</div>
{commands.length > 1 && (
<Button
type="button"
variant="outline"
size="sm"
onClick={() => removeCommand(index)}
disabled={isSubmitting}
className="text-red-500 hover:text-red-700"
>
<Trash2 className="h-4 w-4" />
</Button>
)}
</div>
))}
</div>
<p className="text-xs text-muted-foreground">
ADB命令
</p>
</div>
<div className="space-y-2">
<Label htmlFor="description" className="text-sm font-medium">
</Label>
<Textarea
id="description"
value={formData.description}
onChange={e => handleInputChange('description', e.target.value)}
placeholder="请描述此ADB操作的用途和功能(可选)"
rows={3}
disabled={isSubmitting}
/>
<p className="text-xs text-muted-foreground">
便
</p>
</div>
<div className="space-y-2">
<Label htmlFor="path" className="text-sm font-medium">
ADB路径
</Label>
<Input
id="path"
value={formData.path}
onChange={e => handleInputChange('path', e.target.value)}
placeholder="例如: /usr/local/bin/adb, C:\adb\adb.exe(可选)"
disabled={isSubmitting}
/>
<p className="text-xs text-muted-foreground">
ADB可执行文件的完整路径使
</p>
</div>
<div className="space-y-4">
<div className="flex items-center space-x-2">
<Checkbox
id="useAbsolutePath"
checked={formData.useAbsolutePath}
onCheckedChange={(checked) =>
handleInputChange('useAbsolutePath', checked as boolean)
}
disabled={isSubmitting}
/>
<Label htmlFor="useAbsolutePath" className="text-sm font-medium">
使
</Label>
</div>
<p className="text-xs text-muted-foreground ml-6">
使使
</p>
<div className="flex items-center space-x-2">
<Checkbox
id="isEnabled"
checked={formData.isEnabled}
onCheckedChange={(checked) =>
handleInputChange('isEnabled', checked as boolean)
}
disabled={isSubmitting}
/>
<Label htmlFor="isEnabled" className="text-sm font-medium">
ADB操作
</Label>
</div>
<p className="text-xs text-muted-foreground ml-6">
</p>
</div>
<div className="flex gap-3 pt-4">
<Button
type="submit"
className="flex-1"
disabled={isSubmitting}
>
{isSubmitting ? '提交中...' : (isEdit ? '更新ADB操作' : '创建ADB操作')}
</Button>
</div>
</form>
);
}

72
src/X1.WebUI/src/pages/adb-operations/AdbOperationsView.tsx

@ -1,21 +1,17 @@
import React, { useEffect, useState } from 'react';
import {
getAdbOperations,
getAdbOperationById,
createAdbOperation,
updateAdbOperation,
deleteAdbOperation,
adbOperationService,
AdbOperation,
GetAdbOperationsRequest,
CreateAdbOperationRequest,
UpdateAdbOperationRequest
} from '@/services/adbOperationsService';
import AdbOperationsTable from './AdbOperationsTable';
import AdbOperationForm from './AdbOperationForm';
import AdbOperationDrawer from './AdbOperationDrawer';
import { Input } from '@/components/ui/input';
import PaginationBar from '@/components/ui/PaginationBar';
import TableToolbar, { DensityType } from '@/components/ui/TableToolbar';
import { Dialog, DialogContent, DialogTrigger } from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { useToast } from '@/components/ui/use-toast';
@ -41,9 +37,9 @@ export default function AdbOperationsView() {
// 搜索参数
const [keyword, setKeyword] = useState('');
// 表单对话框状态
const [open, setOpen] = useState(false);
const [editOpen, setEditOpen] = useState(false);
// 抽屉状态
const [drawerOpen, setDrawerOpen] = useState(false);
const [editDrawerOpen, setEditDrawerOpen] = useState(false);
const [selectedOperation, setSelectedOperation] = useState<AdbOperation | null>(null);
// 提交状态
@ -61,7 +57,7 @@ export default function AdbOperationsView() {
...params
};
const result = await getAdbOperations(queryParams);
const result = await adbOperationService.getAdbOperations(queryParams);
if (result.isSuccess && result.data) {
setAdbOperations(result.data.items || []);
setTotal(result.data.totalCount || 0);
@ -76,13 +72,13 @@ export default function AdbOperationsView() {
const handleEdit = (operation: AdbOperation) => {
setSelectedOperation(operation);
setEditOpen(true);
setEditDrawerOpen(true);
};
const handleDelete = async (operation: AdbOperation) => {
if (confirm(`确定要删除ADB操作"${operation.command}" 吗?`)) {
try {
const result = await deleteAdbOperation(operation.id);
const result = await adbOperationService.deleteAdbOperation(operation.id);
if (result.isSuccess) {
toast({
title: "删除成功",
@ -114,13 +110,13 @@ export default function AdbOperationsView() {
setIsSubmitting(true);
try {
const result = await createAdbOperation(data);
const result = await adbOperationService.createAdbOperation(data);
if (result.isSuccess) {
toast({
title: "创建成功",
description: `ADB操作 "${data.command}" 创建成功`,
});
setOpen(false);
setDrawerOpen(false);
fetchAdbOperations();
} else {
const errorMessage = result.errorMessages?.join(', ') || "创建ADB操作时发生错误";
@ -152,13 +148,13 @@ export default function AdbOperationsView() {
...data,
id: selectedOperation.id
};
const result = await updateAdbOperation(selectedOperation.id, updateData);
const result = await adbOperationService.updateAdbOperation(selectedOperation.id, updateData);
if (result.isSuccess) {
toast({
title: "更新成功",
description: `ADB操作 "${data.command}" 更新成功`,
});
setEditOpen(false);
setEditDrawerOpen(false);
setSelectedOperation(null);
fetchAdbOperations();
} else {
@ -242,14 +238,12 @@ export default function AdbOperationsView() {
<div className="rounded-md border bg-background p-4">
{/* 顶部操作栏:添加ADB操作+工具栏 */}
<div className="flex items-center justify-between mb-2">
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button className="bg-primary text-primary-foreground hover:bg-primary/90">+ ADB操作</Button>
</DialogTrigger>
<DialogContent className="bg-background">
<AdbOperationForm onSubmit={handleCreate} isSubmitting={isSubmitting} />
</DialogContent>
</Dialog>
<Button
className="bg-primary text-primary-foreground hover:bg-primary/90"
onClick={() => setDrawerOpen(true)}
>
+ ADB操作
</Button>
<TableToolbar
onRefresh={() => fetchAdbOperations()}
onDensityChange={setDensity}
@ -286,17 +280,23 @@ export default function AdbOperationsView() {
</div>
</div>
{/* 编辑ADB操作对话框 */}
<Dialog open={editOpen} onOpenChange={setEditOpen}>
<DialogContent className="bg-background">
<AdbOperationForm
onSubmit={(data) => handleUpdate(data as UpdateAdbOperationRequest)}
initialData={selectedOperation || undefined}
isEdit={true}
isSubmitting={isSubmitting}
/>
</DialogContent>
</Dialog>
{/* 创建ADB操作抽屉 */}
<AdbOperationDrawer
open={drawerOpen}
onOpenChange={setDrawerOpen}
onSubmit={handleCreate}
isSubmitting={isSubmitting}
/>
{/* 编辑ADB操作抽屉 */}
<AdbOperationDrawer
open={editDrawerOpen}
onOpenChange={setEditDrawerOpen}
onSubmit={(data) => handleUpdate(data as UpdateAdbOperationRequest)}
initialData={selectedOperation || undefined}
isEdit={true}
isSubmitting={isSubmitting}
/>
</main>
);
}

66
src/X1.WebUI/src/services/adbOperationsService.ts

@ -1,5 +1,6 @@
import { httpClient } from '@/lib/http-client';
import { OperationResult } from '@/config/types/config.types';
import { OperationResult } from '@/types/auth';
import { API_PATHS } from '@/constants/api';
// ADB操作接口定义 - 匹配后端AdbOperationDto
export interface AdbOperation {
@ -82,30 +83,51 @@ export interface UpdateAdbOperationResponse {
screenshotData?: Uint8Array;
}
// API路径常量
const ADB_OPERATIONS_API = '/api/adb-operations';
class AdbOperationService {
private readonly baseUrl = API_PATHS.ADB_OPERATIONS;
// 获取ADB操作列表
export function getAdbOperations(params: GetAdbOperationsRequest = {}): Promise<OperationResult<GetAdbOperationsResponse>> {
return httpClient.get(ADB_OPERATIONS_API, { params });
}
// 获取ADB操作列表
async getAdbOperations(params: GetAdbOperationsRequest = {}): Promise<OperationResult<GetAdbOperationsResponse>> {
const queryParams = new URLSearchParams();
if (params.pageNumber) queryParams.append('pageNumber', params.pageNumber.toString());
if (params.pageSize) queryParams.append('pageSize', params.pageSize.toString());
if (params.keyword) queryParams.append('keyword', params.keyword);
if (params.deviceId) queryParams.append('deviceId', params.deviceId);
// 获取ADB操作详情
export function getAdbOperationById(id: string): Promise<OperationResult<AdbOperation>> {
return httpClient.get(`${ADB_OPERATIONS_API}/${id}`);
}
const url = `${this.baseUrl}?${queryParams.toString()}`;
return httpClient.get<GetAdbOperationsResponse>(url);
}
// 创建ADB操作
export function createAdbOperation(data: CreateAdbOperationRequest): Promise<OperationResult<CreateAdbOperationResponse>> {
return httpClient.post(ADB_OPERATIONS_API, data);
}
// 根据ID获取ADB操作详情
async getAdbOperationById(id: string): Promise<OperationResult<AdbOperation>> {
return httpClient.get<AdbOperation>(`${this.baseUrl}/${id}`);
}
// 更新ADB操作
export function updateAdbOperation(id: string, data: UpdateAdbOperationRequest): Promise<OperationResult<UpdateAdbOperationResponse>> {
return httpClient.put(`${ADB_OPERATIONS_API}/${id}`, data);
}
// 创建ADB操作
async createAdbOperation(data: CreateAdbOperationRequest): Promise<OperationResult<CreateAdbOperationResponse>> {
return httpClient.post<CreateAdbOperationResponse>(this.baseUrl, data);
}
// 删除ADB操作
export function deleteAdbOperation(id: string): Promise<OperationResult<boolean>> {
return httpClient.delete(`${ADB_OPERATIONS_API}/${id}`);
// 更新ADB操作
async updateAdbOperation(id: string, data: UpdateAdbOperationRequest): Promise<OperationResult<UpdateAdbOperationResponse>> {
return httpClient.put<UpdateAdbOperationResponse>(`${this.baseUrl}/${id}`, data);
}
// 删除ADB操作
async deleteAdbOperation(id: string): Promise<OperationResult<boolean>> {
return httpClient.delete<boolean>(`${this.baseUrl}/${id}`);
}
// 获取ADB操作状态的可读描述
getAdbOperationStatusDescription(isEnabled: boolean): string {
return isEnabled ? '启用' : '禁用';
}
// 获取ADB操作状态的颜色
getAdbOperationStatusColor(isEnabled: boolean): string {
return isEnabled ? 'success' : 'error';
}
}
export const adbOperationService = new AdbOperationService();

392
src/X1.WebUI/yarn.lock

@ -29,7 +29,7 @@
resolved "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.28.0.tgz"
integrity sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==
"@babel/core@^7.27.4":
"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.27.4":
version "7.28.0"
resolved "https://registry.npmmirror.com/@babel/core/-/core-7.28.0.tgz"
integrity sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==
@ -173,116 +173,6 @@
"@babel/helper-string-parser" "^7.27.1"
"@babel/helper-validator-identifier" "^7.27.1"
"@esbuild/aix-ppc64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f"
integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==
"@esbuild/android-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052"
integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==
"@esbuild/android-arm@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28"
integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==
"@esbuild/android-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e"
integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==
"@esbuild/darwin-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a"
integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==
"@esbuild/darwin-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22"
integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==
"@esbuild/freebsd-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e"
integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==
"@esbuild/freebsd-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261"
integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==
"@esbuild/linux-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b"
integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==
"@esbuild/linux-arm@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9"
integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==
"@esbuild/linux-ia32@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2"
integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==
"@esbuild/linux-loong64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df"
integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==
"@esbuild/linux-mips64el@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe"
integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==
"@esbuild/linux-ppc64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4"
integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==
"@esbuild/linux-riscv64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc"
integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==
"@esbuild/linux-s390x@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de"
integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==
"@esbuild/linux-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0"
integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==
"@esbuild/netbsd-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047"
integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==
"@esbuild/openbsd-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70"
integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==
"@esbuild/sunos-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b"
integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==
"@esbuild/win32-arm64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d"
integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==
"@esbuild/win32-ia32@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b"
integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==
"@esbuild/win32-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz"
@ -419,7 +309,7 @@
"@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9"
"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5":
version "2.0.5"
resolved "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
@ -513,7 +403,7 @@
"@radix-ui/react-use-previous" "1.1.1"
"@radix-ui/react-use-size" "1.1.1"
"@radix-ui/react-collapsible@1.1.11", "@radix-ui/react-collapsible@^1.1.10":
"@radix-ui/react-collapsible@^1.1.10", "@radix-ui/react-collapsible@1.1.11":
version "1.1.11"
resolved "https://registry.npmmirror.com/@radix-ui/react-collapsible/-/react-collapsible-1.1.11.tgz"
integrity sha512-2qrRsVGSCYasSz1RFOorXwl0H7g7J1frQtgpQgYrt+MOidtPAINHn9CPovQXb83r8ahapdx3Tu0fa/pdFFSdPg==
@ -559,7 +449,7 @@
resolved "https://registry.npmmirror.com/@radix-ui/react-context/-/react-context-1.1.2.tgz"
integrity sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==
"@radix-ui/react-dialog@1.1.14", "@radix-ui/react-dialog@^1.1.13":
"@radix-ui/react-dialog@^1.1.13", "@radix-ui/react-dialog@1.1.14":
version "1.1.14"
resolved "https://registry.npmmirror.com/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz"
integrity sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==
@ -881,7 +771,7 @@
"@radix-ui/react-use-previous" "1.1.1"
"@radix-ui/react-use-size" "1.1.1"
"@radix-ui/react-slot@1.2.3", "@radix-ui/react-slot@^1.2.2":
"@radix-ui/react-slot@^1.2.2", "@radix-ui/react-slot@1.2.3":
version "1.2.3"
resolved "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-1.2.3.tgz"
integrity sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==
@ -1032,7 +922,7 @@
"@reactflow/background@11.3.14":
version "11.3.14"
resolved "https://registry.npmmirror.com/@reactflow/background/-/background-11.3.14.tgz#778ca30174f3de77fc321459ab3789e66e71a699"
resolved "https://registry.npmmirror.com/@reactflow/background/-/background-11.3.14.tgz"
integrity sha512-Gewd7blEVT5Lh6jqrvOgd4G6Qk17eGKQfsDXgyRSqM+CTwDqRldG2LsWN4sNeno6sbqVIC2fZ+rAUBFA9ZEUDA==
dependencies:
"@reactflow/core" "11.11.4"
@ -1041,7 +931,7 @@
"@reactflow/controls@11.2.14":
version "11.2.14"
resolved "https://registry.npmmirror.com/@reactflow/controls/-/controls-11.2.14.tgz#508ed2c40d23341b3b0919dd11e76fd49cf850c7"
resolved "https://registry.npmmirror.com/@reactflow/controls/-/controls-11.2.14.tgz"
integrity sha512-MiJp5VldFD7FrqaBNIrQ85dxChrG6ivuZ+dcFhPQUwOK3HfYgX2RHdBua+gx+40p5Vw5It3dVNp/my4Z3jF0dw==
dependencies:
"@reactflow/core" "11.11.4"
@ -1050,7 +940,7 @@
"@reactflow/core@11.11.4":
version "11.11.4"
resolved "https://registry.npmmirror.com/@reactflow/core/-/core-11.11.4.tgz#89bd86d1862aa1416f3f49926cede7e8c2aab6a7"
resolved "https://registry.npmmirror.com/@reactflow/core/-/core-11.11.4.tgz"
integrity sha512-H4vODklsjAq3AMq6Np4LE12i1I4Ta9PrDHuBR9GmL8uzTt2l2jh4CiQbEMpvMDcp7xi4be0hgXj+Ysodde/i7Q==
dependencies:
"@types/d3" "^7.4.0"
@ -1065,7 +955,7 @@
"@reactflow/minimap@11.7.14":
version "11.7.14"
resolved "https://registry.npmmirror.com/@reactflow/minimap/-/minimap-11.7.14.tgz#298d7a63cb1da06b2518c99744f716560c88ca73"
resolved "https://registry.npmmirror.com/@reactflow/minimap/-/minimap-11.7.14.tgz"
integrity sha512-mpwLKKrEAofgFJdkhwR5UQ1JYWlcAAL/ZU/bctBkuNTT1yqV+y0buoNVImsRehVYhJwffSWeSHaBR5/GJjlCSQ==
dependencies:
"@reactflow/core" "11.11.4"
@ -1078,7 +968,7 @@
"@reactflow/node-resizer@2.2.14":
version "2.2.14"
resolved "https://registry.npmmirror.com/@reactflow/node-resizer/-/node-resizer-2.2.14.tgz#1810c0ce51aeb936f179466a6660d1e02c7a77a8"
resolved "https://registry.npmmirror.com/@reactflow/node-resizer/-/node-resizer-2.2.14.tgz"
integrity sha512-fwqnks83jUlYr6OHcdFEedumWKChTHRGw/kbCxj0oqBd+ekfs+SIp4ddyNU0pdx96JIm5iNFS0oNrmEiJbbSaA==
dependencies:
"@reactflow/core" "11.11.4"
@ -1089,7 +979,7 @@
"@reactflow/node-toolbar@1.3.14":
version "1.3.14"
resolved "https://registry.npmmirror.com/@reactflow/node-toolbar/-/node-toolbar-1.3.14.tgz#c6ffc76f82acacdce654f2160dc9852162d6e7c9"
resolved "https://registry.npmmirror.com/@reactflow/node-toolbar/-/node-toolbar-1.3.14.tgz"
integrity sha512-rbynXQnH/xFNu4P9H+hVqlEUafDCkEoCy0Dg9mG22Sg+rY/0ck6KkrAQrYrTgXusd+cEJOMK0uOOFCK2/5rSGQ==
dependencies:
"@reactflow/core" "11.11.4"
@ -1106,101 +996,6 @@
resolved "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.19.tgz"
integrity sha512-3FL3mnMbPu0muGOCaKAhhFEYmqv9eTfPSJRJmANrCwtgK8VuxpsZDGK+m0LYAGoyO8+0j5uRe4PeyPDK1yA/hA==
"@rollup/rollup-android-arm-eabi@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.1.tgz#f768e3b2b0e6b55c595d7a053652c06413713983"
integrity sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w==
"@rollup/rollup-android-arm64@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.1.tgz#40379fd5501cfdfd7d8f86dfa1d3ce8d3a609493"
integrity sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ==
"@rollup/rollup-darwin-arm64@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.1.tgz#972c227bc89fe8a38a3f0c493e1966900e4e1ff7"
integrity sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg==
"@rollup/rollup-darwin-x64@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.1.tgz#96c919dcb87a5aa7dec5f7f77d90de881e578fdd"
integrity sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw==
"@rollup/rollup-freebsd-arm64@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.1.tgz#d199d8eaef830179c0c95b7a6e5455e893d1102c"
integrity sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA==
"@rollup/rollup-freebsd-x64@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.1.tgz#cab01f9e06ca756c1fabe87d64825ae016af4713"
integrity sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw==
"@rollup/rollup-linux-arm-gnueabihf@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.1.tgz#f6f1c42036dba0e58dc2315305429beff0d02c78"
integrity sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==
"@rollup/rollup-linux-arm-musleabihf@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.1.tgz#1157e98e740facf858993fb51431dce3a4a96239"
integrity sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==
"@rollup/rollup-linux-arm64-gnu@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.1.tgz#b39db73f8a4c22e7db31a4f3fd45170105f33265"
integrity sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==
"@rollup/rollup-linux-arm64-musl@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.1.tgz#4043398049fe4449c1485312d1ae9ad8af4056dd"
integrity sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==
"@rollup/rollup-linux-loongarch64-gnu@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.1.tgz#855a80e7e86490da15a85dcce247dbc25265bc08"
integrity sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==
"@rollup/rollup-linux-powerpc64le-gnu@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.1.tgz#8cf843cb7ab1d42e1dda680937cf0a2db6d59047"
integrity sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==
"@rollup/rollup-linux-riscv64-gnu@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.1.tgz#287c085472976c8711f16700326f736a527f2f38"
integrity sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==
"@rollup/rollup-linux-riscv64-musl@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.1.tgz#095ad5e53a54ba475979f1b3226b92440c95c892"
integrity sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==
"@rollup/rollup-linux-s390x-gnu@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.1.tgz#a3dec8281d8f2aef1703e48ebc65d29fe847933c"
integrity sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==
"@rollup/rollup-linux-x64-gnu@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.1.tgz#4b211e6fd57edd6a134740f4f8e8ea61972ff2c5"
integrity sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==
"@rollup/rollup-linux-x64-musl@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.1.tgz#3ecbf8e21b4157e57bb15dc6837b6db851f9a336"
integrity sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==
"@rollup/rollup-win32-arm64-msvc@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.1.tgz#d4aae38465b2ad200557b53c8c817266a3ddbfd0"
integrity sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==
"@rollup/rollup-win32-ia32-msvc@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.1.tgz#0258e8ca052abd48b23fd6113360fa0cd1ec3e23"
integrity sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A==
"@rollup/rollup-win32-x64-msvc@4.44.1":
version "4.44.1"
resolved "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.1.tgz"
@ -1260,36 +1055,36 @@
"@types/d3-array@*":
version "3.2.1"
resolved "https://registry.npmmirror.com/@types/d3-array/-/d3-array-3.2.1.tgz#1f6658e3d2006c4fceac53fde464166859f8b8c5"
resolved "https://registry.npmmirror.com/@types/d3-array/-/d3-array-3.2.1.tgz"
integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==
"@types/d3-axis@*":
version "3.0.6"
resolved "https://registry.npmmirror.com/@types/d3-axis/-/d3-axis-3.0.6.tgz#e760e5765b8188b1defa32bc8bb6062f81e4c795"
resolved "https://registry.npmmirror.com/@types/d3-axis/-/d3-axis-3.0.6.tgz"
integrity sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==
dependencies:
"@types/d3-selection" "*"
"@types/d3-brush@*":
version "3.0.6"
resolved "https://registry.npmmirror.com/@types/d3-brush/-/d3-brush-3.0.6.tgz#c2f4362b045d472e1b186cdbec329ba52bdaee6c"
resolved "https://registry.npmmirror.com/@types/d3-brush/-/d3-brush-3.0.6.tgz"
integrity sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==
dependencies:
"@types/d3-selection" "*"
"@types/d3-chord@*":
version "3.0.6"
resolved "https://registry.npmmirror.com/@types/d3-chord/-/d3-chord-3.0.6.tgz#1706ca40cf7ea59a0add8f4456efff8f8775793d"
resolved "https://registry.npmmirror.com/@types/d3-chord/-/d3-chord-3.0.6.tgz"
integrity sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==
"@types/d3-color@*":
version "3.1.3"
resolved "https://registry.npmmirror.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2"
resolved "https://registry.npmmirror.com/@types/d3-color/-/d3-color-3.1.3.tgz"
integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==
"@types/d3-contour@*":
version "3.0.6"
resolved "https://registry.npmmirror.com/@types/d3-contour/-/d3-contour-3.0.6.tgz#9ada3fa9c4d00e3a5093fed0356c7ab929604231"
resolved "https://registry.npmmirror.com/@types/d3-contour/-/d3-contour-3.0.6.tgz"
integrity sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==
dependencies:
"@types/d3-array" "*"
@ -1297,136 +1092,136 @@
"@types/d3-delaunay@*":
version "6.0.4"
resolved "https://registry.npmmirror.com/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz#185c1a80cc807fdda2a3fe960f7c11c4a27952e1"
resolved "https://registry.npmmirror.com/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz"
integrity sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==
"@types/d3-dispatch@*":
version "3.0.7"
resolved "https://registry.npmmirror.com/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz#ef004d8a128046cfce434d17182f834e44ef95b2"
resolved "https://registry.npmmirror.com/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz"
integrity sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==
"@types/d3-drag@*", "@types/d3-drag@^3.0.1":
version "3.0.7"
resolved "https://registry.npmmirror.com/@types/d3-drag/-/d3-drag-3.0.7.tgz#b13aba8b2442b4068c9a9e6d1d82f8bcea77fc02"
resolved "https://registry.npmmirror.com/@types/d3-drag/-/d3-drag-3.0.7.tgz"
integrity sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==
dependencies:
"@types/d3-selection" "*"
"@types/d3-dsv@*":
version "3.0.7"
resolved "https://registry.npmmirror.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz#0a351f996dc99b37f4fa58b492c2d1c04e3dac17"
resolved "https://registry.npmmirror.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz"
integrity sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==
"@types/d3-ease@*":
version "3.0.2"
resolved "https://registry.npmmirror.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b"
resolved "https://registry.npmmirror.com/@types/d3-ease/-/d3-ease-3.0.2.tgz"
integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==
"@types/d3-fetch@*":
version "3.0.7"
resolved "https://registry.npmmirror.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz#c04a2b4f23181aa376f30af0283dbc7b3b569980"
resolved "https://registry.npmmirror.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz"
integrity sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==
dependencies:
"@types/d3-dsv" "*"
"@types/d3-force@*":
version "3.0.10"
resolved "https://registry.npmmirror.com/@types/d3-force/-/d3-force-3.0.10.tgz#6dc8fc6e1f35704f3b057090beeeb7ac674bff1a"
resolved "https://registry.npmmirror.com/@types/d3-force/-/d3-force-3.0.10.tgz"
integrity sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==
"@types/d3-format@*":
version "3.0.4"
resolved "https://registry.npmmirror.com/@types/d3-format/-/d3-format-3.0.4.tgz#b1e4465644ddb3fdf3a263febb240a6cd616de90"
resolved "https://registry.npmmirror.com/@types/d3-format/-/d3-format-3.0.4.tgz"
integrity sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==
"@types/d3-geo@*":
version "3.1.0"
resolved "https://registry.npmmirror.com/@types/d3-geo/-/d3-geo-3.1.0.tgz#b9e56a079449174f0a2c8684a9a4df3f60522440"
resolved "https://registry.npmmirror.com/@types/d3-geo/-/d3-geo-3.1.0.tgz"
integrity sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==
dependencies:
"@types/geojson" "*"
"@types/d3-hierarchy@*":
version "3.1.7"
resolved "https://registry.npmmirror.com/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz#6023fb3b2d463229f2d680f9ac4b47466f71f17b"
resolved "https://registry.npmmirror.com/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz"
integrity sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==
"@types/d3-interpolate@*":
version "3.0.4"
resolved "https://registry.npmmirror.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c"
resolved "https://registry.npmmirror.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz"
integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==
dependencies:
"@types/d3-color" "*"
"@types/d3-path@*":
version "3.1.1"
resolved "https://registry.npmmirror.com/@types/d3-path/-/d3-path-3.1.1.tgz#f632b380c3aca1dba8e34aa049bcd6a4af23df8a"
resolved "https://registry.npmmirror.com/@types/d3-path/-/d3-path-3.1.1.tgz"
integrity sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==
"@types/d3-polygon@*":
version "3.0.2"
resolved "https://registry.npmmirror.com/@types/d3-polygon/-/d3-polygon-3.0.2.tgz#dfae54a6d35d19e76ac9565bcb32a8e54693189c"
resolved "https://registry.npmmirror.com/@types/d3-polygon/-/d3-polygon-3.0.2.tgz"
integrity sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==
"@types/d3-quadtree@*":
version "3.0.6"
resolved "https://registry.npmmirror.com/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz#d4740b0fe35b1c58b66e1488f4e7ed02952f570f"
resolved "https://registry.npmmirror.com/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz"
integrity sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==
"@types/d3-random@*":
version "3.0.3"
resolved "https://registry.npmmirror.com/@types/d3-random/-/d3-random-3.0.3.tgz#ed995c71ecb15e0cd31e22d9d5d23942e3300cfb"
resolved "https://registry.npmmirror.com/@types/d3-random/-/d3-random-3.0.3.tgz"
integrity sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==
"@types/d3-scale-chromatic@*":
version "3.1.0"
resolved "https://registry.npmmirror.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz#dc6d4f9a98376f18ea50bad6c39537f1b5463c39"
resolved "https://registry.npmmirror.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz"
integrity sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==
"@types/d3-scale@*":
version "4.0.9"
resolved "https://registry.npmmirror.com/@types/d3-scale/-/d3-scale-4.0.9.tgz#57a2f707242e6fe1de81ad7bfcccaaf606179afb"
resolved "https://registry.npmmirror.com/@types/d3-scale/-/d3-scale-4.0.9.tgz"
integrity sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==
dependencies:
"@types/d3-time" "*"
"@types/d3-selection@*", "@types/d3-selection@^3.0.3":
version "3.0.11"
resolved "https://registry.npmmirror.com/@types/d3-selection/-/d3-selection-3.0.11.tgz#bd7a45fc0a8c3167a631675e61bc2ca2b058d4a3"
resolved "https://registry.npmmirror.com/@types/d3-selection/-/d3-selection-3.0.11.tgz"
integrity sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==
"@types/d3-shape@*":
version "3.1.7"
resolved "https://registry.npmmirror.com/@types/d3-shape/-/d3-shape-3.1.7.tgz#2b7b423dc2dfe69c8c93596e673e37443348c555"
resolved "https://registry.npmmirror.com/@types/d3-shape/-/d3-shape-3.1.7.tgz"
integrity sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==
dependencies:
"@types/d3-path" "*"
"@types/d3-time-format@*":
version "4.0.3"
resolved "https://registry.npmmirror.com/@types/d3-time-format/-/d3-time-format-4.0.3.tgz#d6bc1e6b6a7db69cccfbbdd4c34b70632d9e9db2"
resolved "https://registry.npmmirror.com/@types/d3-time-format/-/d3-time-format-4.0.3.tgz"
integrity sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==
"@types/d3-time@*":
version "3.0.4"
resolved "https://registry.npmmirror.com/@types/d3-time/-/d3-time-3.0.4.tgz#8472feecd639691450dd8000eb33edd444e1323f"
resolved "https://registry.npmmirror.com/@types/d3-time/-/d3-time-3.0.4.tgz"
integrity sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==
"@types/d3-timer@*":
version "3.0.2"
resolved "https://registry.npmmirror.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70"
resolved "https://registry.npmmirror.com/@types/d3-timer/-/d3-timer-3.0.2.tgz"
integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==
"@types/d3-transition@*":
version "3.0.9"
resolved "https://registry.npmmirror.com/@types/d3-transition/-/d3-transition-3.0.9.tgz#1136bc57e9ddb3c390dccc9b5ff3b7d2b8d94706"
resolved "https://registry.npmmirror.com/@types/d3-transition/-/d3-transition-3.0.9.tgz"
integrity sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==
dependencies:
"@types/d3-selection" "*"
"@types/d3-zoom@*", "@types/d3-zoom@^3.0.1":
version "3.0.8"
resolved "https://registry.npmmirror.com/@types/d3-zoom/-/d3-zoom-3.0.8.tgz#dccb32d1c56b1e1c6e0f1180d994896f038bc40b"
resolved "https://registry.npmmirror.com/@types/d3-zoom/-/d3-zoom-3.0.8.tgz"
integrity sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==
dependencies:
"@types/d3-interpolate" "*"
@ -1434,7 +1229,7 @@
"@types/d3@^7.4.0":
version "7.4.3"
resolved "https://registry.npmmirror.com/@types/d3/-/d3-7.4.3.tgz#d4550a85d08f4978faf0a4c36b848c61eaac07e2"
resolved "https://registry.npmmirror.com/@types/d3/-/d3-7.4.3.tgz"
integrity sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==
dependencies:
"@types/d3-array" "*"
@ -1475,7 +1270,7 @@
"@types/geojson@*":
version "7946.0.16"
resolved "https://registry.npmmirror.com/@types/geojson/-/geojson-7946.0.16.tgz#8ebe53d69efada7044454e3305c19017d97ced2a"
resolved "https://registry.npmmirror.com/@types/geojson/-/geojson-7946.0.16.tgz"
integrity sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==
"@types/json-schema@^7.0.12":
@ -1483,7 +1278,7 @@
resolved "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
"@types/node@^20.11.16":
"@types/node@^18.0.0 || >=20.0.0", "@types/node@^20.11.16":
version "20.19.4"
resolved "https://registry.npmmirror.com/@types/node/-/node-20.19.4.tgz"
integrity sha512-OP+We5WV8Xnbuvw0zC2m4qfB/BJvjyCwtNjhHdJxV1639SGSKrLmJkc3fMnp2Qy8nJyHp8RO6umxELN/dS1/EA==
@ -1495,7 +1290,7 @@
resolved "https://registry.npmmirror.com/@types/prop-types/-/prop-types-15.7.15.tgz"
integrity sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==
"@types/react-dom@^18.2.17":
"@types/react-dom@*", "@types/react-dom@^18.2.17":
version "18.3.7"
resolved "https://registry.npmmirror.com/@types/react-dom/-/react-dom-18.3.7.tgz"
integrity sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==
@ -1507,7 +1302,7 @@
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@^18.2.43":
"@types/react@*", "@types/react@^18.0.0", "@types/react@^18.2.43", "@types/react@>=16.8":
version "18.3.23"
resolved "https://registry.npmmirror.com/@types/react/-/react-18.3.23.tgz"
integrity sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==
@ -1537,7 +1332,7 @@
semver "^7.5.4"
ts-api-utils "^1.0.1"
"@typescript-eslint/parser@^6.14.0":
"@typescript-eslint/parser@^6.0.0 || ^6.0.0-alpha", "@typescript-eslint/parser@^6.14.0":
version "6.21.0"
resolved "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-6.21.0.tgz"
integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==
@ -1628,7 +1423,7 @@ acorn-jsx@^5.3.2:
resolved "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
acorn@^8.9.0:
"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.9.0:
version "8.15.0"
resolved "https://registry.npmmirror.com/acorn/-/acorn-8.15.0.tgz"
integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
@ -1772,7 +1567,7 @@ braces@^3.0.3, braces@~3.0.2:
dependencies:
fill-range "^7.1.1"
browserslist@^4.24.0, browserslist@^4.24.4:
browserslist@^4.24.0, browserslist@^4.24.4, "browserslist@>= 4.21.0":
version "4.25.1"
resolved "https://registry.npmmirror.com/browserslist/-/browserslist-4.25.1.tgz"
integrity sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==
@ -1813,11 +1608,6 @@ caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001726:
resolved "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz"
integrity sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==
chalk@5.2.0:
version "5.2.0"
resolved "https://registry.npmmirror.com/chalk/-/chalk-5.2.0.tgz"
integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==
chalk@^4.0.0:
version "4.1.2"
resolved "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz"
@ -1831,6 +1621,11 @@ chalk@^5.0.0:
resolved "https://registry.npmmirror.com/chalk/-/chalk-5.4.1.tgz"
integrity sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==
chalk@5.2.0:
version "5.2.0"
resolved "https://registry.npmmirror.com/chalk/-/chalk-5.2.0.tgz"
integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==
chokidar@^3.6.0:
version "3.6.0"
resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz"
@ -1855,7 +1650,7 @@ class-variance-authority@^0.7.0:
classcat@^5.0.3, classcat@^5.0.4:
version "5.0.5"
resolved "https://registry.npmmirror.com/classcat/-/classcat-5.0.5.tgz#8c209f359a93ac302404a10161b501eba9c09c77"
resolved "https://registry.npmmirror.com/classcat/-/classcat-5.0.5.tgz"
integrity sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==
cli-cursor@^4.0.0:
@ -1940,17 +1735,17 @@ csstype@^3.0.2:
"d3-color@1 - 3":
version "3.1.0"
resolved "https://registry.npmmirror.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2"
resolved "https://registry.npmmirror.com/d3-color/-/d3-color-3.1.0.tgz"
integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==
"d3-dispatch@1 - 3":
version "3.0.1"
resolved "https://registry.npmmirror.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz#5fc75284e9c2375c36c839411a0cf550cbfc4d5e"
resolved "https://registry.npmmirror.com/d3-dispatch/-/d3-dispatch-3.0.1.tgz"
integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==
"d3-drag@2 - 3", d3-drag@^3.0.0:
d3-drag@^3.0.0, "d3-drag@2 - 3":
version "3.0.0"
resolved "https://registry.npmmirror.com/d3-drag/-/d3-drag-3.0.0.tgz#994aae9cd23c719f53b5e10e3a0a6108c69607ba"
resolved "https://registry.npmmirror.com/d3-drag/-/d3-drag-3.0.0.tgz"
integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==
dependencies:
d3-dispatch "1 - 3"
@ -1958,29 +1753,29 @@ csstype@^3.0.2:
"d3-ease@1 - 3":
version "3.0.1"
resolved "https://registry.npmmirror.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4"
resolved "https://registry.npmmirror.com/d3-ease/-/d3-ease-3.0.1.tgz"
integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==
"d3-interpolate@1 - 3":
version "3.0.1"
resolved "https://registry.npmmirror.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d"
resolved "https://registry.npmmirror.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz"
integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
dependencies:
d3-color "1 - 3"
"d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0:
d3-selection@^3.0.0, "d3-selection@2 - 3", d3-selection@3:
version "3.0.0"
resolved "https://registry.npmmirror.com/d3-selection/-/d3-selection-3.0.0.tgz#c25338207efa72cc5b9bd1458a1a41901f1e1b31"
resolved "https://registry.npmmirror.com/d3-selection/-/d3-selection-3.0.0.tgz"
integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==
"d3-timer@1 - 3":
version "3.0.1"
resolved "https://registry.npmmirror.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0"
resolved "https://registry.npmmirror.com/d3-timer/-/d3-timer-3.0.1.tgz"
integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==
"d3-transition@2 - 3":
version "3.0.1"
resolved "https://registry.npmmirror.com/d3-transition/-/d3-transition-3.0.1.tgz#6869fdde1448868077fdd5989200cb61b2a1645f"
resolved "https://registry.npmmirror.com/d3-transition/-/d3-transition-3.0.1.tgz"
integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==
dependencies:
d3-color "1 - 3"
@ -1991,7 +1786,7 @@ csstype@^3.0.2:
d3-zoom@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/d3-zoom/-/d3-zoom-3.0.0.tgz#d13f4165c73217ffeaa54295cd6969b3e7aee8f3"
resolved "https://registry.npmmirror.com/d3-zoom/-/d3-zoom-3.0.0.tgz"
integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==
dependencies:
d3-dispatch "1 - 3"
@ -2181,7 +1976,7 @@ eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3:
resolved "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz"
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
eslint@^8.55.0:
"eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", eslint@^8.55.0, eslint@>=8.40:
version "8.57.1"
resolved "https://registry.npmmirror.com/eslint/-/eslint-8.57.1.tgz"
integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==
@ -2409,11 +2204,6 @@ fs.realpath@^1.0.0:
resolved "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
fsevents@~2.3.2, fsevents@~2.3.3:
version "2.3.3"
resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz"
@ -2602,7 +2392,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@^2.0.3, inherits@^2.0.4:
inherits@^2.0.3, inherits@^2.0.4, inherits@2:
version "2.0.4"
resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@ -2847,13 +2637,6 @@ mimic-fn@^4.0.0:
resolved "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-4.0.0.tgz"
integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==
minimatch@9.0.3:
version "9.0.3"
resolved "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz"
integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==
dependencies:
brace-expansion "^2.0.1"
minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz"
@ -2868,6 +2651,13 @@ minimatch@^9.0.4:
dependencies:
brace-expansion "^2.0.1"
minimatch@9.0.3:
version "9.0.3"
resolved "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz"
integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==
dependencies:
brace-expansion "^2.0.1"
"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2:
version "7.1.2"
resolved "https://registry.npmmirror.com/minipass/-/minipass-7.1.2.tgz"
@ -3131,7 +2921,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0:
resolved "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@^8.4.33, postcss@^8.4.43, postcss@^8.4.47:
postcss@^8.0.0, postcss@^8.1.0, postcss@^8.2.14, postcss@^8.4.21, postcss@^8.4.33, postcss@^8.4.43, postcss@^8.4.47, postcss@>=8.0.9:
version "8.5.6"
resolved "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz"
integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==
@ -3185,7 +2975,7 @@ react-async-script@^1.2.0:
hoist-non-react-statics "^3.3.0"
prop-types "^15.5.0"
react-dom@^18.2.0:
"react-dom@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom@^18.0.0 || ^19.0.0", react-dom@^18.2.0, react-dom@>=16.8, react-dom@>=16.8.0, react-dom@>=17:
version "18.3.1"
resolved "https://registry.npmmirror.com/react-dom/-/react-dom-18.3.1.tgz"
integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==
@ -3201,7 +2991,7 @@ react-google-recaptcha@^3.1.0:
prop-types "^15.5.0"
react-async-script "^1.2.0"
react-hook-form@^7.50.0:
react-hook-form@^7.50.0, react-hook-form@^7.55.0:
version "7.59.0"
resolved "https://registry.npmmirror.com/react-hook-form/-/react-hook-form-7.59.0.tgz"
integrity sha512-kmkek2/8grqarTJExFNjy+RXDIP8yM+QTl3QL6m6Q8b2bih4ltmiXxH7T9n+yXNK477xPh5yZT/6vD8sYGzJTA==
@ -3263,7 +3053,7 @@ react-style-singleton@^2.2.2, react-style-singleton@^2.2.3:
get-nonce "^1.0.0"
tslib "^2.0.0"
react@^18.2.0:
react@*, "react@^16.5.1 || ^17.0.0 || ^18.0.0", "react@^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react@^16.8.0 || ^17 || ^18 || ^19", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react@^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc", "react@^18.0.0 || ^19.0.0", react@^18.2.0, react@^18.3.1, react@>=16.13.1, react@>=16.4.1, react@>=16.8, react@>=16.8.0, react@>=17:
version "18.3.1"
resolved "https://registry.npmmirror.com/react/-/react-18.3.1.tgz"
integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
@ -3272,7 +3062,7 @@ react@^18.2.0:
reactflow@^11.11.4:
version "11.11.4"
resolved "https://registry.npmmirror.com/reactflow/-/reactflow-11.11.4.tgz#e3593e313420542caed81aecbd73fb9bc6576653"
resolved "https://registry.npmmirror.com/reactflow/-/reactflow-11.11.4.tgz"
integrity sha512-70FOtJkUWH3BAOsN+LU9lCrKoKbtOPnz2uq0CV2PLdNSwxTXOhCbsZr50GmZ+Rtw3jx8Uv7/vBFtCGixLfd4Og==
dependencies:
"@reactflow/background" "11.3.14"
@ -3448,6 +3238,13 @@ stdin-discarder@^0.1.0:
dependencies:
bl "^5.0.0"
string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz"
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
dependencies:
safe-buffer "~5.2.0"
"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz"
@ -3475,13 +3272,6 @@ string-width@^5.0.1, string-width@^5.1.2:
emoji-regex "^9.2.2"
strip-ansi "^7.0.1"
string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz"
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
dependencies:
safe-buffer "~5.2.0"
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz"
@ -3548,7 +3338,7 @@ tailwindcss-animate@^1.0.7:
resolved "https://registry.npmmirror.com/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz"
integrity sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==
tailwindcss@^3.4.1:
tailwindcss@^3.4.1, "tailwindcss@>=3.0.0 || insiders":
version "3.4.17"
resolved "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.17.tgz"
integrity sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==
@ -3629,7 +3419,7 @@ type-fest@^0.20.2:
resolved "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz"
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
typescript@^5.2.2:
typescript@^5.2.2, typescript@>=4.2.0:
version "5.8.3"
resolved "https://registry.npmmirror.com/typescript/-/typescript-5.8.3.tgz"
integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==
@ -3684,7 +3474,7 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2:
resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
vite@^5.0.8:
"vite@^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0", vite@^5.0.8:
version "5.4.19"
resolved "https://registry.npmmirror.com/vite/-/vite-5.4.19.tgz"
integrity sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==
@ -3764,7 +3554,7 @@ zod@^3.20.2, zod@^3.24.4:
zustand@^4.4.1:
version "4.5.7"
resolved "https://registry.npmmirror.com/zustand/-/zustand-4.5.7.tgz#7d6bb2026a142415dd8be8891d7870e6dbe65f55"
resolved "https://registry.npmmirror.com/zustand/-/zustand-4.5.7.tgz"
integrity sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==
dependencies:
use-sync-external-store "^1.2.2"

1493
src/modify.md

File diff suppressed because it is too large
Loading…
Cancel
Save