Merge branch 'main' of http://113.45.157.195:3003/insiinc/re-mooc
This commit is contained in:
commit
ead0026d01
|
@ -3,6 +3,7 @@ backup
|
|||
# dependencies
|
||||
**/node_modules/
|
||||
volumes
|
||||
web-dist
|
||||
/.pnp
|
||||
.pnp.js
|
||||
*.tar
|
||||
|
|
49
Dockerfile
49
Dockerfile
|
@ -1,51 +1,23 @@
|
|||
# 基础镜像
|
||||
FROM node:18.17-alpine as base
|
||||
# 更改 apk 镜像源为阿里云
|
||||
# RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
||||
|
||||
# 使用阿里云镜像源 + 完整仓库声明
|
||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
|
||||
echo "https://mirrors.aliyun.com/alpine/v3.18/community" >> /etc/apk/repositories
|
||||
|
||||
# 安装最新稳定版 PostgreSQL 客户端(15.11)
|
||||
RUN apk update --no-cache && \
|
||||
apk add --no-cache \
|
||||
postgresql15-client \
|
||||
libpq \
|
||||
readline
|
||||
|
||||
RUN apk add --no-cache ffmpeg
|
||||
|
||||
# 设置 npm 镜像源
|
||||
RUN yarn config set registry https://registry.npmmirror.com
|
||||
|
||||
# 全局安装 pnpm 并设置其镜像源
|
||||
RUN yarn global add pnpm && pnpm config set registry https://registry.npmmirror.com
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 复制 pnpm workspace 配置文件
|
||||
COPY pnpm-workspace.yaml ./
|
||||
|
||||
# 首先复制 package.json, package-lock.json 和 pnpm-lock.yaml 文件
|
||||
COPY package*.json pnpm-lock.yaml* ./
|
||||
|
||||
COPY tsconfig.base.json .
|
||||
# 利用 Docker 缓存机制,如果依赖没有改变则不会重新执行 pnpm install
|
||||
#100-500 5-40
|
||||
|
||||
|
||||
FROM base As server-build
|
||||
WORKDIR /app
|
||||
COPY packages/common /app/packages/common
|
||||
COPY packages/tus /app/packages/tus
|
||||
COPY apps/server /app/apps/server
|
||||
RUN pnpm config set registry https://registry.npmmirror.com/
|
||||
RUN pnpm install --filter common
|
||||
RUN pnpm install --filter tus
|
||||
RUN pnpm install --filter server
|
||||
RUN pnpm --filter common generate && pnpm --filter common build:cjs
|
||||
COPY . .
|
||||
RUN pnpm install
|
||||
RUN pnpm --filter common build
|
||||
RUN pnpm --filter tus build
|
||||
RUN pnpm --filter utils build
|
||||
RUN pnpm --filter server build
|
||||
|
||||
FROM base As server-prod-dep
|
||||
|
@ -55,6 +27,7 @@ COPY packages/tus /app/packages/tus
|
|||
COPY apps/server /app/apps/server
|
||||
RUN pnpm install --filter common --prod
|
||||
RUN pnpm install --filter tus --prod
|
||||
RUN pnpm install --filter utils --prod
|
||||
RUN pnpm install --filter server --prod
|
||||
|
||||
|
||||
|
@ -66,10 +39,8 @@ COPY --from=server-build /app/packages/common/dist ./packages/common/dist
|
|||
COPY --from=server-build /app/packages/tus/dist ./packages/tus/dist
|
||||
COPY --from=server-build /app/apps/server/dist ./apps/server/dist
|
||||
COPY apps/server/entrypoint.sh ./apps/server/entrypoint.sh
|
||||
|
||||
RUN chmod +x ./apps/server/entrypoint.sh
|
||||
RUN apk add --no-cache postgresql-client
|
||||
|
||||
RUN apk add --no-cache ffmpeg
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
|
@ -108,21 +79,15 @@ CMD ["/usr/bin/entrypoint.sh"]
|
|||
|
||||
# 使用 Nginx 的 Alpine 版本作为基础镜像
|
||||
FROM nginx:stable-alpine as nginx
|
||||
|
||||
# 替换 Alpine 的软件源为阿里云镜像
|
||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /usr/share/nginx/html
|
||||
|
||||
# 设置环境变量
|
||||
ENV NODE_ENV production
|
||||
|
||||
# 安装 envsubst 和 inotify-tools
|
||||
RUN apk add --no-cache gettext inotify-tools
|
||||
|
||||
# 创建 /data/uploads 目录
|
||||
RUN mkdir -p /data/uploads
|
||||
|
||||
# 暴露 80 端口
|
||||
EXPOSE 80
|
|
@ -1,21 +1,29 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { TrpcService } from '@server/trpc/trpc.service';
|
||||
import { DepartmentService } from './department.service'; // assuming it's in the same directory
|
||||
import { DepartmentMethodSchema, Prisma, UpdateOrderSchema } from '@nice/common';
|
||||
import {
|
||||
DepartmentMethodSchema,
|
||||
Prisma,
|
||||
UpdateOrderSchema,
|
||||
} from '@nice/common';
|
||||
import { z, ZodType } from 'zod';
|
||||
import { DepartmentRowService } from './department.row.service';
|
||||
|
||||
const DepartmentCreateArgsSchema: ZodType<Prisma.DepartmentCreateArgs> = z.any()
|
||||
const DepartmentUpdateArgsSchema: ZodType<Prisma.DepartmentUpdateArgs> = z.any()
|
||||
const DepartmentFindFirstArgsSchema: ZodType<Prisma.DepartmentFindFirstArgs> = z.any()
|
||||
const DepartmentFindManyArgsSchema: ZodType<Prisma.DepartmentFindManyArgs> = z.any()
|
||||
const DepartmentCreateArgsSchema: ZodType<Prisma.DepartmentCreateArgs> =
|
||||
z.any();
|
||||
const DepartmentUpdateArgsSchema: ZodType<Prisma.DepartmentUpdateArgs> =
|
||||
z.any();
|
||||
const DepartmentFindFirstArgsSchema: ZodType<Prisma.DepartmentFindFirstArgs> =
|
||||
z.any();
|
||||
const DepartmentFindManyArgsSchema: ZodType<Prisma.DepartmentFindManyArgs> =
|
||||
z.any();
|
||||
@Injectable()
|
||||
export class DepartmentRouter {
|
||||
constructor(
|
||||
private readonly trpc: TrpcService,
|
||||
private readonly departmentService: DepartmentService, // 注入 DepartmentService
|
||||
private readonly departmentRowService: DepartmentRowService
|
||||
) { }
|
||||
private readonly departmentRowService: DepartmentRowService,
|
||||
) {}
|
||||
router = this.trpc.router({
|
||||
// 创建部门
|
||||
create: this.trpc.protectProcedure
|
||||
|
@ -36,9 +44,11 @@ export class DepartmentRouter {
|
|||
return this.departmentService.softDeleteByIds(input.ids);
|
||||
}),
|
||||
// 更新部门顺序
|
||||
updateOrder: this.trpc.protectProcedure.input(UpdateOrderSchema).mutation(async ({ input }) => {
|
||||
return this.departmentService.updateOrder(input)
|
||||
}),
|
||||
updateOrder: this.trpc.protectProcedure
|
||||
.input(UpdateOrderSchema)
|
||||
.mutation(async ({ input }) => {
|
||||
return this.departmentService.updateOrder(input);
|
||||
}),
|
||||
// 查询多个部门
|
||||
findMany: this.trpc.procedure
|
||||
.input(DepartmentFindManyArgsSchema) // 假设 StaffMethodSchema.findMany 是根据关键字查找员工的 Zod schema
|
||||
|
@ -53,13 +63,15 @@ export class DepartmentRouter {
|
|||
}),
|
||||
// 获取子部门的简单树结构
|
||||
getChildSimpleTree: this.trpc.procedure
|
||||
.input(DepartmentMethodSchema.getSimpleTree).query(async ({ input }) => {
|
||||
return await this.departmentService.getChildSimpleTree(input)
|
||||
.input(DepartmentMethodSchema.getSimpleTree)
|
||||
.query(async ({ input }) => {
|
||||
return await this.departmentService.getChildSimpleTree(input);
|
||||
}),
|
||||
// 获取父部门的简单树结构
|
||||
getParentSimpleTree: this.trpc.procedure
|
||||
.input(DepartmentMethodSchema.getSimpleTree).query(async ({ input }) => {
|
||||
return await this.departmentService.getParentSimpleTree(input)
|
||||
.input(DepartmentMethodSchema.getSimpleTree)
|
||||
.query(async ({ input }) => {
|
||||
return await this.departmentService.getParentSimpleTree(input);
|
||||
}),
|
||||
// 获取部门行数据
|
||||
getRows: this.trpc.protectProcedure
|
||||
|
|
|
@ -61,6 +61,18 @@ export class StaffRouter {
|
|||
.query(async ({ input }) => {
|
||||
return await this.staffService.findMany(input);
|
||||
}),
|
||||
findManyWithPagination: this.trpc.procedure
|
||||
.input(
|
||||
z.object({
|
||||
page: z.number().optional(),
|
||||
pageSize: z.number().optional(),
|
||||
where: StaffWhereInputSchema.optional(),
|
||||
select: StaffSelectSchema.optional(),
|
||||
}),
|
||||
) // Assuming StaffMethodSchema.findMany is the Zod schema for finding staffs by keyword
|
||||
.query(async ({ input }) => {
|
||||
return await this.staffService.findManyWithPagination(input);
|
||||
}),
|
||||
getRows: this.trpc.protectProcedure
|
||||
.input(StaffMethodSchema.getRows)
|
||||
.query(async ({ input, ctx }) => {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import {
|
||||
db,
|
||||
ObjectType,
|
||||
StaffMethodSchema,
|
||||
UserProfile,
|
||||
RolePerms,
|
||||
ResPerm,
|
||||
Staff,
|
||||
RowModelRequest,
|
||||
db,
|
||||
ObjectType,
|
||||
StaffMethodSchema,
|
||||
UserProfile,
|
||||
RolePerms,
|
||||
ResPerm,
|
||||
Staff,
|
||||
RowModelRequest,
|
||||
} from '@nice/common';
|
||||
import { DepartmentService } from '../department/department.service';
|
||||
import { RowCacheService } from '../base/row-cache.service';
|
||||
|
@ -15,121 +15,116 @@ import { z } from 'zod';
|
|||
import { isFieldCondition } from '../base/sql-builder';
|
||||
@Injectable()
|
||||
export class StaffRowService extends RowCacheService {
|
||||
constructor(
|
||||
private readonly departmentService: DepartmentService,
|
||||
) {
|
||||
super(ObjectType.STAFF, false);
|
||||
constructor(private readonly departmentService: DepartmentService) {
|
||||
super(ObjectType.STAFF, false);
|
||||
}
|
||||
createUnGroupingRowSelect(request?: RowModelRequest): string[] {
|
||||
const result = super
|
||||
.createUnGroupingRowSelect(request)
|
||||
.concat([
|
||||
`${this.tableName}.id AS id`,
|
||||
`${this.tableName}.username AS username`,
|
||||
`${this.tableName}.showname AS showname`,
|
||||
`${this.tableName}.avatar AS avatar`,
|
||||
`${this.tableName}.officer_id AS officer_id`,
|
||||
`${this.tableName}.phone_number AS phone_number`,
|
||||
`${this.tableName}.order AS order`,
|
||||
`${this.tableName}.enabled AS enabled`,
|
||||
'dept.name AS dept_name',
|
||||
'domain.name AS domain_name',
|
||||
]);
|
||||
return result;
|
||||
}
|
||||
createJoinSql(request?: RowModelRequest): string[] {
|
||||
return [
|
||||
`LEFT JOIN department dept ON ${this.tableName}.dept_id = dept.id`,
|
||||
`LEFT JOIN department domain ON ${this.tableName}.domain_id = domain.id`,
|
||||
];
|
||||
}
|
||||
protected createGetRowsFilters(
|
||||
request: z.infer<typeof StaffMethodSchema.getRows>,
|
||||
staff: UserProfile,
|
||||
) {
|
||||
const condition = super.createGetRowsFilters(request);
|
||||
const { domainId, includeDeleted = false } = request;
|
||||
if (isFieldCondition(condition)) {
|
||||
return;
|
||||
}
|
||||
createUnGroupingRowSelect(request?: RowModelRequest): string[] {
|
||||
const result = super.createUnGroupingRowSelect(request).concat([
|
||||
`${this.tableName}.id AS id`,
|
||||
`${this.tableName}.username AS username`,
|
||||
`${this.tableName}.showname AS showname`,
|
||||
`${this.tableName}.avatar AS avatar`,
|
||||
`${this.tableName}.officer_id AS officer_id`,
|
||||
`${this.tableName}.phone_number AS phone_number`,
|
||||
`${this.tableName}.order AS order`,
|
||||
`${this.tableName}.enabled AS enabled`,
|
||||
'dept.name AS dept_name',
|
||||
'domain.name AS domain_name',
|
||||
]);
|
||||
return result
|
||||
if (domainId) {
|
||||
condition.AND.push({
|
||||
field: `${this.tableName}.domain_id`,
|
||||
value: domainId,
|
||||
op: 'equals',
|
||||
});
|
||||
} else {
|
||||
condition.AND.push({
|
||||
field: `${this.tableName}.domain_id`,
|
||||
op: 'blank',
|
||||
});
|
||||
}
|
||||
createJoinSql(request?: RowModelRequest): string[] {
|
||||
return [
|
||||
`LEFT JOIN department dept ON ${this.tableName}.dept_id = dept.id`,
|
||||
`LEFT JOIN department domain ON ${this.tableName}.domain_id = domain.id`,
|
||||
];
|
||||
if (!includeDeleted) {
|
||||
condition.AND.push({
|
||||
field: `${this.tableName}.deleted_at`,
|
||||
type: 'date',
|
||||
op: 'blank',
|
||||
});
|
||||
}
|
||||
protected createGetRowsFilters(
|
||||
request: z.infer<typeof StaffMethodSchema.getRows>,
|
||||
staff: UserProfile,
|
||||
) {
|
||||
const condition = super.createGetRowsFilters(request);
|
||||
const { domainId, includeDeleted = false } = request;
|
||||
if (isFieldCondition(condition)) {
|
||||
return;
|
||||
}
|
||||
if (domainId) {
|
||||
condition.AND.push({
|
||||
field: `${this.tableName}.domain_id`,
|
||||
value: domainId,
|
||||
op: 'equals',
|
||||
});
|
||||
} else {
|
||||
condition.AND.push({
|
||||
field: `${this.tableName}.domain_id`,
|
||||
op: 'blank',
|
||||
});
|
||||
}
|
||||
if (!includeDeleted) {
|
||||
condition.AND.push({
|
||||
field: `${this.tableName}.deleted_at`,
|
||||
type: 'date',
|
||||
op: 'blank',
|
||||
});
|
||||
}
|
||||
condition.OR = [];
|
||||
if (!staff.permissions.includes(RolePerms.MANAGE_ANY_STAFF)) {
|
||||
if (staff.permissions.includes(RolePerms.MANAGE_DOM_STAFF)) {
|
||||
condition.OR.push({
|
||||
field: 'dept.id',
|
||||
value: staff.domainId,
|
||||
op: 'equals',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return condition;
|
||||
}
|
||||
|
||||
async getPermissionContext(id: string, staff: UserProfile) {
|
||||
const data = await db.staff.findUnique({
|
||||
where: { id },
|
||||
select: {
|
||||
deptId: true,
|
||||
domainId: true,
|
||||
},
|
||||
condition.OR = [];
|
||||
if (!staff.permissions.includes(RolePerms.MANAGE_ANY_STAFF)) {
|
||||
if (staff.permissions.includes(RolePerms.MANAGE_DOM_STAFF)) {
|
||||
condition.OR.push({
|
||||
field: 'dept.id',
|
||||
value: staff.domainId,
|
||||
op: 'equals',
|
||||
});
|
||||
const deptId = data?.deptId;
|
||||
const isFromSameDept = staff.deptIds?.includes(deptId);
|
||||
const domainChildDeptIds = await this.departmentService.getDescendantIds(
|
||||
staff.domainId, true
|
||||
);
|
||||
const belongsToDomain = domainChildDeptIds.includes(
|
||||
deptId,
|
||||
);
|
||||
return { isFromSameDept, belongsToDomain };
|
||||
}
|
||||
protected async setResPermissions(
|
||||
data: Staff,
|
||||
staff: UserProfile,
|
||||
) {
|
||||
const permissions: ResPerm = {};
|
||||
const { isFromSameDept, belongsToDomain } = await this.getPermissionContext(
|
||||
data.id,
|
||||
staff,
|
||||
);
|
||||
const setManagePermissions = (permissions: ResPerm) => {
|
||||
Object.assign(permissions, {
|
||||
read: true,
|
||||
delete: true,
|
||||
edit: true,
|
||||
});
|
||||
};
|
||||
staff.permissions.forEach((permission) => {
|
||||
switch (permission) {
|
||||
case RolePerms.MANAGE_ANY_STAFF:
|
||||
setManagePermissions(permissions);
|
||||
break;
|
||||
case RolePerms.MANAGE_DOM_STAFF:
|
||||
if (belongsToDomain) {
|
||||
setManagePermissions(permissions);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
return { ...data, perm: permissions };
|
||||
}
|
||||
}
|
||||
|
||||
return condition;
|
||||
}
|
||||
|
||||
async getPermissionContext(id: string, staff: UserProfile) {
|
||||
const data = await db.staff.findUnique({
|
||||
where: { id },
|
||||
select: {
|
||||
deptId: true,
|
||||
domainId: true,
|
||||
},
|
||||
});
|
||||
const deptId = data?.deptId;
|
||||
const isFromSameDept = staff.deptIds?.includes(deptId);
|
||||
const domainChildDeptIds = await this.departmentService.getDescendantIds(
|
||||
staff.domainId,
|
||||
true,
|
||||
);
|
||||
const belongsToDomain = domainChildDeptIds.includes(deptId);
|
||||
return { isFromSameDept, belongsToDomain };
|
||||
}
|
||||
protected async setResPermissions(data: Staff, staff: UserProfile) {
|
||||
const permissions: ResPerm = {};
|
||||
const { isFromSameDept, belongsToDomain } = await this.getPermissionContext(
|
||||
data.id,
|
||||
staff,
|
||||
);
|
||||
const setManagePermissions = (permissions: ResPerm) => {
|
||||
Object.assign(permissions, {
|
||||
read: true,
|
||||
delete: true,
|
||||
edit: true,
|
||||
});
|
||||
};
|
||||
staff.permissions.forEach((permission) => {
|
||||
switch (permission) {
|
||||
case RolePerms.MANAGE_ANY_STAFF:
|
||||
setManagePermissions(permissions);
|
||||
break;
|
||||
case RolePerms.MANAGE_DOM_STAFF:
|
||||
if (belongsToDomain) {
|
||||
setManagePermissions(permissions);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
return { ...data, perm: permissions };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import EventBus, { CrudOperation } from '@server/utils/event-bus';
|
|||
|
||||
@Injectable()
|
||||
export class StaffService extends BaseService<Prisma.StaffDelegate> {
|
||||
|
||||
constructor(private readonly departmentService: DepartmentService) {
|
||||
super(db, ObjectType.STAFF, true);
|
||||
}
|
||||
|
@ -25,7 +24,10 @@ export class StaffService extends BaseService<Prisma.StaffDelegate> {
|
|||
*/
|
||||
async findByDept(data: z.infer<typeof StaffMethodSchema.findByDept>) {
|
||||
const { deptId, domainId } = data;
|
||||
const childDepts = await this.departmentService.getDescendantIds(deptId, true);
|
||||
const childDepts = await this.departmentService.getDescendantIds(
|
||||
deptId,
|
||||
true,
|
||||
);
|
||||
const result = await db.staff.findMany({
|
||||
where: {
|
||||
deptId: { in: childDepts },
|
||||
|
@ -50,7 +52,9 @@ export class StaffService extends BaseService<Prisma.StaffDelegate> {
|
|||
await this.validateUniqueFields(data, where.id);
|
||||
const updateData = {
|
||||
...data,
|
||||
...(data.password && { password: await argon2.hash(data.password as string) })
|
||||
...(data.password && {
|
||||
password: await argon2.hash(data.password as string),
|
||||
}),
|
||||
};
|
||||
const result = await super.update({ ...args, data: updateData });
|
||||
this.emitDataChangedEvent(result, CrudOperation.UPDATED);
|
||||
|
@ -58,17 +62,26 @@ export class StaffService extends BaseService<Prisma.StaffDelegate> {
|
|||
}
|
||||
private async validateUniqueFields(data: any, excludeId?: string) {
|
||||
const uniqueFields = [
|
||||
{ field: 'officerId', errorMsg: (val: string) => `证件号为${val}的用户已存在` },
|
||||
{ field: 'phoneNumber', errorMsg: (val: string) => `手机号为${val}的用户已存在` },
|
||||
{ field: 'username', errorMsg: (val: string) => `帐号为${val}的用户已存在` }
|
||||
{
|
||||
field: 'officerId',
|
||||
errorMsg: (val: string) => `证件号为${val}的用户已存在`,
|
||||
},
|
||||
{
|
||||
field: 'phoneNumber',
|
||||
errorMsg: (val: string) => `手机号为${val}的用户已存在`,
|
||||
},
|
||||
{
|
||||
field: 'username',
|
||||
errorMsg: (val: string) => `帐号为${val}的用户已存在`,
|
||||
},
|
||||
];
|
||||
for (const { field, errorMsg } of uniqueFields) {
|
||||
if (data[field]) {
|
||||
const count = await db.staff.count({
|
||||
where: {
|
||||
[field]: data[field],
|
||||
...(excludeId && { id: { not: excludeId } })
|
||||
}
|
||||
...(excludeId && { id: { not: excludeId } }),
|
||||
},
|
||||
});
|
||||
if (count > 0) {
|
||||
throw new Error(errorMsg(data[field]));
|
||||
|
@ -77,9 +90,8 @@ export class StaffService extends BaseService<Prisma.StaffDelegate> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private emitDataChangedEvent(data: any, operation: CrudOperation) {
|
||||
EventBus.emit("dataChanged", {
|
||||
EventBus.emit('dataChanged', {
|
||||
type: this.objectType,
|
||||
operation,
|
||||
data,
|
||||
|
@ -87,12 +99,12 @@ export class StaffService extends BaseService<Prisma.StaffDelegate> {
|
|||
}
|
||||
|
||||
/**
|
||||
* 更新员工DomainId
|
||||
* @param data 包含domainId对象
|
||||
* @returns 更新后的员工记录
|
||||
*/
|
||||
* 更新员工DomainId
|
||||
* @param data 包含domainId对象
|
||||
* @returns 更新后的员工记录
|
||||
*/
|
||||
async updateUserDomain(data: { domainId?: string }, staff?: UserProfile) {
|
||||
let { domainId } = data;
|
||||
const { domainId } = data;
|
||||
if (staff.domainId !== domainId) {
|
||||
const result = await this.update({
|
||||
where: { id: staff.id },
|
||||
|
@ -107,7 +119,6 @@ export class StaffService extends BaseService<Prisma.StaffDelegate> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * 根据关键词或ID集合查找员工
|
||||
// * @param data 包含关键词、域ID和ID集合的对象
|
||||
|
@ -176,5 +187,4 @@ export class StaffService extends BaseService<Prisma.StaffDelegate> {
|
|||
|
||||
// return combinedResults;
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -107,10 +107,10 @@ export async function updatePostViewCount(id: string, type: VisitType) {
|
|||
where: { id: course.id },
|
||||
data: {
|
||||
[metaFieldMap[type]]: courseViews._sum.views || 0,
|
||||
meta: {
|
||||
...((post?.meta as any) || {}),
|
||||
[metaFieldMap[type]]: courseViews._sum.views || 0,
|
||||
},
|
||||
// meta: {
|
||||
// ...((post?.meta as any) || {}),
|
||||
// [metaFieldMap[type]]: courseViews._sum.views || 0,
|
||||
// },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -127,10 +127,10 @@ export async function updatePostViewCount(id: string, type: VisitType) {
|
|||
where: { id },
|
||||
data: {
|
||||
[metaFieldMap[type]]: totalViews._sum.views || 0,
|
||||
meta: {
|
||||
...((post?.meta as any) || {}),
|
||||
[metaFieldMap[type]]: totalViews._sum.views || 0,
|
||||
},
|
||||
// meta: {
|
||||
// ...((post?.meta as any) || {}),
|
||||
// [metaFieldMap[type]]: totalViews._sum.views || 0,
|
||||
// },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -41,12 +41,11 @@ export class InitService {
|
|||
|
||||
const existingTaxonomies = await db.taxonomy.findMany();
|
||||
const existingTaxonomyMap = new Map(
|
||||
existingTaxonomies.map((taxonomy) => [taxonomy.name, taxonomy]),
|
||||
existingTaxonomies.map((taxonomy) => [taxonomy.slug, taxonomy]),
|
||||
);
|
||||
|
||||
for (const [index, taxonomy] of InitTaxonomies.entries()) {
|
||||
const existingTaxonomy = existingTaxonomyMap.get(taxonomy.name);
|
||||
|
||||
const existingTaxonomy = existingTaxonomyMap.get(taxonomy.slug);
|
||||
if (!existingTaxonomy) {
|
||||
// Create new taxonomy
|
||||
await db.taxonomy.create({
|
||||
|
@ -56,7 +55,7 @@ export class InitService {
|
|||
},
|
||||
});
|
||||
this.logger.log(`Created new taxonomy: ${taxonomy.name}`);
|
||||
} else {
|
||||
} else if(process.env.NODE_ENV === 'development'){
|
||||
// Check for differences and update if necessary
|
||||
const differences = Object.keys(taxonomy).filter(
|
||||
(key) => taxonomy[key] !== existingTaxonomy[key],
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
VITE_APP_SERVER_IP=192.168.252.239
|
||||
VITE_APP_SERVER_IP=localhost
|
||||
VITE_APP_SERVER_PORT=3000
|
||||
VITE_APP_FILE_PORT=80
|
||||
VITE_APP_VERSION=0.3.0
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<script>
|
||||
window.env = {
|
||||
VITE_APP_SERVER_IP: "$VITE_APP_SERVER_IP",
|
||||
VITE_APP_APP_NAME: "$VITE_APP_APP_NAME",
|
||||
VITE_APP_VERSION: "$VITE_APP_VERSION",
|
||||
VITE_APP_SERVER_IP: "$SERVER_IP",
|
||||
VITE_APP_SERVER_PORT: "$SERVER_PORT",
|
||||
VITE_APP_APP_NAME: "$APP_NAME",
|
||||
VITE_APP_VERSION: "$VERSION",
|
||||
VITE_APP_FILE_PORT: "$FILE_PORT",
|
||||
};
|
||||
</script>
|
||||
<title>fhmooc</title>
|
||||
<title>$APP_NAME</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
"@nice/common": "workspace:^",
|
||||
"@nice/config": "workspace:^",
|
||||
"@nice/iconer": "workspace:^",
|
||||
"@nice/ui": "workspace:^",
|
||||
"@nice/utils": "workspace:^",
|
||||
"@tanstack/query-async-storage-persister": "^5.51.9",
|
||||
"@tanstack/react-query": "^5.51.21",
|
||||
|
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
@ -18,16 +18,6 @@ import type { CarouselRef } from "antd/es/carousel";
|
|||
import { useAppConfig } from "@nice/client";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
|
||||
interface CarouselItem {
|
||||
title: string;
|
||||
desc: string;
|
||||
image: string;
|
||||
action: string;
|
||||
color: string;
|
||||
}
|
||||
|
||||
interface PlatformStat {
|
||||
icon: React.ReactNode;
|
||||
value: number;
|
||||
|
|
0
apps/web/src/app/main/my-duty-path/components/MyDutyPathContainer.tsx
Normal file → Executable file
0
apps/web/src/app/main/my-duty-path/components/MyDutyPathContainer.tsx
Normal file → Executable file
0
apps/web/src/app/main/my-learning/components/MyLearningListContainer.tsx
Normal file → Executable file
0
apps/web/src/app/main/my-learning/components/MyLearningListContainer.tsx
Normal file → Executable file
|
@ -20,9 +20,11 @@ import { useTusUpload } from "@web/src/hooks/useTusUpload";
|
|||
import { useNavigate } from "react-router-dom";
|
||||
import { useAuth } from "@web/src/providers/auth-provider";
|
||||
import { MIND_OPTIONS } from "./constant";
|
||||
import { SaveOutlined } from "@ant-design/icons";
|
||||
import { LinkOutlined, SaveOutlined } from "@ant-design/icons";
|
||||
import JoinButton from "../../models/course/detail/CourseOperationBtns/JoinButton";
|
||||
import { CourseDetailContext } from "../../models/course/detail/PostDetailContext";
|
||||
import ReactDOM from "react-dom";
|
||||
import { createRoot } from "react-dom/client";
|
||||
export default function MindEditor({ id }: { id?: string }) {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const {
|
||||
|
@ -57,6 +59,17 @@ export default function MindEditor({ id }: { id?: string }) {
|
|||
});
|
||||
const { handleFileUpload } = useTusUpload();
|
||||
const [form] = Form.useForm();
|
||||
const CustomLinkIconPlugin = (mind) => {
|
||||
mind.bus.addListener('operation', async () => {
|
||||
const hyperLinkElement = await document.querySelectorAll('.hyper-link');
|
||||
console.log('hyperLinkElement', hyperLinkElement);
|
||||
hyperLinkElement.forEach((item) => {
|
||||
const hyperLinkDom = createRoot(item)
|
||||
hyperLinkDom.render(<LinkOutlined />)
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
if (post?.id && id) {
|
||||
read.mutateAsync({
|
||||
|
@ -98,6 +111,7 @@ export default function MindEditor({ id }: { id?: string }) {
|
|||
nodeMenu: canEdit, // 禁用节点右键菜单
|
||||
keypress: canEdit, // 禁用键盘快捷键
|
||||
});
|
||||
mind.install(CustomLinkIconPlugin);
|
||||
mind.init(MindElixir.new("新思维导图"));
|
||||
containerRef.current.hidden = true;
|
||||
//挂载实例
|
||||
|
@ -173,16 +187,13 @@ export default function MindEditor({ id }: { id?: string }) {
|
|||
}
|
||||
console.log(result);
|
||||
},
|
||||
(error) => {},
|
||||
(error) => { },
|
||||
`mind-thumb-${new Date().toString()}`
|
||||
);
|
||||
};
|
||||
useEffect(() => {
|
||||
containerRef.current.style.height = `${Math.floor(window.innerHeight - 271)}px`;
|
||||
}, []);
|
||||
useEffect(()=>{
|
||||
console.log(canEdit,user?.id,post?.author?.id)
|
||||
})
|
||||
return (
|
||||
<div className={` flex-col flex `}>
|
||||
{taxonomies && (
|
||||
|
@ -214,7 +225,7 @@ export default function MindEditor({ id }: { id?: string }) {
|
|||
multiple
|
||||
/>
|
||||
</Form.Item>
|
||||
<JoinButton></JoinButton>
|
||||
{post && id ? <JoinButton></JoinButton> : <></>}
|
||||
</div>
|
||||
<div>
|
||||
{canEdit && (
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// components/CourseDetailDisplayArea.tsx
|
||||
import { motion, useScroll, useTransform } from "framer-motion";
|
||||
import React, { useContext, useRef, useState } from "react";
|
||||
import React, { useContext, useEffect, useRef, useState } from "react";
|
||||
import { VideoPlayer } from "@web/src/components/presentation/video-player/VideoPlayer";
|
||||
import { CourseDetailDescription } from "./CourseDetailDescription";
|
||||
import { Course, LectureType, PostType } from "@nice/common";
|
||||
|
@ -40,7 +40,7 @@ export const CourseDetailDisplayArea: React.FC = () => {
|
|||
opacity: videoOpacity,
|
||||
}}
|
||||
className="w-full bg-black rounded-lg ">
|
||||
<div className=" w-full ">
|
||||
<div className=" w-full cursor-pointer">
|
||||
<VideoPlayer src={lecture?.meta?.videoUrl} />
|
||||
</div>
|
||||
</motion.div>
|
||||
|
|
0
apps/web/src/components/models/course/detail/CourseOperationBtns/JoinButton.tsx
Normal file → Executable file
0
apps/web/src/components/models/course/detail/CourseOperationBtns/JoinButton.tsx
Normal file → Executable file
|
@ -28,6 +28,7 @@ export default function PostList({
|
|||
renderItem,
|
||||
}: PostListProps) {
|
||||
const [currentPage, setCurrentPage] = useState<number>(params?.page || 1);
|
||||
|
||||
const { data, isLoading }: PostPagnationProps =
|
||||
api.post.findManyWithPagination.useQuery({
|
||||
select: courseDetailSelect,
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import { api } from "@nice/client";
|
||||
|
||||
export default function PostSelect() {
|
||||
const { data } = api.post.findMany.useQuery({
|
||||
where: {
|
||||
title: {
|
||||
contains: ""
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
|
@ -91,6 +91,7 @@ export default function PostSelect({
|
|||
dropdownStyle={{
|
||||
minWidth: 200, // 设置合适的最小宽度
|
||||
}}
|
||||
autoClearSearchValue
|
||||
placeholder={placeholder}
|
||||
onChange={onChange}
|
||||
filterOption={false}
|
||||
|
|
|
@ -25,6 +25,7 @@ export const VideoDisplay: React.FC<VideoDisplayProps> = ({
|
|||
isDragging,
|
||||
setIsDragging,
|
||||
progressRef,
|
||||
isPlaying
|
||||
} = useContext(VideoPlayerContext);
|
||||
|
||||
// 处理进度条拖拽
|
||||
|
@ -191,9 +192,20 @@ export const VideoDisplay: React.FC<VideoDisplayProps> = ({
|
|||
};
|
||||
}, [src, onError, autoPlay]);
|
||||
|
||||
const handleVideoClick = () => {
|
||||
if (videoRef.current && isPlaying) {
|
||||
videoRef.current.pause();
|
||||
setIsPlaying(false);
|
||||
}else if (videoRef.current && !isPlaying) {
|
||||
videoRef.current.play();
|
||||
setIsPlaying(true);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative w-full aspect-video">
|
||||
<div className="relative w-full aspect-video" >
|
||||
<video
|
||||
onClick={handleVideoClick}
|
||||
ref={videoRef}
|
||||
className="w-full h-full"
|
||||
poster={poster}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import { api } from "packages/client/dist";
|
||||
import { ReactNode } from "react";
|
||||
export default function StaffList({ renderItem }: { renderItem: ReactNode }) {
|
||||
const { data } = api.staff.findManyWithPagination.useQuery({});
|
||||
data.items.map((staff) => renderItem);
|
||||
}
|
|
@ -11,6 +11,7 @@ ModuleRegistry.registerModules([ClientSideRowModelModule]);
|
|||
LicenseManager.setLicenseKey(
|
||||
'LICENSE_KEY_BODY[version=v3][0102]_EXPIRY_NDg4NDc0ODcwNTExMw==094bf1c7852b11df1841f4d14457ae96'
|
||||
);
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
import apiClient from "../utils/axios-client";
|
||||
import { AuthSchema, RolePerms, UserProfile } from "@nice/common";
|
||||
import { z } from "zod";
|
||||
import { env } from "../env";
|
||||
interface AuthContextProps {
|
||||
accessToken: string | null;
|
||||
refreshToken: string | null;
|
||||
|
@ -115,10 +116,12 @@ export function AuthProvider({ children }: AuthProviderProps) {
|
|||
const login = async (username: string, password: string): Promise<void> => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
console.error(env.SERVER_IP, env.SERVER_PORT)
|
||||
const response = await apiClient.post(`/auth/login`, {
|
||||
username,
|
||||
password,
|
||||
});
|
||||
|
||||
const {
|
||||
access_token,
|
||||
refresh_token,
|
||||
|
|
|
@ -72,9 +72,7 @@ export const routes: CustomRouteObject[] = [
|
|||
{
|
||||
path: "editor/:id?",
|
||||
element: (
|
||||
<WithAuth>
|
||||
<PathEditorPage></PathEditorPage>
|
||||
</WithAuth>
|
||||
<PathEditorPage></PathEditorPage>
|
||||
),
|
||||
},
|
||||
],
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import axios from 'axios';
|
||||
import { env } from '../env';
|
||||
const BASE_URL = `http://${env.SERVER_IP}:${env?.SERVER_PORT}`
|
||||
|
||||
const apiClient = axios.create({
|
||||
baseURL: BASE_URL,
|
||||
// withCredentials: true,
|
||||
|
|
|
@ -100,7 +100,11 @@ server {
|
|||
# 仅供内部使用
|
||||
internal;
|
||||
# 代理到认证服务
|
||||
<<<<<<< HEAD
|
||||
proxy_pass http://host.docker.internal:3000/auth/file;
|
||||
=======
|
||||
proxy_pass http://host.docker.internal:3001/auth/file;
|
||||
>>>>>>> fdb7b2357a6f025bc5d2ec0a8803142015fb2500
|
||||
|
||||
# 请求优化:不传递请求体
|
||||
proxy_pass_request_body off;
|
||||
|
|
|
@ -14,8 +14,11 @@ done
|
|||
# Check if the index.html file exists before processing
|
||||
if [ -f "/usr/share/nginx/html/index.html" ]; then
|
||||
# Use envsubst to replace environment variable placeholders
|
||||
envsubst < /usr/share/nginx/html/index.html > /usr/share/nginx/html/index.html.tmp
|
||||
echo "Processing /usr/share/nginx/html/index.html"
|
||||
envsubst < /usr/share/nginx/html/index.temp > /usr/share/nginx/html/index.html.tmp
|
||||
mv /usr/share/nginx/html/index.html.tmp /usr/share/nginx/html/index.html
|
||||
echo "Processed content:"
|
||||
cat /usr/share/nginx/html/index.html
|
||||
else
|
||||
echo "Info: /usr/share/nginx/html/index.html does not exist , skip replace env"
|
||||
exit 1
|
||||
|
|
|
@ -1,136 +1,115 @@
|
|||
version: "3.8"
|
||||
services:
|
||||
db:
|
||||
image: postgres:latest
|
||||
ports:
|
||||
- "5432:5432"
|
||||
environment:
|
||||
- POSTGRES_DB=app
|
||||
- POSTGRES_USER=root
|
||||
- POSTGRES_PASSWORD=Letusdoit000
|
||||
volumes:
|
||||
- ./volumes/postgres:/var/lib/postgresql/data
|
||||
# minio:
|
||||
# image: minio/minio
|
||||
# ports:
|
||||
# - "9000:9000"
|
||||
# - "9001:9001"
|
||||
# volumes:
|
||||
# - ./volumes/minio:/minio_data
|
||||
# environment:
|
||||
# - MINIO_ACCESS_KEY=minioadmin
|
||||
# - MINIO_SECRET_KEY=minioadmin
|
||||
# command: minio server /minio_data --console-address ":9001" -address ":9000"
|
||||
# healthcheck:
|
||||
# test:
|
||||
# [
|
||||
# "CMD",
|
||||
# "curl",
|
||||
# "-f",
|
||||
# "http://192.168.2.1:9001/minio/health/live"
|
||||
# ]
|
||||
# interval: 30s
|
||||
# timeout: 20s
|
||||
# retries: 3
|
||||
pgadmin:
|
||||
image: dpage/pgadmin4
|
||||
ports:
|
||||
- "8082:80"
|
||||
environment:
|
||||
- PGADMIN_DEFAULT_EMAIL=insiinc@outlook.com
|
||||
- PGADMIN_DEFAULT_PASSWORD=Letusdoit000
|
||||
# tusd:
|
||||
# image: tusproject/tusd
|
||||
# ports:
|
||||
# - "8080:8080"
|
||||
# environment:
|
||||
# - AWS_REGION=cn-north-1
|
||||
# - AWS_ACCESS_KEY_ID=minioadmin
|
||||
# - AWS_SECRET_ACCESS_KEY=minioadmin
|
||||
# command: -verbose -s3-bucket app -s3-endpoint http://minio:9000 -hooks-http http://host.docker.internal:3000/upload/hook
|
||||
# volumes:
|
||||
# - ./volumes/tusd:/data
|
||||
# extra_hosts:
|
||||
# - "host.docker.internal:host-gateway"
|
||||
# depends_on:
|
||||
# - minio
|
||||
# tusd:
|
||||
# image: tusproject/tusd
|
||||
# ports:
|
||||
# - "8080:8080"
|
||||
# command: -verbose -upload-dir /data -hooks-http http://host.docker.internal:3000/upload/hook
|
||||
# volumes:
|
||||
# - ./uploads:/data
|
||||
# extra_hosts:
|
||||
# - "host.docker.internal:host-gateway"
|
||||
nginx:
|
||||
image: nice-nginx:2.0
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- ./config/nginx/conf.d:/etc/nginx/conf.d
|
||||
- ./config/nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./uploads:/data/uploads # tusd 上传目录
|
||||
- ./web-dist:/usr/share/nginx/html # 添加前端构建文件的挂载
|
||||
- ./config/nginx/entrypoint.sh:/docker-entrypoint.sh
|
||||
environment:
|
||||
- SERVER_IP=host.docker.internal
|
||||
- SERVER_PORT=3000
|
||||
entrypoint: ["/docker-entrypoint.sh"]
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
db:
|
||||
image: postgres:latest
|
||||
ports:
|
||||
- "5432:5432"
|
||||
environment:
|
||||
- POSTGRES_DB=app
|
||||
- POSTGRES_USER=root
|
||||
- POSTGRES_PASSWORD=Letusdoit000
|
||||
volumes:
|
||||
- ./volumes/postgres:/var/lib/postgresql/data
|
||||
# minio:
|
||||
# image: minio/minio
|
||||
# ports:
|
||||
# - "9000:9000"
|
||||
# - "9001:9001"
|
||||
# volumes:
|
||||
# - ./volumes/minio:/minio_data
|
||||
# environment:
|
||||
# - MINIO_ACCESS_KEY=minioadmin
|
||||
# - MINIO_SECRET_KEY=minioadmin
|
||||
# command: minio server /minio_data --console-address ":9001" -address ":9000"
|
||||
# healthcheck:
|
||||
# test:
|
||||
# [
|
||||
# "CMD",
|
||||
# "curl",
|
||||
# "-f",
|
||||
# "http://192.168.2.1:9001/minio/health/live"
|
||||
# ]
|
||||
# interval: 30s
|
||||
# timeout: 20s
|
||||
# retries: 3
|
||||
pgadmin:
|
||||
image: dpage/pgadmin4
|
||||
ports:
|
||||
- "8082:80"
|
||||
environment:
|
||||
- PGADMIN_DEFAULT_EMAIL=insiinc@outlook.com
|
||||
- PGADMIN_DEFAULT_PASSWORD=Letusdoit000
|
||||
|
||||
redis:
|
||||
image: redis:latest
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- ./config/redis.conf:/usr/local/etc/redis/redis.conf
|
||||
- ./volumes/redis:/data
|
||||
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
|
||||
# restic:
|
||||
# image: restic/restic:latest
|
||||
# environment:
|
||||
# - RESTIC_REPOSITORY=/backup
|
||||
# - RESTIC_PASSWORD=Letusdoit000
|
||||
# volumes:
|
||||
# - ./volumes/postgres:/data
|
||||
# - ./volumes/restic-cache:/root/.cache/restic
|
||||
# - ./backup:/backup # 本地目录挂载到容器内的 /backup
|
||||
# - ./config/backup.sh:/usr/local/bin/backup.sh # Mount your script inside the container
|
||||
# entrypoint: /usr/local/bin/backup.sh
|
||||
# depends_on:
|
||||
# - db
|
||||
# web:
|
||||
# image: td-web:latest
|
||||
# ports:
|
||||
# - "80:80"
|
||||
# environment:
|
||||
# - VITE_APP_SERVER_IP=192.168.79.77
|
||||
# - VITE_APP_VERSION=0.3.0
|
||||
# - VITE_APP_APP_NAME=两道防线管理后台
|
||||
# server:
|
||||
# image: td-server:latest
|
||||
# ports:
|
||||
# - "3000:3000"
|
||||
# - "3001:3001"
|
||||
# environment:
|
||||
# - DATABASE_URL=postgresql://root:Letusdoit000@db:5432/app?schema=public
|
||||
# - REDIS_HOST=redis
|
||||
# - REDIS_PORT=6379
|
||||
# - REDIS_PASSWORD=Letusdoit000
|
||||
# - TUS_URL=http://192.168.2.1:8080
|
||||
# - JWT_SECRET=/yT9MnLm/r6NY7ee2Fby6ihCHZl+nFx4OQFKupivrhA=
|
||||
# - PUSH_URL=http://dns:9092
|
||||
# - PUSH_APPID=123
|
||||
# - PUSH_APPSECRET=123
|
||||
# - MINIO_HOST=minio
|
||||
# - ADMIN_PHONE_NUMBER=13258117304
|
||||
# - DEADLINE_CRON=0 0 8 * * *
|
||||
# depends_on:
|
||||
# - db
|
||||
# - redis
|
||||
nginx:
|
||||
image: nice-nginx:latest
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- ./config/nginx/conf.d:/etc/nginx/conf.d
|
||||
- ./config/nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./uploads:/data/uploads # tusd 上传目录
|
||||
- ./web-dist:/usr/share/nginx/html # 添加前端构建文件的挂载
|
||||
- ./config/nginx/entrypoint.sh:/docker-entrypoint.sh
|
||||
environment:
|
||||
- SERVER_IP=192.168.252.77
|
||||
- SERVER_PORT=3000
|
||||
- FILE_PORT=80
|
||||
- APP_NAME=test
|
||||
- VERSION=0.30
|
||||
entrypoint: ["/docker-entrypoint.sh"]
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
redis:
|
||||
image: redis:latest
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- ./config/redis.conf:/usr/local/etc/redis/redis.conf
|
||||
- ./volumes/redis:/data
|
||||
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
|
||||
# restic:
|
||||
# image: restic/restic:latest
|
||||
# environment:
|
||||
# - RESTIC_REPOSITORY=/backup
|
||||
# - RESTIC_PASSWORD=Letusdoit000
|
||||
# volumes:
|
||||
# - ./volumes/postgres:/data
|
||||
# - ./volumes/restic-cache:/root/.cache/restic
|
||||
# - ./backup:/backup # 本地目录挂载到容器内的 /backup
|
||||
# - ./config/backup.sh:/usr/local/bin/backup.sh # Mount your script inside the container
|
||||
# entrypoint: /usr/local/bin/backup.sh
|
||||
# depends_on:
|
||||
# - db
|
||||
# web:
|
||||
# image: td-web:latest
|
||||
# ports:
|
||||
# - "80:80"
|
||||
# environment:
|
||||
# - VITE_APP_SERVER_IP=192.168.79.77
|
||||
# - VITE_APP_VERSION=0.3.0
|
||||
# - VITE_APP_APP_NAME=两道防线管理后台
|
||||
# server:
|
||||
# image: td-server:latest
|
||||
# ports:
|
||||
# - "3000:3000"
|
||||
# - "3001:3001"
|
||||
# environment:
|
||||
# - DATABASE_URL=postgresql://root:Letusdoit000@db:5432/app?schema=public
|
||||
# - REDIS_HOST=redis
|
||||
# - REDIS_PORT=6379
|
||||
# - REDIS_PASSWORD=Letusdoit000
|
||||
# - TUS_URL=http://192.168.2.1:8080
|
||||
# - JWT_SECRET=/yT9MnLm/r6NY7ee2Fby6ihCHZl+nFx4OQFKupivrhA=
|
||||
# - PUSH_URL=http://dns:9092
|
||||
# - PUSH_APPID=123
|
||||
# - PUSH_APPSECRET=123
|
||||
# - MINIO_HOST=minio
|
||||
# - ADMIN_PHONE_NUMBER=13258117304
|
||||
# - DEADLINE_CRON=0 0 8 * * *
|
||||
# depends_on:
|
||||
# - db
|
||||
# - redis
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: remooc
|
||||
default:
|
||||
name: remooc
|
||||
|
|
|
@ -63,6 +63,6 @@ export function useAppConfig() {
|
|||
isLoading,
|
||||
slides,
|
||||
slideLinks,
|
||||
statistics,
|
||||
statistics
|
||||
};
|
||||
}
|
||||
|
|
|
@ -8,9 +8,8 @@
|
|||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"generate": "pnpm prisma generate",
|
||||
"build": "pnpm generate && tsup",
|
||||
"build": "pnpm generate && tsup --no-watch",
|
||||
"dev": "pnpm generate && tsup --watch ",
|
||||
"dev-nowatch": "pnpm generate && tsup --no-watch ",
|
||||
"studio": "pnpm prisma studio",
|
||||
"db:clear": "rm -rf prisma/migrations && pnpm prisma migrate dev --name init",
|
||||
"postinstall": "pnpm generate"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"types": "./dist/index.d.ts",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"build": "tsup --no-watch",
|
||||
"dev": "tsup --watch",
|
||||
"clean": "rimraf dist",
|
||||
"typecheck": "tsc --noEmit"
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
{
|
||||
"name": "@nice/ui",
|
||||
"version": "1.0.0",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "tsup --watch",
|
||||
"clean": "rimraf dist",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dagrejs/dagre": "^1.1.4",
|
||||
"@nice/utils": "workspace:^",
|
||||
"@xyflow/react": "^12.3.6",
|
||||
"dagre": "^0.8.5",
|
||||
"nanoid": "^5.0.9",
|
||||
"react-hotkeys-hook": "^4.6.1",
|
||||
"zustand": "^5.0.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/dagre": "^0.7.52",
|
||||
"@types/node": "^20.3.1",
|
||||
"@types/react": "18.2.38",
|
||||
"@types/react-dom": "18.2.15",
|
||||
"concurrently": "^8.0.0",
|
||||
"rimraf": "^6.0.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"tsup": "^8.3.5",
|
||||
"typescript": "^5.5.4"
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
import { useCallback, useState, useRef, useEffect } from 'react';
|
||||
import {
|
||||
ReactFlow,
|
||||
Controls,
|
||||
Background,
|
||||
useReactFlow,
|
||||
Panel,
|
||||
ReactFlowProvider,
|
||||
NodeOrigin,
|
||||
ConnectionLineType,
|
||||
useStoreApi,
|
||||
InternalNode,
|
||||
} from '@xyflow/react';
|
||||
import MindMapNode from './MindMapNode';
|
||||
import useMindMapStore, { RFState } from './store';
|
||||
import { shallow, useShallow } from 'zustand/shallow';
|
||||
import MindMapEdge from './MindMapEdge';
|
||||
import '@xyflow/react/dist/style.css';
|
||||
import { useFlowKeyboardControls } from './hooks/useFlowKeyboardControl';
|
||||
|
||||
const selector = (state: RFState) => ({
|
||||
nodes: state.nodes,
|
||||
edges: state.edges,
|
||||
onNodesChange: state.onNodesChange,
|
||||
onEdgesChange: state.onEdgesChange,
|
||||
addChildNode: state.addChildNode,
|
||||
addSiblingNode: state.addSiblingNode,
|
||||
selectedNodeId: state.selectedNodeId,
|
||||
setSelectedNodeIdId: state.setSelectedNodeId,
|
||||
undo: state.undo,
|
||||
redo: state.redo,
|
||||
canUndo: state.canUndo,
|
||||
canRedo: state.canRedo
|
||||
|
||||
});
|
||||
const nodeOrigin: NodeOrigin = [0.5, 0.5];
|
||||
// 节点类型定义
|
||||
const nodeTypes = {
|
||||
mindmap: MindMapNode,
|
||||
};
|
||||
|
||||
const edgeTypes = {
|
||||
mindmap: MindMapEdge,
|
||||
};
|
||||
const connectionLineStyle = {
|
||||
stroke: '#999',
|
||||
strokeWidth: 2,
|
||||
radius: 20 // Add corner radius for orthogonal lines
|
||||
};
|
||||
|
||||
const defaultEdgeOptions = {
|
||||
style: connectionLineStyle,
|
||||
type: 'mindmap',
|
||||
animated: false
|
||||
};
|
||||
export function Flow() {
|
||||
const { nodes, edges, onNodesChange, undo, redo, setSelectedNodeIdId, onEdgesChange, addChildNode, addSiblingNode, selectedNodeId } = useMindMapStore(
|
||||
useShallow(selector)
|
||||
);
|
||||
useFlowKeyboardControls()
|
||||
return (
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
nodeTypes={nodeTypes}
|
||||
edgeTypes={edgeTypes}
|
||||
nodeOrigin={nodeOrigin}
|
||||
connectionLineStyle={connectionLineStyle}
|
||||
defaultEdgeOptions={defaultEdgeOptions}
|
||||
connectionLineType={ConnectionLineType.SmoothStep}
|
||||
fitView
|
||||
panOnDrag={[2]}
|
||||
minZoom={0.2}
|
||||
maxZoom={4}
|
||||
nodesConnectable={false}
|
||||
|
||||
>
|
||||
<Background />
|
||||
<Controls />
|
||||
<Panel position="top-left">React Flow Mind Map</Panel>
|
||||
</ReactFlow>
|
||||
);
|
||||
}
|
||||
export function MindMap() {
|
||||
return <ReactFlowProvider>
|
||||
<Flow></Flow>
|
||||
</ReactFlowProvider>
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
import { BaseEdge, EdgeProps, getBezierPath, getStraightPath } from '@xyflow/react';
|
||||
|
||||
function MindMapEdge(props: EdgeProps) {
|
||||
const { sourceX, sourceY, targetX, targetY } = props;
|
||||
|
||||
const [edgePath] = getBezierPath({
|
||||
sourceX,
|
||||
sourceY,
|
||||
targetX,
|
||||
targetY,
|
||||
});
|
||||
|
||||
return <BaseEdge path={edgePath} {...props} />;
|
||||
}
|
||||
|
||||
export default MindMapEdge;
|
|
@ -1,83 +0,0 @@
|
|||
import { Handle, NodeProps, Position, useEdges } from '@xyflow/react';
|
||||
import { MindMapNodeType } from './types';
|
||||
import useMindMapStore, { RFState } from './store';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useShallow } from 'zustand/shallow';
|
||||
import { useClickOutside } from '../../hooks/useClickOutside';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
const selector = (state: RFState) => ({
|
||||
selectedNodeId: state.selectedNodeId,
|
||||
editingNodeId: state.editingNodeId,
|
||||
updateNodeLabel: state.updateNodeLabel,
|
||||
setSelectedNodeId: state.setSelectedNodeId,
|
||||
setEditingNodeId: state.setEditingNodeId
|
||||
|
||||
});
|
||||
function MindMapNode({ id, data }: NodeProps<MindMapNodeType>) {
|
||||
const nodeRef = useRef<HTMLDivElement>(null);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const [inputValue, setInputValue] = useState(data.label);
|
||||
|
||||
const {
|
||||
updateNodeLabel,
|
||||
selectedNodeId,
|
||||
setSelectedNodeId,
|
||||
setEditingNodeId,
|
||||
editingNodeId
|
||||
} = useMindMapStore(useShallow(selector));
|
||||
useEffect(() => {
|
||||
if (editingNodeId === id) {
|
||||
setEditingNodeId(id);
|
||||
setInputValue(data.label);
|
||||
setTimeout(() => {
|
||||
inputRef.current?.focus();
|
||||
inputRef.current?.select();
|
||||
}, 0);
|
||||
} else {
|
||||
inputRef.current?.blur()
|
||||
}
|
||||
}, [editingNodeId])
|
||||
const handleDoubleClick = (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
setEditingNodeId(id)
|
||||
};
|
||||
|
||||
useHotkeys("space", (e) => {
|
||||
if (selectedNodeId === id)
|
||||
setEditingNodeId(id)
|
||||
}, { preventDefault: true });
|
||||
const handleClick = (e: React.MouseEvent) => {
|
||||
setSelectedNodeId(id);
|
||||
};
|
||||
|
||||
useClickOutside(nodeRef, () => {
|
||||
console.log(selectedNodeId, id)
|
||||
if (selectedNodeId === id)
|
||||
setSelectedNodeId(null)
|
||||
if (editingNodeId === id) {
|
||||
setEditingNodeId(null)
|
||||
updateNodeLabel(id, inputValue)
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={nodeRef}
|
||||
onDoubleClick={handleDoubleClick}
|
||||
onClick={handleClick}
|
||||
className={`mindmap-node ${id === selectedNodeId ? 'selected' : ''}`}
|
||||
>
|
||||
<input
|
||||
ref={inputRef}
|
||||
value={inputValue}
|
||||
onChange={(e) => setInputValue(e.target.value)}
|
||||
className="input"
|
||||
readOnly={id !== editingNodeId}
|
||||
/>
|
||||
<Handle type="target" position={Position.Top} />
|
||||
<Handle type="source" position={Position.Top} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default MindMapNode;
|
|
@ -1,11 +0,0 @@
|
|||
import type { Edge, EdgeTypes } from "@xyflow/react";
|
||||
|
||||
export const initialEdges = [
|
||||
{ id: "a->c", source: "a", target: "c", animated: true },
|
||||
{ id: "b->d", source: "b", target: "d" },
|
||||
{ id: "c->d", source: "c", target: "d", animated: true },
|
||||
] satisfies Edge[];
|
||||
|
||||
export const edgeTypes = {
|
||||
// Add your custom edge types here!
|
||||
} satisfies EdgeTypes;
|
|
@ -1,145 +0,0 @@
|
|||
import { useCallback } from 'react';
|
||||
import { useHotkeys } from 'react-hotkeys-hook';
|
||||
import { useStoreApi } from '@xyflow/react';
|
||||
import useMindMapStore, { RFState } from '../store';
|
||||
import { useShallow } from 'zustand/shallow';
|
||||
|
||||
const controlsSelector = (state: RFState) => ({
|
||||
selectedNodeId: state.selectedNodeId,
|
||||
setSelectedNodeId: state.setSelectedNodeId,
|
||||
addChildNode: state.addChildNode,
|
||||
addSiblingNode: state.addSiblingNode,
|
||||
undo: state.undo,
|
||||
redo: state.redo,
|
||||
});
|
||||
|
||||
export function useFlowKeyboardControls() {
|
||||
const {
|
||||
selectedNodeId,
|
||||
setSelectedNodeId,
|
||||
addChildNode,
|
||||
addSiblingNode,
|
||||
undo,
|
||||
redo,
|
||||
} = useMindMapStore(useShallow(controlsSelector));
|
||||
|
||||
const store = useStoreApi();
|
||||
|
||||
const getNextNodeInDirection = useCallback((direction: 'left' | 'right' | 'up' | 'down') => {
|
||||
const { nodeLookup, edges } = store.getState();
|
||||
if (!selectedNodeId) return null;
|
||||
|
||||
const currentNode = nodeLookup.get(selectedNodeId);
|
||||
if (!currentNode) return null;
|
||||
|
||||
// 构建节点关系图
|
||||
const nodeRelations = new Map<string, { parent: string | null; children: string[]; siblings: string[] }>();
|
||||
|
||||
edges.forEach(edge => {
|
||||
const source = edge.source;
|
||||
const target = edge.target;
|
||||
|
||||
if (!nodeRelations.has(source)) {
|
||||
nodeRelations.set(source, { parent: null, children: [], siblings: [] });
|
||||
}
|
||||
if (!nodeRelations.has(target)) {
|
||||
nodeRelations.set(target, { parent: null, children: [], siblings: [] });
|
||||
}
|
||||
|
||||
nodeRelations.get(target)!.parent = source;
|
||||
nodeRelations.get(source)!.children.push(target);
|
||||
});
|
||||
|
||||
// 找出同级节点
|
||||
const currentRelation = nodeRelations.get(selectedNodeId);
|
||||
if (currentRelation?.parent) {
|
||||
const parentRelation = nodeRelations.get(currentRelation.parent);
|
||||
if (parentRelation) {
|
||||
currentRelation.siblings = parentRelation.children.filter(id => id !== selectedNodeId);
|
||||
}
|
||||
}
|
||||
|
||||
// 根据方向决定下一个节点
|
||||
switch (direction) {
|
||||
case 'left': {
|
||||
// 如果当前节点是子节点,优先选择父节点
|
||||
if (currentRelation?.parent) {
|
||||
const parentNode = nodeLookup.get(currentRelation.parent);
|
||||
if (parentNode && parentNode.position.x < currentNode.position.x) {
|
||||
return currentRelation.parent;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'right': {
|
||||
// 如果有子节点,选择第一个子节点
|
||||
const children = currentRelation?.children || [];
|
||||
if (children.length > 0) {
|
||||
return children[0];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'up': {
|
||||
// 在同级节点中找位置靠上的节点
|
||||
const siblings = currentRelation?.siblings || [];
|
||||
const upperSiblings = siblings
|
||||
.map(id => nodeLookup.get(id))
|
||||
.filter(node => node && node.position.y < currentNode.position.y)
|
||||
.sort((a, b) => b!.position.y - a!.position.y);
|
||||
|
||||
if (upperSiblings.length > 0) {
|
||||
return upperSiblings[0]!.id;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'down': {
|
||||
// 在同级节点中找位置靠下的节点
|
||||
const siblings = currentRelation?.siblings || [];
|
||||
const lowerSiblings = siblings
|
||||
.map(id => nodeLookup.get(id))
|
||||
.filter(node => node && node.position.y > currentNode.position.y)
|
||||
.sort((a, b) => a!.position.y - b!.position.y);
|
||||
|
||||
if (lowerSiblings.length > 0) {
|
||||
return lowerSiblings[0]!.id;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}, [selectedNodeId, store]);
|
||||
|
||||
// Tab 键添加子节点
|
||||
useHotkeys('tab', (e) => {
|
||||
e.preventDefault();
|
||||
if (selectedNodeId) addChildNode(selectedNodeId);
|
||||
}, { enableOnFormTags: true, preventDefault: true });
|
||||
|
||||
// Enter 键添加同级节点
|
||||
useHotkeys('enter', (e) => {
|
||||
e.preventDefault();
|
||||
if (selectedNodeId) addSiblingNode(selectedNodeId);
|
||||
}, { enableOnFormTags: true, preventDefault: true });
|
||||
|
||||
// 撤销重做
|
||||
// useHotkeys('ctrl+z, cmd+z', (e) => {
|
||||
|
||||
// undo();
|
||||
// }, { enableOnFormTags: false });
|
||||
|
||||
// useHotkeys('ctrl+y, cmd+y', (e) => {
|
||||
|
||||
// redo();
|
||||
// }, { enableOnFormTags: false });
|
||||
|
||||
// 方向键导航
|
||||
const directions = ['left', 'right', 'up', 'down'] as const;
|
||||
directions.forEach(direction => {
|
||||
useHotkeys(direction, (e) => {
|
||||
e.preventDefault();
|
||||
const nextNodeId = getNextNodeInDirection(direction);
|
||||
if (nextNodeId) setSelectedNodeId(nextNodeId);
|
||||
}, { enableOnFormTags: true });
|
||||
});
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
export * from "./MindMap"
|
|
@ -1,43 +0,0 @@
|
|||
import { Edge, Node } from '@xyflow/react';
|
||||
import dagre from 'dagre';
|
||||
|
||||
export const getLayoutedElements = (nodes: Node[], edges: Edge[], direction = 'LR') => {
|
||||
const dagreGraph = new dagre.graphlib.Graph();
|
||||
dagreGraph.setDefaultEdgeLabel(() => ({}));
|
||||
|
||||
const nodeWidth = 200;
|
||||
const nodeHeight = 50;
|
||||
|
||||
dagreGraph.setGraph({
|
||||
rankdir: direction,
|
||||
nodesep: 80,
|
||||
ranksep: 100
|
||||
});
|
||||
|
||||
// 添加节点
|
||||
nodes.forEach((node) => {
|
||||
dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });
|
||||
});
|
||||
|
||||
// 添加边
|
||||
edges.forEach((edge) => {
|
||||
dagreGraph.setEdge(edge.source, edge.target);
|
||||
});
|
||||
|
||||
// 计算布局
|
||||
dagre.layout(dagreGraph);
|
||||
|
||||
// 获取新的节点位置
|
||||
const layoutedNodes = nodes.map((node) => {
|
||||
const nodeWithPosition = dagreGraph.node(node.id);
|
||||
return {
|
||||
...node,
|
||||
position: {
|
||||
x: nodeWithPosition.x - nodeWidth / 2,
|
||||
y: nodeWithPosition.y - nodeHeight / 2,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return { nodes: layoutedNodes, edges };
|
||||
};
|
|
@ -1,234 +0,0 @@
|
|||
import {
|
||||
Edge,
|
||||
EdgeChange,
|
||||
Node,
|
||||
NodeChange,
|
||||
OnNodesChange,
|
||||
OnEdgesChange,
|
||||
applyNodeChanges,
|
||||
applyEdgeChanges,
|
||||
XYPosition,
|
||||
} from '@xyflow/react';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { create } from 'zustand';
|
||||
import { HistoryData, HistoryState, NodeLayout, NodeRelationType } from './types';
|
||||
import { getLayoutedElements } from './layout';
|
||||
|
||||
|
||||
const createHistoryState = (initialPresent: HistoryData): HistoryState<HistoryData> => ({
|
||||
past: [],
|
||||
present: initialPresent,
|
||||
future: [],
|
||||
});
|
||||
|
||||
const initialNodes: Node[] = [{
|
||||
id: 'root',
|
||||
type: 'mindmap',
|
||||
data: { label: 'React Flow Mind Map' },
|
||||
position: { x: 0, y: 0 },
|
||||
}];
|
||||
|
||||
export type RFState = {
|
||||
nodes: Node[];
|
||||
edges: Edge[];
|
||||
onNodesChange: OnNodesChange;
|
||||
onEdgesChange: OnEdgesChange;
|
||||
history: HistoryState<HistoryData>;
|
||||
addChildNode: (nodeId: string, position?: XYPosition) => void;
|
||||
updateNodeLabel: (nodeId: string, label: string) => void
|
||||
addSiblingNode: (nodeId: string, position?: XYPosition) => void
|
||||
selectedNodeId: string | null;
|
||||
setSelectedNodeId: (nodeId: string | null) => void;
|
||||
editingNodeId: string | null;
|
||||
setEditingNodeId: (nodeId: string | null) => void;
|
||||
isEditing: boolean;
|
||||
undo: () => void;
|
||||
redo: () => void;
|
||||
canUndo: boolean;
|
||||
canRedo: boolean;
|
||||
};
|
||||
const useMindMapStore = create<RFState>((set, get) => {
|
||||
const updateHistory = (newState: Partial<HistoryData>) => {
|
||||
const currentState = get().history.present;
|
||||
return {
|
||||
past: [...get().history.past, currentState],
|
||||
present: { ...currentState, ...newState },
|
||||
future: [],
|
||||
};
|
||||
};
|
||||
|
||||
const createNewNode = (label: string = 'New Node'): Node => ({
|
||||
id: nanoid(),
|
||||
type: 'mindmap',
|
||||
data: { label },
|
||||
position: { x: 0, y: 0 }
|
||||
});
|
||||
const addNode = (
|
||||
parentId: string,
|
||||
relationType: NodeRelationType
|
||||
) => {
|
||||
const { nodes, edges, editingNodeId } = get();
|
||||
const parentNode = nodes.find(node => node.id === parentId);
|
||||
if (!parentNode) return;
|
||||
const newNode = createNewNode();
|
||||
const newEdge = {
|
||||
id: nanoid(),
|
||||
source: relationType === 'child' ? parentId : edges.find(e => e.target === parentId)?.source ?? parentId,
|
||||
target: newNode.id,
|
||||
type: 'smoothstep',
|
||||
};
|
||||
const newNodes = [...nodes, newNode];
|
||||
const newEdges = [...edges, newEdge];
|
||||
const { nodes: layoutedNodes, edges: layoutedEdges } = getLayoutedElements(newNodes, newEdges);
|
||||
set({
|
||||
nodes: layoutedNodes,
|
||||
edges: layoutedEdges,
|
||||
selectedNodeId: newNode.id,
|
||||
history: updateHistory({
|
||||
nodes: layoutedNodes,
|
||||
edges: layoutedEdges,
|
||||
selectedNodeId: newNode.id,
|
||||
editingNodeId,
|
||||
}),
|
||||
});
|
||||
};
|
||||
return {
|
||||
nodes: initialNodes,
|
||||
edges: [],
|
||||
isEditing: false,
|
||||
history: createHistoryState({ nodes: initialNodes, edges: [], selectedNodeId: null, editingNodeId: null }),
|
||||
editingNodeId: null,
|
||||
setEditingNodeId: (nodeId: string | null) => {
|
||||
const { nodes, edges, selectedNodeId } = get();
|
||||
set({
|
||||
editingNodeId: nodeId,
|
||||
isEditing: Boolean(nodeId),
|
||||
history: {
|
||||
past: [...get().history.past, get().history.present],
|
||||
present: {
|
||||
nodes,
|
||||
edges,
|
||||
selectedNodeId,
|
||||
editingNodeId: nodeId
|
||||
},
|
||||
future: [],
|
||||
},
|
||||
});
|
||||
},
|
||||
selectedNodeId: null,
|
||||
setSelectedNodeId: (nodeId: string | null) => {
|
||||
const { nodes, edges, editingNodeId } = get();
|
||||
set({
|
||||
selectedNodeId: nodeId,
|
||||
history: {
|
||||
past: [...get().history.past, get().history.present],
|
||||
present: { nodes, edges, selectedNodeId: nodeId, editingNodeId },
|
||||
future: [],
|
||||
},
|
||||
});
|
||||
},
|
||||
updateNodeLabel: (nodeId: string, label: string) => {
|
||||
const { nodes, edges, selectedNodeId, editingNodeId } = get();
|
||||
const newNodes = nodes.map((node) => {
|
||||
if (node.id === nodeId) {
|
||||
return { ...node, data: { ...node.data, label } };
|
||||
}
|
||||
return node;
|
||||
});
|
||||
set({
|
||||
nodes: newNodes,
|
||||
edges,
|
||||
selectedNodeId,
|
||||
history: {
|
||||
past: [...get().history.past, get().history.present],
|
||||
present: { nodes: newNodes, edges, selectedNodeId, editingNodeId },
|
||||
future: [],
|
||||
},
|
||||
});
|
||||
},
|
||||
onNodesChange: (changes: NodeChange[]) => {
|
||||
console.log('on node change', changes)
|
||||
const { nodes, edges, selectedNodeId } = get();
|
||||
const newNodes = applyNodeChanges(changes, nodes);
|
||||
set({ nodes: newNodes });
|
||||
},
|
||||
onEdgesChange: (changes: EdgeChange[]) => {
|
||||
const { nodes, edges, selectedNodeId } = get();
|
||||
const newEdges = applyEdgeChanges(changes, edges);
|
||||
|
||||
set({ edges: newEdges });
|
||||
},
|
||||
addChildNode: (nodeId: string) =>
|
||||
addNode(nodeId, 'child'),
|
||||
addSiblingNode: (nodeId: string) =>
|
||||
addNode(nodeId, 'sibling'),
|
||||
undo: () => {
|
||||
const { history } = get();
|
||||
console.log('[Undo] Starting undo operation');
|
||||
|
||||
if (history.past.length === 0) {
|
||||
console.log('[Undo] No past states available, undo skipped');
|
||||
return;
|
||||
}
|
||||
const previous = history.past[history.past.length - 1];
|
||||
const newPast = history.past.slice(0, -1);
|
||||
const newPresent = { ...history.present };
|
||||
console.log('[Undo] Previous state:', previous);
|
||||
console.log('[Undo] New past length:', newPast.length);
|
||||
|
||||
set({
|
||||
nodes: previous.nodes,
|
||||
edges: previous.edges,
|
||||
selectedNodeId: previous.selectedNodeId,
|
||||
editingNodeId: previous.editingNodeId,
|
||||
history: {
|
||||
past: newPast,
|
||||
present: previous,
|
||||
future: [newPresent, ...history.future],
|
||||
},
|
||||
});
|
||||
|
||||
console.log('[Undo] Operation completed');
|
||||
},
|
||||
|
||||
redo: () => {
|
||||
const { history } = get();
|
||||
console.log('[Redo] Starting redo operation');
|
||||
|
||||
if (history.future.length === 0) {
|
||||
console.log('[Redo] No future states available, redo skipped');
|
||||
return;
|
||||
}
|
||||
|
||||
const next = history.future[0];
|
||||
const newFuture = history.future.slice(1);
|
||||
|
||||
console.log('[Redo] Next state:', next);
|
||||
console.log('[Redo] New future length:', newFuture.length);
|
||||
|
||||
set({
|
||||
nodes: next.nodes,
|
||||
edges: next.edges,
|
||||
selectedNodeId: next.selectedNodeId,
|
||||
editingNodeId: next.editingNodeId,
|
||||
history: {
|
||||
past: [...history.past, history.present],
|
||||
present: next,
|
||||
future: newFuture,
|
||||
},
|
||||
});
|
||||
|
||||
console.log('[Redo] Operation completed');
|
||||
},
|
||||
get canUndo() {
|
||||
return get().history.past.length > 0;
|
||||
},
|
||||
|
||||
get canRedo() {
|
||||
return get().history.future.length > 0;
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
export default useMindMapStore;
|
|
@ -1,32 +0,0 @@
|
|||
import type { Node, NodeTypes, BuiltInNode, Edge } from "@xyflow/react";
|
||||
|
||||
export type MindMapNodeType = Node<
|
||||
{
|
||||
label: string
|
||||
level: number
|
||||
isExpanded?: boolean
|
||||
metadata?: Record<string, number>
|
||||
}, "mindmap">
|
||||
|
||||
export type MindMapEdgeType = Edge<{
|
||||
label: string
|
||||
}, "mindmap">
|
||||
|
||||
export type HistoryState<T> = {
|
||||
past: T[];
|
||||
present: T;
|
||||
future: T[];
|
||||
};
|
||||
export type HistoryData = {
|
||||
nodes: Node[];
|
||||
edges: Edge[];
|
||||
selectedNodeId: string | null;
|
||||
editingNodeId: string | null; // Add this
|
||||
};
|
||||
export type NodeRelationType = 'child' | 'sibling';
|
||||
export type NodeLayout = {
|
||||
horizontalSpacing: number;
|
||||
verticalSpacing: number;
|
||||
nodeWidth: number;
|
||||
nodeHeight: number;
|
||||
};
|
|
@ -1,15 +0,0 @@
|
|||
import { useEffect, RefObject } from 'react';
|
||||
|
||||
export function useClickOutside<T extends HTMLElement>(ref: RefObject<T>, handler: () => void) {
|
||||
useEffect(() => {
|
||||
function handleClickOutside(event: MouseEvent) {
|
||||
console.log(event.target)
|
||||
if (ref.current && !ref.current.contains(event.target as Node)) {
|
||||
handler();
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
return () => document.removeEventListener('mousedown', handleClickOutside);
|
||||
}, [ref, handler]);
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
export * from "./components/mindmap"
|
|
@ -1,43 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2022",
|
||||
"module": "esnext",
|
||||
"allowJs": true,
|
||||
"lib": [
|
||||
"DOM",
|
||||
"es2022",
|
||||
"DOM.Iterable"
|
||||
],
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"removeComments": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "react-jsx",
|
||||
"esModuleInterop": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noImplicitReturns": false,
|
||||
"noFallthroughCasesInSwitch": false,
|
||||
"noUncheckedIndexedAccess": false,
|
||||
"noImplicitOverride": false,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"outDir": "dist",
|
||||
"incremental": true,
|
||||
"tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo"
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist",
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.ts",
|
||||
"**/__tests__"
|
||||
]
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
import { defineConfig } from 'tsup'
|
||||
|
||||
export default defineConfig({
|
||||
entry: ['src/index.ts'],
|
||||
format: ['esm', 'cjs'],
|
||||
dts: true,
|
||||
clean: true,
|
||||
sourcemap: true,
|
||||
minify: true,
|
||||
external: ['react', 'react-dom'],
|
||||
bundle: true,
|
||||
target: "esnext"
|
||||
})
|
|
@ -6,9 +6,8 @@
|
|||
"types": "./dist/index.d.ts",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"build": "tsup --no-watch",
|
||||
"dev": "tsup --watch",
|
||||
"dev-static": "tsup --no-watch",
|
||||
"clean": "rimraf dist",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
|
|
166
pnpm-lock.yaml
166
pnpm-lock.yaml
|
@ -12,7 +12,7 @@ importers:
|
|||
dependencies:
|
||||
'@nestjs/bullmq':
|
||||
specifier: ^10.2.0
|
||||
version: 10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1))(bullmq@5.34.8)
|
||||
version: 10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)(bullmq@5.34.8)
|
||||
'@nestjs/common':
|
||||
specifier: ^10.3.10
|
||||
version: 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1)
|
||||
|
@ -33,7 +33,7 @@ importers:
|
|||
version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/websockets@10.4.15)(rxjs@7.8.1)
|
||||
'@nestjs/schedule':
|
||||
specifier: ^4.1.0
|
||||
version: 4.1.2(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1))
|
||||
version: 4.1.2(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)
|
||||
'@nestjs/websockets':
|
||||
specifier: ^10.3.10
|
||||
version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)(@nestjs/platform-socket.io@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1)
|
||||
|
@ -148,7 +148,7 @@ importers:
|
|||
version: 10.2.3(chokidar@3.6.0)(typescript@5.7.2)
|
||||
'@nestjs/testing':
|
||||
specifier: ^10.0.0
|
||||
version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15))
|
||||
version: 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)(@nestjs/platform-express@10.4.15)
|
||||
'@types/exceljs':
|
||||
specifier: ^1.3.0
|
||||
version: 1.3.2
|
||||
|
@ -296,9 +296,6 @@ importers:
|
|||
'@nice/iconer':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/iconer
|
||||
'@nice/ui':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/ui
|
||||
'@nice/utils':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/utils
|
||||
|
@ -785,64 +782,6 @@ importers:
|
|||
specifier: ^5.5.4
|
||||
version: 5.7.2
|
||||
|
||||
packages/ui:
|
||||
dependencies:
|
||||
'@dagrejs/dagre':
|
||||
specifier: ^1.1.4
|
||||
version: 1.1.4
|
||||
'@nice/utils':
|
||||
specifier: workspace:^
|
||||
version: link:../utils
|
||||
'@xyflow/react':
|
||||
specifier: ^12.3.6
|
||||
version: 12.3.6(@types/react@18.2.38)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
dagre:
|
||||
specifier: ^0.8.5
|
||||
version: 0.8.5
|
||||
nanoid:
|
||||
specifier: ^5.0.9
|
||||
version: 5.0.9
|
||||
react:
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0
|
||||
react-dom:
|
||||
specifier: 18.2.0
|
||||
version: 18.2.0(react@18.2.0)
|
||||
react-hotkeys-hook:
|
||||
specifier: ^4.6.1
|
||||
version: 4.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
zustand:
|
||||
specifier: ^5.0.3
|
||||
version: 5.0.3(@types/react@18.2.38)(react@18.2.0)(use-sync-external-store@1.4.0(react@18.2.0))
|
||||
devDependencies:
|
||||
'@types/dagre':
|
||||
specifier: ^0.7.52
|
||||
version: 0.7.52
|
||||
'@types/node':
|
||||
specifier: ^20.3.1
|
||||
version: 20.17.12
|
||||
'@types/react':
|
||||
specifier: 18.2.38
|
||||
version: 18.2.38
|
||||
'@types/react-dom':
|
||||
specifier: 18.2.15
|
||||
version: 18.2.15
|
||||
concurrently:
|
||||
specifier: ^8.0.0
|
||||
version: 8.2.2
|
||||
rimraf:
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.1
|
||||
ts-node:
|
||||
specifier: ^10.9.1
|
||||
version: 10.9.2(@swc/core@1.10.6(@swc/helpers@0.5.15))(@types/node@20.17.12)(typescript@5.7.2)
|
||||
tsup:
|
||||
specifier: ^8.3.5
|
||||
version: 8.3.5(@microsoft/api-extractor@7.49.2(@types/node@20.17.12))(@swc/core@1.10.6(@swc/helpers@0.5.15))(jiti@1.21.7)(postcss@8.4.49)(typescript@5.7.2)(yaml@2.7.0)
|
||||
typescript:
|
||||
specifier: ^5.5.4
|
||||
version: 5.7.2
|
||||
|
||||
packages/utils:
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
|
@ -1395,13 +1334,6 @@ packages:
|
|||
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@dagrejs/dagre@1.1.4':
|
||||
resolution: {integrity: sha512-QUTc54Cg/wvmlEUxB+uvoPVKFazM1H18kVHBQNmK2NbrDR5ihOCR6CXLnDSZzMcSQKJtabPUWridBOlJM3WkDg==}
|
||||
|
||||
'@dagrejs/graphlib@2.2.4':
|
||||
resolution: {integrity: sha512-mepCf/e9+SKYy1d02/UkvSy6+6MoyXhVxP8lLDfA7BPE1X1d4dR0sZznmbM8/XVJ1GPM+Svnx7Xj6ZweByWUkw==}
|
||||
engines: {node: '>17.0.0'}
|
||||
|
||||
'@dnd-kit/accessibility@3.1.1':
|
||||
resolution: {integrity: sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==}
|
||||
peerDependencies:
|
||||
|
@ -1987,67 +1919,79 @@ packages:
|
|||
resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.0.5':
|
||||
resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.0.4':
|
||||
resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.0.4':
|
||||
resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.0.4':
|
||||
resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.0.4':
|
||||
resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linux-arm64@0.33.5':
|
||||
resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-arm@0.33.5':
|
||||
resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-s390x@0.33.5':
|
||||
resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-x64@0.33.5':
|
||||
resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.33.5':
|
||||
resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.33.5':
|
||||
resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-wasm32@0.33.5':
|
||||
resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==}
|
||||
|
@ -2515,51 +2459,61 @@ packages:
|
|||
resolution: {integrity: sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.30.1':
|
||||
resolution: {integrity: sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.30.1':
|
||||
resolution: {integrity: sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.30.1':
|
||||
resolution: {integrity: sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-loongarch64-gnu@4.30.1':
|
||||
resolution: {integrity: sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-powerpc64le-gnu@4.30.1':
|
||||
resolution: {integrity: sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.30.1':
|
||||
resolution: {integrity: sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.30.1':
|
||||
resolution: {integrity: sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.30.1':
|
||||
resolution: {integrity: sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.30.1':
|
||||
resolution: {integrity: sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-win32-arm64-msvc@4.30.1':
|
||||
resolution: {integrity: sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==}
|
||||
|
@ -2918,24 +2872,28 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@swc/core-linux-arm64-musl@1.10.6':
|
||||
resolution: {integrity: sha512-hB2xZFmXCKf2iJF5y2z01PSuLqEoUP3jIX/XlIHN+/AIP7PkSKsValE63LnjlnWPnSEI0IxUyRE3T3FzWE/fQQ==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@swc/core-linux-x64-gnu@1.10.6':
|
||||
resolution: {integrity: sha512-PRGPp0I22+oJ8RMGg8M4hXYxEffH3ayu0WoSDPOjfol1F51Wj1tfTWN4wVa2RibzJjkBwMOT0KGLGb/hSEDDXQ==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@swc/core-linux-x64-musl@1.10.6':
|
||||
resolution: {integrity: sha512-SoNBxlA86lnoV9vIz/TCyakLkdRhFSHx6tFMKNH8wAhz1kKYbZfDmpYoIzeQqdTh0tpx8e/Zu1zdK4smovsZqQ==}
|
||||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@swc/core-win32-arm64-msvc@1.10.6':
|
||||
resolution: {integrity: sha512-6L5Y2E+FVvM+BtoA+mJFjf/SjpFr73w2kHBxINxwH8/PkjAjkePDr5m0ibQhPXV61bTwX49+1otzTY85EsUW9Q==}
|
||||
|
@ -4275,9 +4233,6 @@ packages:
|
|||
resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
dagre@0.8.5:
|
||||
resolution: {integrity: sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==}
|
||||
|
||||
dargs@7.0.0:
|
||||
resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -5016,9 +4971,6 @@ packages:
|
|||
graphemer@1.4.0:
|
||||
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
|
||||
|
||||
graphlib@2.1.8:
|
||||
resolution: {integrity: sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==}
|
||||
|
||||
hard-rejection@2.1.0:
|
||||
resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==}
|
||||
engines: {node: '>=6'}
|
||||
|
@ -6706,12 +6658,6 @@ packages:
|
|||
react: '>=16'
|
||||
react-dom: '>=16'
|
||||
|
||||
react-hotkeys-hook@4.6.1:
|
||||
resolution: {integrity: sha512-XlZpbKUj9tkfgPgT9gA+1p7Ey6vFIZHttUjPqpTdyT5nqQ8mHL7elxvSbaC+dpSiHUSmr21Ya1mDxBZG3aje4Q==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.1'
|
||||
react-dom: '>=16.8.1'
|
||||
|
||||
react-is@16.13.1:
|
||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||
|
||||
|
@ -7885,24 +7831,6 @@ packages:
|
|||
react:
|
||||
optional: true
|
||||
|
||||
zustand@5.0.3:
|
||||
resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==}
|
||||
engines: {node: '>=12.20.0'}
|
||||
peerDependencies:
|
||||
'@types/react': '>=18.0.0'
|
||||
immer: '>=9.0.6'
|
||||
react: '>=18.0.0'
|
||||
use-sync-external-store: '>=1.2.0'
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
immer:
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
use-sync-external-store:
|
||||
optional: true
|
||||
|
||||
snapshots:
|
||||
|
||||
'@ag-grid-community/client-side-row-model@32.3.3':
|
||||
|
@ -8911,12 +8839,6 @@ snapshots:
|
|||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.9
|
||||
|
||||
'@dagrejs/dagre@1.1.4':
|
||||
dependencies:
|
||||
'@dagrejs/graphlib': 2.2.4
|
||||
|
||||
'@dagrejs/graphlib@2.2.4': {}
|
||||
|
||||
'@dnd-kit/accessibility@3.1.1(react@18.2.0)':
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
|
@ -9654,15 +9576,15 @@ snapshots:
|
|||
'@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3':
|
||||
optional: true
|
||||
|
||||
'@nestjs/bull-shared@10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1))':
|
||||
'@nestjs/bull-shared@10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)':
|
||||
dependencies:
|
||||
'@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1)
|
||||
'@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1)
|
||||
tslib: 2.8.1
|
||||
|
||||
'@nestjs/bullmq@10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1))(bullmq@5.34.8)':
|
||||
'@nestjs/bullmq@10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)(bullmq@5.34.8)':
|
||||
dependencies:
|
||||
'@nestjs/bull-shared': 10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1))
|
||||
'@nestjs/bull-shared': 10.2.3(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)
|
||||
'@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1)
|
||||
'@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1)
|
||||
bullmq: 5.34.8
|
||||
|
@ -9759,7 +9681,7 @@ snapshots:
|
|||
- supports-color
|
||||
- utf-8-validate
|
||||
|
||||
'@nestjs/schedule@4.1.2(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1))':
|
||||
'@nestjs/schedule@4.1.2(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)':
|
||||
dependencies:
|
||||
'@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1)
|
||||
'@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1)
|
||||
|
@ -9777,7 +9699,7 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- chokidar
|
||||
|
||||
'@nestjs/testing@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15))':
|
||||
'@nestjs/testing@10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.4.15)(@nestjs/platform-express@10.4.15)':
|
||||
dependencies:
|
||||
'@nestjs/common': 10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1)
|
||||
'@nestjs/core': 10.4.15(@nestjs/common@10.4.15(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.4.15)(@nestjs/websockets@10.4.15)(reflect-metadata@0.2.2)(rxjs@7.8.1)
|
||||
|
@ -12118,11 +12040,6 @@ snapshots:
|
|||
d3-selection: 3.0.0
|
||||
d3-transition: 3.0.1(d3-selection@3.0.0)
|
||||
|
||||
dagre@0.8.5:
|
||||
dependencies:
|
||||
graphlib: 2.1.8
|
||||
lodash: 4.17.21
|
||||
|
||||
dargs@7.0.0: {}
|
||||
|
||||
date-fns@2.30.0:
|
||||
|
@ -12984,10 +12901,6 @@ snapshots:
|
|||
|
||||
graphemer@1.4.0: {}
|
||||
|
||||
graphlib@2.1.8:
|
||||
dependencies:
|
||||
lodash: 4.17.21
|
||||
|
||||
hard-rejection@2.1.0: {}
|
||||
|
||||
has-flag@4.0.0: {}
|
||||
|
@ -14872,11 +14785,6 @@ snapshots:
|
|||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
|
||||
react-hotkeys-hook@4.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
|
||||
react-is@16.13.1: {}
|
||||
|
||||
react-is@18.3.1: {}
|
||||
|
@ -16106,9 +16014,3 @@ snapshots:
|
|||
optionalDependencies:
|
||||
'@types/react': 18.2.38
|
||||
react: 18.2.0
|
||||
|
||||
zustand@5.0.3(@types/react@18.2.38)(react@18.2.0)(use-sync-external-store@1.4.0(react@18.2.0)):
|
||||
optionalDependencies:
|
||||
'@types/react': 18.2.38
|
||||
react: 18.2.0
|
||||
use-sync-external-store: 1.4.0(react@18.2.0)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const r=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:40,height:40,viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M20 2H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h4l4 4l4-4h4a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2m-8 2.3c1.5 0 2.7 1.2 2.7 2.7S13.5 9.7 12 9.7S9.3 8.5 9.3 7s1.2-2.7 2.7-2.7M18 15H6v-.9c0-2 4-3.1 6-3.1s6 1.1 6 3.1z"}));export{r as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const h=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},e.createElement("path",{fill:"currentColor",d:"M11 13H5v-2h6V5h2v6h6v2h-6v6h-2z"}));export{h as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const l=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},e.createElement("path",{fill:"currentColor",d:"M12 23C6.443 21.765 2 16.522 2 11V5l10-4l10 4v6c0 5.524-4.443 10.765-10 12M4 6v5a10.58 10.58 0 0 0 8 10a10.58 10.58 0 0 0 8-10V6l-8-3Z"}),e.createElement("circle",{cx:12,cy:8.5,r:2.5,fill:"currentColor"}),e.createElement("path",{fill:"currentColor",d:"M7 15a5.78 5.78 0 0 0 5 3a5.78 5.78 0 0 0 5-3c-.025-1.896-3.342-3-5-3c-1.667 0-4.975 1.104-5 3"}));export{l as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as l}from"./index-De5TXRhh.js";const h=t=>l.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},l.createElement("path",{fill:"currentColor",d:"m6.923 13.442l1.848-4.75H5.038l-1.267 1.904H3.02l.827-2.865l-.827-2.885h.752L5.04 6.75h3.73L6.923 2h1l3.335 4.75h3.146q.413 0 .697.284q.284.283.284.697t-.284.687q-.284.274-.697.274h-3.146l-3.335 4.75zM16.096 22l-3.335-4.75H9.617q-.414 0-.698-.284q-.283-.283-.283-.697t.283-.697t.698-.284h3.146l3.334-4.73h1l-1.848 4.73h3.733l1.267-1.884H21l-.827 2.865l.827 2.885h-.752l-1.267-1.904h-3.733L17.096 22z"}));export{h as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const h=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M4.5 20q-.213 0-.356-.144T4 19.499t.144-.356T4.5 19h15q.213 0 .356.144t.144.357t-.144.356T19.5 20zm4-3.75q-.213 0-.356-.144T8 15.749t.144-.356t.356-.143h7q.213 0 .356.144t.144.357t-.144.356t-.356.143zm-4-3.75q-.213 0-.356-.144T4 11.999t.144-.356t.356-.143h15q.213 0 .356.144t.144.357t-.144.356t-.356.143zm4-3.75q-.213 0-.356-.144T8 8.249t.144-.356t.356-.143h7q.213 0 .356.144t.144.357t-.144.356t-.356.143zM4.5 5q-.213 0-.356-.144T4 4.499t.144-.356T4.5 4h15q.213 0 .356.144t.144.357t-.144.356T19.5 5z"}));export{h as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const h=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M4.5 20q-.213 0-.356-.144T4 19.499t.144-.356T4.5 19h15q.213 0 .356.144t.144.357t-.144.356T19.5 20zm0-3.75q-.213 0-.356-.144T4 15.749t.144-.356t.356-.143h15q.213 0 .356.144t.144.357t-.144.356t-.356.143zm0-3.75q-.213 0-.356-.144T4 11.999t.144-.356t.356-.143h15q.213 0 .356.144t.144.357t-.144.356t-.356.143zm0-3.75q-.213 0-.356-.144T4 8.249t.144-.356t.356-.143h15q.213 0 .356.144t.144.357t-.144.356t-.356.143zM4.5 5q-.213 0-.356-.144T4 4.499t.144-.356T4.5 4h15q.213 0 .356.144t.144.357t-.144.356T19.5 5z"}));export{h as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const h=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M4.5 20q-.213 0-.356-.144T4 19.499t.144-.356T4.5 19h15q.213 0 .356.144t.144.357t-.144.356T19.5 20zm0-3.75q-.213 0-.356-.144T4 15.749t.144-.356t.356-.143h9q.213 0 .356.144t.144.357t-.144.356t-.356.143zm0-3.75q-.213 0-.356-.144T4 11.999t.144-.356t.356-.143h15q.213 0 .356.144t.144.357t-.144.356t-.356.143zm0-3.75q-.213 0-.356-.144T4 8.249t.144-.356t.356-.143h9q.213 0 .356.144t.144.357t-.144.356t-.356.143zM4.5 5q-.213 0-.356-.144T4 4.499t.144-.356T4.5 4h15q.213 0 .356.144t.144.357t-.144.356T19.5 5z"}));export{h as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const h=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M4.5 5q-.213 0-.356-.144T4 4.499t.144-.356T4.5 4h15q.213 0 .356.144t.144.357t-.144.356T19.5 5zm6 3.75q-.213 0-.356-.144T10 8.249t.144-.356t.356-.143h9q.213 0 .356.144t.144.357t-.144.356t-.356.143zm-6 3.75q-.213 0-.356-.144T4 11.999t.144-.356t.356-.143h15q.213 0 .356.144t.144.357t-.144.356t-.356.143zm6 3.75q-.213 0-.356-.144T10 15.749t.144-.356t.356-.143h9q.213 0 .356.144t.144.357t-.144.356t-.356.143zM4.5 20q-.213 0-.356-.144T4 19.499t.144-.356T4.5 19h15q.213 0 .356.144t.144.357t-.144.356T19.5 20z"}));export{h as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as l}from"./index-De5TXRhh.js";const r=t=>l.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},l.createElement("path",{fill:"currentColor",d:"m23 12l-2.44-2.78l.34-3.68l-3.61-.82l-1.89-3.18L12 3L8.6 1.54L6.71 4.72l-3.61.81l.34 3.68L1 12l2.44 2.78l-.34 3.69l3.61.82l1.89 3.18L12 21l3.4 1.46l1.89-3.18l3.61-.82l-.34-3.68zm-13 5l-4-4l1.41-1.41L10 14.17l6.59-6.59L18 9z"}));export{r as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const l=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"m11.565 13.873l-2.677-2.677q-.055-.055-.093-.129q-.037-.073-.037-.157q0-.168.11-.289q.112-.121.294-.121h5.677q.181 0 .292.124t.111.288q0 .042-.13.284l-2.677 2.677q-.093.093-.2.143t-.235.05t-.235-.05t-.2-.143"}));export{l as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as l}from"./index-De5TXRhh.js";const t=a=>l.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:40,height:40,viewBox:"0 0 36 36",...a},l.createElement("path",{fill:"currentColor",d:"m33.53 18.76l-6.93-3.19V6.43a1 1 0 0 0-.6-.9l-7.5-3.45a1 1 0 0 0-.84 0l-7.5 3.45a1 1 0 0 0-.58.91v9.14l-6.9 3.18a1 1 0 0 0-.58.91v9.78a1 1 0 0 0 .58.91l7.5 3.45a1 1 0 0 0 .84 0l7.08-3.26l7.08 3.26a1 1 0 0 0 .84 0l7.5-3.45a1 1 0 0 0 .58-.91v-9.78a1 1 0 0 0-.57-.91M25.61 22l-5.11-2.33l5.11-2.35l5.11 2.35Zm-1-6.44l-6.44 3v-7.69a1 1 0 0 0 .35-.08L24.6 8v7.58ZM18.1 4.08l5.11 2.35l-5.11 2.35L13 6.43Zm-7.5 13.23l5.11 2.35L10.6 22l-5.11-2.33Zm6.5 11.49l-6.5 3v-7.69A1 1 0 0 0 11 24l6.08-2.8Zm15 0l-6.46 3v-7.69A1 1 0 0 0 26 24l6.08-2.8Z",className:"clr-i-solid clr-i-solid-path-1"}),l.createElement("path",{fill:"none",d:"M0 0h36v36H0z"}));export{t as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const r=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M8.916 18.25q-.441 0-.74-.299t-.299-.74V6.79q0-.441.299-.74t.74-.299h3.159q1.433 0 2.529.904T15.7 9.006q0 .967-.508 1.693t-1.257 1.065q.913.255 1.55 1.073t.638 1.97q0 1.61-1.202 2.527q-1.202.916-2.646.916zm.236-1.184h3.062q1.161 0 1.875-.7q.715-.699.715-1.627q0-.93-.714-1.629q-.715-.698-1.894-.698H9.152zm0-5.816h2.864q.997 0 1.69-.617t.692-1.546q0-.947-.704-1.553q-.704-.605-1.667-.605H9.152z"}));export{r as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const l=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 16 16",...t},e.createElement("path",{fill:"currentColor",fillRule:"evenodd",d:"M6.705 11.823a.73.73 0 0 1-1.205-.552V4.729a.73.73 0 0 1 1.205-.552L10.214 7.2a1 1 0 0 1 .347.757v.084a1 1 0 0 1-.347.757z",clipRule:"evenodd"}));export{l as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const r=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},e.createElement("path",{fill:"currentColor",d:"M11 13.5v8H3v-8zm-2 2H5v4h4zM12 2l5.5 9h-11zm0 3.86L10.08 9h3.84zM17.5 13c2.5 0 4.5 2 4.5 4.5S20 22 17.5 22S13 20 13 17.5s2-4.5 4.5-4.5m0 2a2.5 2.5 0 0 0-2.5 2.5a2.5 2.5 0 0 0 2.5 2.5a2.5 2.5 0 0 0 2.5-2.5a2.5 2.5 0 0 0-2.5-2.5"}));export{r as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const l=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},e.createElement("path",{fill:"currentColor",d:"m9.55 18l-5.7-5.7l1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"}));export{l as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const o=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 48 48",...t},e.createElement("g",{fill:"none",stroke:"currentColor",strokeLinejoin:"round",strokeWidth:4},e.createElement("path",{d:"M24 44a19.94 19.94 0 0 0 14.142-5.858A19.94 19.94 0 0 0 44 24a19.94 19.94 0 0 0-5.858-14.142A19.94 19.94 0 0 0 24 4A19.94 19.94 0 0 0 9.858 9.858A19.94 19.94 0 0 0 4 24a19.94 19.94 0 0 0 5.858 14.142A19.94 19.94 0 0 0 24 44Z"}),e.createElement("path",{strokeLinecap:"round",d:"m16 24l6 6l12-12"})));export{o as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as a}from"./index-De5TXRhh.js";const h=t=>a.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:40,height:40,viewBox:"0 0 24 24",...t},a.createElement("path",{fill:"currentColor",d:"M13.75 2.25a.75.75 0 0 1 .75.75v4A.75.75 0 0 1 13 7V5.75H3a.75.75 0 0 1 0-1.5h10V3a.75.75 0 0 1 .75-.75M17.25 5a.75.75 0 0 1 .75-.75h3a.75.75 0 0 1 0 1.5h-3a.75.75 0 0 1-.75-.75m-6.5 4.25a.75.75 0 0 1 .75.75v1.25H21a.75.75 0 0 1 0 1.5h-9.5V14a.75.75 0 0 1-1.5 0v-4a.75.75 0 0 1 .75-.75M2.25 12a.75.75 0 0 1 .75-.75h4a.75.75 0 0 1 0 1.5H3a.75.75 0 0 1-.75-.75m11.5 4.25a.75.75 0 0 1 .75.75v4a.75.75 0 0 1-1.5 0v-1.25H3a.75.75 0 0 1 0-1.5h10V17a.75.75 0 0 1 .75-.75m3.5 2.75a.75.75 0 0 1 .75-.75h3a.75.75 0 0 1 0 1.5h-3a.75.75 0 0 1-.75-.75"}));export{h as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const h=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M5.73 15.885h12.54v-1H5.73zm0-3.385h12.54v-1H5.73zm0-3.384h8.77v-1H5.73zM4.616 19q-.69 0-1.153-.462T3 17.384V6.616q0-.691.463-1.153T4.615 5h14.77q.69 0 1.152.463T21 6.616v10.769q0 .69-.463 1.153T19.385 19zm0-1h14.77q.23 0 .423-.192t.192-.424V6.616q0-.231-.192-.424T19.385 6H4.615q-.23 0-.423.192T4 6.616v10.769q0 .23.192.423t.423.192M4 18V6z"}));export{h as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const q=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M9.116 17q-.691 0-1.153-.462T7.5 15.385V4.615q0-.69.463-1.153T9.116 3h7.769q.69 0 1.153.462t.462 1.153v10.77q0 .69-.462 1.152T16.884 17zm0-1h7.769q.23 0 .423-.192t.192-.423V4.615q0-.23-.192-.423T16.884 4H9.116q-.231 0-.424.192t-.192.423v10.77q0 .23.192.423t.423.192m-3 4q-.69 0-1.153-.462T4.5 18.385V6.615h1v11.77q0 .23.192.423t.423.192h8.77v1zM8.5 16V4z"}));export{q as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const l=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 256 256",...t},e.createElement("g",{fill:"currentColor"},e.createElement("path",{d:"M128 129.09V232a8 8 0 0 1-3.84-1l-88-48.16a8 8 0 0 1-4.16-7V80.2a8 8 0 0 1 .7-3.27Z",opacity:.2}),e.createElement("path",{d:"m223.68 66.15l-88-48.15a15.88 15.88 0 0 0-15.36 0l-88 48.17a16 16 0 0 0-8.32 14v95.64a16 16 0 0 0 8.32 14l88 48.17a15.88 15.88 0 0 0 15.36 0l88-48.17a16 16 0 0 0 8.32-14V80.18a16 16 0 0 0-8.32-14.03M128 32l80.34 44L128 120L47.66 76ZM40 90l80 43.78v85.79l-80-43.75Zm96 129.57v-85.75L216 90v85.78Z"})));export{l as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const m=h=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 2048 2048",...h},t.createElement("path",{fill:"currentColor",d:"M1792 993q60 41 107 93t81 114t50 131t18 141q0 119-45 224t-124 183t-183 123t-224 46q-91 0-176-27t-156-78t-126-122t-85-157H128V128h256V0h128v128h896V0h128v128h256zM256 256v256h1408V256h-128v128h-128V256H512v128H384V256zm643 1280q-3-31-3-64q0-86 24-167t73-153h-97v-128h128v86q41-51 91-90t108-67t121-42t128-15q100 0 192 33V640H256v896zm573 384q93 0 174-35t142-96t96-142t36-175q0-93-35-174t-96-142t-142-96t-175-36q-93 0-174 35t-142 96t-96 142t-36 175q0 93 35 174t96 142t142 96t175 36m64-512h192v128h-320v-384h128zM384 1024h128v128H384zm256 0h128v128H640zm0-256h128v128H640zm-256 512h128v128H384zm256 0h128v128H640zm384-384H896V768h128zm256 0h-128V768h128zm256 0h-128V768h128z"}));export{m as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const r=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:40,height:40,viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M7 21q-.825 0-1.412-.587T5 19V6H4V4h5V3h6v1h5v2h-1v13q0 .825-.587 1.413T17 21zM17 6H7v13h10zM9 17h2V8H9zm4 0h2V8h-2zM7 6v13z"}));export{r as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const o=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},e.createElement("path",{fill:"currentColor",d:"M3 21v-4.25L17.625 2.175L21.8 6.45L7.25 21zM17.6 7.8L19 6.4L17.6 5l-1.4 1.4z"}));export{o as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const h=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},e.createElement("path",{fill:"currentColor",d:"M12 4c-4.42 0-8 3.58-8 8s3.58 8 8 8s8-3.58 8-8s-3.58-8-8-8m1 13h-2v-2h2zm0-4h-2V7h2z",opacity:.3}),e.createElement("path",{fill:"currentColor",d:"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2M12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8s8 3.58 8 8s-3.58 8-8 8m-1-5h2v2h-2zm0-8h2v6h-2z"}));export{h as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const r=T=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...T},t.createElement("path",{fill:"currentColor",d:"M12 17q.425 0 .713-.288T13 16t-.288-.712T12 15t-.712.288T11 16t.288.713T12 17m-1-4h2V7h-2zm1 9q-2.075 0-3.9-.788t-3.175-2.137T2.788 15.9T2 12t.788-3.9t2.137-3.175T8.1 2.788T12 2t3.9.788t3.175 2.137T21.213 8.1T22 12t-.788 3.9t-2.137 3.175t-3.175 2.138T12 22m0-2q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m0-8"}));export{r as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const l=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 16 16",...t},e.createElement("path",{fill:"currentColor",d:"M12 10V8H7V6h5V4l3 3zm-1-1v4H6v3l-6-3V0h11v5h-1V1H2l4 2v9h4V9z"}));export{l as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const r=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 512 512",...t},e.createElement("path",{fill:"currentColor",d:"M472 168H40a24 24 0 0 1 0-48h432a24 24 0 0 1 0 48m-80 112H120a24 24 0 0 1 0-48h272a24 24 0 0 1 0 48m-96 112h-80a24 24 0 0 1 0-48h80a24 24 0 0 1 0 48"}));export{r as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const a=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 28 28",...t},e.createElement("path",{fill:"currentColor",d:"M13 20.5c0 2.098.862 3.995 2.25 5.357q-1.077.142-2.25.143c-5.79 0-10-2.567-10-6.285V19a3 3 0 0 1 3-3h8.5a7.47 7.47 0 0 0-1.5 4.5M13 2a6 6 0 1 1 0 12a6 6 0 0 1 0-12m14 18.5a6.5 6.5 0 1 1-13 0a6.5 6.5 0 0 1 13 0m-5.786-3.96a.742.742 0 0 0-1.428 0l-.716 2.298h-2.318c-.727 0-1.03.97-.441 1.416l1.875 1.42l-.716 2.298c-.225.721.567 1.32 1.155.875l1.875-1.42l1.875 1.42c.588.446 1.38-.154 1.155-.875l-.716-2.298l1.875-1.42c.588-.445.286-1.416-.441-1.416H21.93z"}));export{a as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as h}from"./index-De5TXRhh.js";const v=e=>h.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},h.createElement("path",{fill:"currentColor",d:"M11.5 16V9h-3V8h7v1h-3v7zm-9.115 5.616v-4.232H4V6.616H2.385V2.385h4.23V4h10.77V2.385h4.23v4.23H20v10.77h1.616v4.23h-4.232V20H6.616v1.616zM6.615 19h10.77v-1.616H19V6.616h-1.616V5H6.616v1.616H5v10.769h1.616z"}));export{v as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const t=r=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...r},e.createElement("path",{fill:"currentColor",d:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10s10-4.48 10-10S17.52 2 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8s8 3.59 8 8s-3.59 8-8 8"}),e.createElement("circle",{cx:8,cy:14,r:2,fill:"currentColor"}),e.createElement("circle",{cx:12,cy:8,r:2,fill:"currentColor"}),e.createElement("circle",{cx:16,cy:14,r:2,fill:"currentColor"}));export{t as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const o=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...t},e.createElement("g",{fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:1.5},e.createElement("path",{d:"M2.5 12.89H7l3-5l4 9l3-5h4.43"}),e.createElement("path",{d:"M12 21.5a9.5 9.5 0 1 0 0-19a9.5 9.5 0 0 0 0 19"})));export{o as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const o=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M12 21q-3.45 0-6.012-2.287T3.05 13H5.1q.35 2.6 2.313 4.3T12 19q2.925 0 4.963-2.037T19 12t-2.037-4.962T12 5q-1.725 0-3.225.8T6.25 8H9v2H3V4h2v2.35q1.275-1.6 3.113-2.475T12 3q1.875 0 3.513.713t2.85 1.924t1.925 2.85T21 12t-.712 3.513t-1.925 2.85t-2.85 1.925T12 21m2.8-4.8L11 12.4V7h2v4.6l3.2 3.2z"}));export{o as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const r=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:40,height:40,viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M12 3L2 12h3v8h6v-6h2v6h6v-8h3zm5 15h-2v-6H9v6H7v-7.81l5-4.5l5 4.5z"}),t.createElement("path",{fill:"currentColor",d:"M7 10.19V18h2v-6h6v6h2v-7.81l-5-4.5z",opacity:.3}));export{r as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const o=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M5.5 12.5q-.213 0-.356-.144T5 11.999t.144-.356t.356-.143h13q.213 0 .356.144t.144.357t-.144.356t-.356.143z"}));export{o as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./index-De5TXRhh.js";const r=t=>e.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 50 50",...t},e.createElement("path",{fill:"currentColor",d:"M39 38H11c-1.7 0-3-1.3-3-3V15c0-1.7 1.3-3 3-3h28c1.7 0 3 1.3 3 3v20c0 1.7-1.3 3-3 3M11 14c-.6 0-1 .4-1 1v20c0 .6.4 1 1 1h28c.6 0 1-.4 1-1V15c0-.6-.4-1-1-1z"}),e.createElement("path",{fill:"currentColor",d:"M30 24c-2.2 0-4-1.8-4-4s1.8-4 4-4s4 1.8 4 4s-1.8 4-4 4m0-6c-1.1 0-2 .9-2 2s.9 2 2 2s2-.9 2-2s-.9-2-2-2m5.3 19.7L19 22.4L9.7 31l-1.4-1.4l10.7-10l17.7 16.7z"}),e.createElement("path",{fill:"currentColor",d:"M40.4 32.7L35 28.3L30.5 32l-1.3-1.6l5.8-4.7l6.6 5.4z"}));export{r as default};
|
|
@ -1 +0,0 @@
|
|||
import{r as l}from"./index-De5TXRhh.js";const a=e=>l.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},l.createElement("g",{fill:"none",fillRule:"evenodd"},l.createElement("path",{d:"m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z"}),l.createElement("path",{fill:"currentColor",d:"M5.83 5.106A2 2 0 0 1 7.617 4h8.764a2 2 0 0 1 1.789 1.106l3.512 7.025a3 3 0 0 1 .318 1.34V19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-5.528a3 3 0 0 1 .317-1.341zM16.381 6H7.618L4.12 13H7.5A1.5 1.5 0 0 1 9 14.5v1a.5.5 0 0 0 .5.5h5a.5.5 0 0 0 .5-.5v-1a1.5 1.5 0 0 1 1.5-1.5h3.38z"})));export{a as default};
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
import{r as t}from"./index-De5TXRhh.js";const l=e=>t.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",...e},t.createElement("path",{fill:"currentColor",d:"M6.346 18.25q-.234 0-.396-.162t-.161-.397t.161-.396t.396-.16h3.077l3.48-10.27H9.828q-.234 0-.396-.162t-.162-.397t.162-.395t.396-.161h7.192q.235 0 .396.162t.162.397t-.162.396q-.161.16-.396.16h-2.961l-3.481 10.27h2.962q.234 0 .395.162t.162.397t-.162.396t-.395.16z"}));export{l as default};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue