{editor && editor.isEditable && (
)}
diff --git a/apps/client/src/features/editor/styles/code.css b/apps/client/src/features/editor/styles/code.css
new file mode 100644
index 00000000..d4d2a2dd
--- /dev/null
+++ b/apps/client/src/features/editor/styles/code.css
@@ -0,0 +1,89 @@
+.ProseMirror {
+ pre {
+ padding: var(--mantine-spacing-sm) var(--mantine-spacing-md);
+ font-family: "JetBrainsMono", var(--mantine-font-family-monospace);
+ border-radius: var(--mantine-radius-default);
+
+ @mixin light {
+ background-color: var(--mantine-color-gray-0);
+ color: var(--mantine-color-gray-9);
+ }
+
+ @mixin dark {
+ background-color: var(--mantine-color-dark-8);
+ color: var(--mantine-color-dark-1);
+ }
+
+ code {
+ color: inherit;
+ padding: 0;
+ background: none;
+ font-size: inherit;
+ }
+
+ /* Code styling */
+ .hljs-comment,
+ .hljs-quote {
+ color: light-dark(
+ var(--mantine-color-gray-5),
+ var(--mantine-color-dark-2)
+ );
+ }
+
+ .hljs-variable,
+ .hljs-template-variable,
+ .hljs-attribute,
+ .hljs-tag,
+ .hljs-name,
+ .hljs-regexp,
+ .hljs-link,
+ .hljs-name,
+ .hljs-selector-id,
+ .hljs-selector-class {
+ color: light-dark(var(--mantine-color-red-7), var(--mantine-color-red-5));
+ }
+
+ .hljs-number,
+ .hljs-meta,
+ .hljs-built_in,
+ .hljs-builtin-name,
+ .hljs-literal,
+ .hljs-type,
+ .hljs-params {
+ color: light-dark(
+ var(--mantine-color-blue-7),
+ var(--mantine-color-cyan-5)
+ );
+ }
+
+ .hljs-string,
+ .hljs-symbol,
+ .hljs-bullet {
+ color: light-dark(var(--mantine-color-red-7), var(--mantine-color-red-5));
+ }
+
+ .hljs-title,
+ .hljs-section {
+ color: light-dark(
+ var(--mantine-color-pink-7),
+ var(--mantine-color-yellow-5)
+ );
+ }
+
+ .hljs-keyword,
+ .hljs-selector-tag {
+ color: light-dark(
+ var(--mantine-color-violet-7),
+ var(--mantine-color-violet-3)
+ );
+ }
+
+ .hljs-emphasis {
+ font-style: italic;
+ }
+
+ .hljs-strong {
+ font-weight: 700;
+ }
+ }
+}
diff --git a/apps/client/src/features/editor/styles/core.css b/apps/client/src/features/editor/styles/core.css
index e7f10f93..6e532626 100644
--- a/apps/client/src/features/editor/styles/core.css
+++ b/apps/client/src/features/editor/styles/core.css
@@ -1,110 +1,133 @@
.ProseMirror {
- background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-7));
- color: light-dark(var(--mantine-color-default-color), var(--mantine-color-dark-0));
- font-size: var(--mantine-font-size-md);
- line-height: var(--mantine-line-height-md);
- font-weight: 400;
- width: 100%;
+ background-color: light-dark(
+ var(--mantine-color-white),
+ var(--mantine-color-dark-7)
+ );
+ color: light-dark(
+ var(--mantine-color-default-color),
+ var(--mantine-color-dark-0)
+ );
+ font-size: var(--mantine-font-size-md);
+ line-height: var(--mantine-line-height-xl);
+ font-weight: 400;
+ width: 100%;
- > * + * {
- margin-top: 0.75em;
+ {
+ margin-top: 0.75em;
+ }
+
+ &:focus {
+ outline: none;
+ }
+
+ ul,
+ ol {
+ padding: 0 1rem;
+ margin-top: 0.25rem;
+ margin-bottom: 0.25rem;
+ }
+
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
+ line-height: 1.1;
+ }
+
+ code {
+ background-color: light-dark(
+ var(--mantine-color-gray-0),
+ var(--mantine-color-dark-8)
+ );
+ color: #616161;
+ }
+
+ a {
+ color: light-dark(#207af1, #587da9);
+ font-weight: bold;
+ text-decoration: none;
+ cursor: pointer;
+ }
+
+ blockquote {
+ padding-left: 25px;
+ padding-right: 25px;
+ border-left: 2px solid var(--mantine-color-gray-6);
+ background-color: light-dark(
+ var(--mantine-color-gray-0),
+ var(--mantine-color-dark-8)
+ );
+ margin: 0;
+ }
+
+ hr {
+ border: none;
+ border-top: 2px solid #ced4da;
+ margin: 2rem 0;
+
+ &:hover {
+ cursor: pointer;
}
+ }
- &:focus {
- outline: none;
+ hr.ProseMirror-selectednode {
+ border-top: 1px solid #68cef8;
+ }
+
+ .ProseMirror-selectednode {
+ outline: 2px solid #70cff8;
+ }
+
+ .node-mathInline {
+ .katex-display {
+ margin: 0;
}
+ }
- ul,
- ol {
- padding: 0 1rem;
- margin-top: .25rem;
- margin-bottom: .25rem;
- }
-
- h1,
- h2,
- h3,
- h4,
- h5,
- h6 {
- line-height: 1.1;
- }
-
- code {
- background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-8));
- color: #616161;
- }
-
- pre {
- padding: var(--mantine-spacing-xs);
- margin: var(--mantine-spacing-md) 0;
- font-family: var(--mantine-font-family-monospace);
- border-radius: var(--mantine-radius-sm);
-
- @mixin light {
- background-color: var(--mantine-color-gray-0);
- color: var(--mantine-color-black);
+ .react-renderer {
+ &.node-callout {
+ padding-top: var(--mantine-spacing-xs);
+ padding-bottom: var(--mantine-spacing-xs);
+ div[style*="white-space: inherit;"] {
+ > :first-child {
+ margin: 0;
}
-
- @mixin dark {
- background-color: var(--mantine-color-dark-8);
- color: var(--mantine-color-white);
- }
-
- code {
- color: inherit;
- padding: 0;
- background: none;
- font-size: inherit;
- }
- }
-
- img {
- max-width: 100%;
- height: auto;
- }
-
- a {
- color: light-dark(#207af1, #587da9);
- font-weight: bold;
- text-decoration: none;
- cursor: pointer;
-
- }
-
- blockquote {
- padding-left: 25px;
- border-left: 2px solid var(--mantine-color-gray-6);
- background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-8));
- margin: 0;
- }
-
- hr {
- border: none;
- border-top: 2px solid #ced4da;
- margin: 2rem 0;
-
- &:hover {
- cursor: pointer;
- }
- }
-
- hr.ProseMirror-selectednode {
- border-top: 1px solid #68CEF8;
- }
-
- .ProseMirror-selectednode {
- outline: 2px solid #70CFF8;
+ }
}
+ }
}
.resize-cursor {
- cursor: ew-resize;
- cursor: col-resize;
+ cursor: ew-resize;
+ cursor: col-resize;
}
.comment-mark {
- background: rgba(255, 215, 0, .14);
- border-bottom: 2px solid rgb(166, 158, 12);
+ background: rgba(255, 215, 0, 0.14);
+ border-bottom: 2px solid rgb(166, 158, 12);
+}
+
+.ProseMirror-icon {
+ display: inline-block;
+ width: 1em;
+ height: 1em;
+ mask-image: var(--svg);
+ mask-repeat: no-repeat;
+ mask-size: 100% 100%;
+ background-color: currentColor;
+
+ & -open {
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M10 3v2H5v14h14v-5h2v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm7.586 2H13V3h8v8h-2V6.414l-7 7L10.586 12z'/%3E%3C/svg%3E");
+ }
+
+ &-right-line {
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M12.172 12L9.343 9.173l1.415-1.414L15 12l-4.242 4.242l-1.415-1.414z'/%3E%3C/svg%3E");
+ }
+}
+
+.actionIconGroup {
+ background: var(--mantine-color-body);
}
diff --git a/apps/client/src/features/editor/styles/details.css b/apps/client/src/features/editor/styles/details.css
new file mode 100644
index 00000000..959a1789
--- /dev/null
+++ b/apps/client/src/features/editor/styles/details.css
@@ -0,0 +1,77 @@
+.ProseMirror {
+ [data-type="details"] {
+ display: flex;
+ padding: 0.5em;
+ border-radius: 4px;
+ border: 1px solid transparent;
+ transition: border 0.3s;
+ width: 100%;
+
+ &:hover {
+ border: 1px solid
+ light-dark(var(--mantine-color-gray-3), var(--mantine-color-gray-7));
+
+ [data-type="detailsSummary"] {}
+ }
+
+ [data-type="detailsButton"] {
+ display: flex;
+ cursor: pointer;
+ border: none;
+ padding: 0;
+ background: transparent;
+
+ .ProseMirror-icon {
+ width: 2em;
+ height: 2em;
+ transform: rotateZ(0deg);
+ transition: transform 0.3s;
+ }
+
+ > div {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 4px;
+
+ &:hover,
+ &.active {
+ color: light-dark(
+ var(--mantine-color-gray-8),
+ var(--mantine-color-gray-0)
+ );
+ background: light-dark(
+ var(--mantine-color-gray-1),
+ var(--mantine-color-gray-8)
+ );
+ }
+ }
+ }
+
+ [data-type="detailsContainer"] {
+ flex: 1;
+ margin-left: 0.2em;
+ overflow-x: hidden;
+ word-break: break-word;
+ overflow-wrap: break-word;
+
+ [data-type="detailsContent"] {
+ display: none;
+ }
+ }
+
+ &[open] {
+ [data-type="detailsButton"] {
+ .ProseMirror-icon {
+ transform: rotateZ(90deg);
+ }
+ }
+
+ [data-type="detailsContainer"] {
+ [data-type="detailsContent"] {
+ display: block;
+ }
+ }
+ }
+ }
+}
diff --git a/apps/client/src/features/editor/styles/drag-handle.css b/apps/client/src/features/editor/styles/drag-handle.css
index 36d234f5..e1d3ae4b 100644
--- a/apps/client/src/features/editor/styles/drag-handle.css
+++ b/apps/client/src/features/editor/styles/drag-handle.css
@@ -1,9 +1,9 @@
-.ProseMirror:not(.dragging) .ProseMirror-selectednode {
+/*.ProseMirror:not(.dragging) .ProseMirror-selectednode {
outline: none !important;
background-color: rgba(150, 170, 220, 0.2);
transition: background-color 0.2s;
box-shadow: none;
-}
+}*/
.drag-handle {
position: fixed;
diff --git a/apps/client/src/features/editor/styles/index.css b/apps/client/src/features/editor/styles/index.css
index 9036b187..d9b0fdb6 100644
--- a/apps/client/src/features/editor/styles/index.css
+++ b/apps/client/src/features/editor/styles/index.css
@@ -1,5 +1,12 @@
-@import './core';
-@import './collaboration';
-@import './task-list';
-@import './placeholder';
-@import './drag-handle';
+@import "./core.css";
+@import "./collaboration.css";
+@import "./task-list.css";
+@import "./placeholder.css";
+@import "./drag-handle.css";
+@import "./details.css";
+@import "./table.css";
+@import "./youtube.css";
+@import "./media.css";
+@import "./code.css";
+
+
diff --git a/apps/client/src/features/editor/styles/media.css b/apps/client/src/features/editor/styles/media.css
new file mode 100644
index 00000000..ef616d74
--- /dev/null
+++ b/apps/client/src/features/editor/styles/media.css
@@ -0,0 +1,13 @@
+.ProseMirror {
+ img {
+ max-width: 100%;
+ height: auto;
+ }
+
+ .node-image, .node-video {
+ &.ProseMirror-selectednode {
+ outline: none;
+ }
+ }
+}
+
diff --git a/apps/client/src/features/editor/styles/table.css b/apps/client/src/features/editor/styles/table.css
new file mode 100644
index 00000000..7564def5
--- /dev/null
+++ b/apps/client/src/features/editor/styles/table.css
@@ -0,0 +1,73 @@
+.tableWrapper {
+ margin-top: 3rem;
+ margin-bottom: 3rem;
+ overflow-x: auto;
+ & table {
+ overflow-x: hidden;
+ }
+}
+
+.ProseMirror {
+ table {
+ border-collapse: collapse;
+ margin: 0;
+ table-layout: fixed;
+ width: 100%;
+
+ td,
+ th {
+ border: 1px solid #ced4da;
+ box-sizing: border-box;
+ min-width: 1em;
+ padding: 3px 5px;
+ position: relative;
+ vertical-align: top;
+
+ &:first-of-type:not(a) {
+ margin-top: 0;
+ }
+
+ p {
+ margin: 0;
+
+ & + p {
+ margin-top: 0.75rem;
+ }
+ }
+ }
+
+ th {
+ background-color: light-dark(
+ var(--mantine-color-gray-1),
+ var(--mantine-color-dark-5)
+ );
+ font-weight: bold;
+ text-align: left;
+ }
+
+ .column-resize-handle {
+ background-color: #adf;
+ bottom: -2px;
+ position: absolute;
+ right: -2px;
+ pointer-events: none;
+ top: 0;
+ width: 4px;
+ }
+
+ .selectedCell:after {
+ background: rgba(200, 200, 255, 0.4);
+ content: "";
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ pointer-events: none;
+ position: absolute;
+ z-index: 2;
+ }
+
+ }
+}
+
+
diff --git a/apps/client/src/features/editor/styles/youtube.css b/apps/client/src/features/editor/styles/youtube.css
new file mode 100644
index 00000000..90cb0e53
--- /dev/null
+++ b/apps/client/src/features/editor/styles/youtube.css
@@ -0,0 +1,21 @@
+.ProseMirror {
+ div[data-youtube-video] {
+ cursor: move;
+
+ iframe {
+ display: block;
+ outline: 0px solid transparent;
+ border-radius: var(--mantine-radius-md);
+ width: 100%;
+ }
+
+ &.ProseMirror-selectednode iframe {
+ outline: 1px solid var(--mantine-color-blue-6);
+ transition: outline 0.15s;
+ }
+
+ &.ProseMirror-selectednode {
+ background-color: transparent;
+ }
+ }
+}
diff --git a/apps/client/src/features/page/services/page-service.ts b/apps/client/src/features/page/services/page-service.ts
index 0a3a3d31..6a804434 100644
--- a/apps/client/src/features/page/services/page-service.ts
+++ b/apps/client/src/features/page/services/page-service.ts
@@ -5,7 +5,7 @@ import {
IPageInput,
SidebarPagesParams,
} from "@/features/page/types/page.types";
-import { IPagination } from "@/lib/types.ts";
+import { IAttachment, IPagination } from "@/lib/types.ts";
export async function createPage(data: Partial
): Promise {
const req = await api.post("/pages/create", data);
@@ -52,3 +52,19 @@ export async function getRecentChanges(
const req = await api.post("/pages/recent", { spaceId });
return req.data;
}
+
+export async function uploadFile(file: File, pageId: string) {
+ const formData = new FormData();
+ formData.append("pageId", pageId);
+ formData.append("file", file);
+
+ // should be file endpoint
+ const req = await api.post("/files/upload", formData, {
+ headers: {
+ "Content-Type": "multipart/form-data",
+ },
+ });
+ // console.log("req", req);
+
+ return req;
+}
diff --git a/apps/client/src/lib/types.ts b/apps/client/src/lib/types.ts
index bd4a6b43..6613f20f 100644
--- a/apps/client/src/lib/types.ts
+++ b/apps/client/src/lib/types.ts
@@ -32,3 +32,20 @@ export type IPagination = {
items: T[];
meta: IPaginationMeta;
};
+
+export interface IAttachment {
+ id: string;
+ fileName: string;
+ filePath: string;
+ fileSize: number;
+ fileExt: string;
+ mimeType: string;
+ type: string;
+ creatorId: string;
+ pageId: string | null;
+ spaceId: string | null;
+ workspaceId: string;
+ createdAt: string;
+ updatedAt: string;
+ deletedAt: string | null;
+}
diff --git a/apps/client/src/pages/page/page-redirect.tsx b/apps/client/src/pages/page/page-redirect.tsx
index ed5e0078..c7d3f3ec 100644
--- a/apps/client/src/pages/page/page-redirect.tsx
+++ b/apps/client/src/pages/page/page-redirect.tsx
@@ -3,6 +3,7 @@ import { useEffect } from "react";
import { usePageQuery } from "@/features/page/queries/page-query";
import { buildPageUrl } from "@/features/page/page.utils.ts";
import { extractPageSlugId } from "@/lib";
+import { Error404 } from "@/components/ui/error-404.tsx";
export default function PageRedirect() {
const { pageSlug } = useParams();
@@ -20,6 +21,10 @@ export default function PageRedirect() {
}
}, [page]);
+ if (isError) {
+ return ;
+ }
+
if (pageIsLoading) {
return <>>;
}
diff --git a/apps/client/src/pages/page/page.tsx b/apps/client/src/pages/page/page.tsx
index 6276173b..0d478ca1 100644
--- a/apps/client/src/pages/page/page.tsx
+++ b/apps/client/src/pages/page/page.tsx
@@ -42,7 +42,7 @@ export default function Page() {
page && (
- {`${page?.icon || ""} ${page.title || "untitled"}`}
+ {`${page?.icon || ""} ${page?.title || "untitled"}`}
{
const request = ctx.switchToHttp().getRequest();
+ if (!request?.user?.user) {
+ throw new BadRequestException('Invalid User');
+ }
+
return request.user.user;
},
);
diff --git a/apps/server/src/common/decorators/auth-workspace.decorator.ts b/apps/server/src/common/decorators/auth-workspace.decorator.ts
index 51529c2c..1ae6b8dd 100644
--- a/apps/server/src/common/decorators/auth-workspace.decorator.ts
+++ b/apps/server/src/common/decorators/auth-workspace.decorator.ts
@@ -1,8 +1,18 @@
-import { createParamDecorator, ExecutionContext } from '@nestjs/common';
+import {
+ BadRequestException,
+ createParamDecorator,
+ ExecutionContext,
+} from '@nestjs/common';
export const AuthWorkspace = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
- return request.user.workspace;
+ const workspace = request.raw?.workspace ?? request?.user?.workspace;
+
+ if (!workspace) {
+ throw new BadRequestException('Invalid workspace');
+ }
+
+ return workspace;
},
);
diff --git a/apps/server/src/common/middlewares/domain.middleware.ts b/apps/server/src/common/middlewares/domain.middleware.ts
index 4f47e2f5..47ea57df 100644
--- a/apps/server/src/common/middlewares/domain.middleware.ts
+++ b/apps/server/src/common/middlewares/domain.middleware.ts
@@ -22,7 +22,9 @@ export class DomainMiddleware implements NestMiddleware {
return next();
}
+ // TODO: unify
(req as any).workspaceId = workspace.id;
+ (req as any).workspace = workspace;
} else if (this.environmentService.isCloud()) {
const header = req.headers.host;
const subdomain = header.split('.')[0];
@@ -34,6 +36,7 @@ export class DomainMiddleware implements NestMiddleware {
}
(req as any).workspaceId = workspace.id;
+ (req as any).workspace = workspace;
}
next();
diff --git a/apps/server/src/core/attachment/attachment.constants.ts b/apps/server/src/core/attachment/attachment.constants.ts
index c2cf0d99..02010c37 100644
--- a/apps/server/src/core/attachment/attachment.constants.ts
+++ b/apps/server/src/core/attachment/attachment.constants.ts
@@ -5,8 +5,15 @@ export enum AttachmentType {
File = 'file',
}
-export const validImageExtensions = ['.jpg', '.png', '.jpeg'];
+export const validImageExtensions = ['.jpg', '.png', '.jpeg', 'gif'];
export const MAX_AVATAR_SIZE = '5MB';
-export const validFileExtensions = ['.jpg', '.png', '.jpeg', '.pdf'];
+export const InlineFileExtensions = [
+ '.jpg',
+ '.png',
+ '.jpeg',
+ '.pdf',
+ '.mp4',
+ '.mov',
+];
export const MAX_FILE_SIZE = '20MB';
diff --git a/apps/server/src/core/attachment/attachment.controller.ts b/apps/server/src/core/attachment/attachment.controller.ts
index 842bdb2d..b3231597 100644
--- a/apps/server/src/core/attachment/attachment.controller.ts
+++ b/apps/server/src/core/attachment/attachment.controller.ts
@@ -43,8 +43,12 @@ import {
WorkspaceCaslSubject,
} from '../casl/interfaces/workspace-ability.type';
import WorkspaceAbilityFactory from '../casl/abilities/workspace-ability.factory';
+import { PageRepo } from '@docmost/db/repos/page/page.repo';
+import { AttachmentRepo } from '@docmost/db/repos/attachment/attachment.repo';
+import { Public } from '../../common/decorators/public.decorator';
+import { validate as isValidUUID } from 'uuid';
-@Controller('attachments')
+@Controller()
export class AttachmentController {
private readonly logger = new Logger(AttachmentController.name);
@@ -53,11 +57,13 @@ export class AttachmentController {
private readonly storageService: StorageService,
private readonly workspaceAbility: WorkspaceAbilityFactory,
private readonly spaceAbility: SpaceAbilityFactory,
+ private readonly pageRepo: PageRepo,
+ private readonly attachmentRepo: AttachmentRepo,
) {}
@UseGuards(JwtAuthGuard)
@HttpCode(HttpStatus.OK)
- @Post('upload-file')
+ @Post('files/upload')
@UseInterceptors(AttachmentInterceptor)
async uploadFile(
@Req() req: any,
@@ -70,9 +76,10 @@ export class AttachmentController {
let file = null;
try {
file = await req.file({
- limits: { fileSize: maxFileSize, fields: 1, files: 1 },
+ limits: { fileSize: maxFileSize, fields: 2, files: 1 },
});
} catch (err: any) {
+ this.logger.error(err.message);
if (err?.statusCode === 413) {
throw new BadRequestException(
`File too large. Exceeds the ${MAX_FILE_SIZE} limit`,
@@ -81,42 +88,85 @@ export class AttachmentController {
}
if (!file) {
- throw new BadRequestException('Invalid file upload');
+ throw new BadRequestException('Failed to upload file');
}
- const pageId = file.fields?.pageId.value;
+ const pageId = file.fields?.pageId?.value;
if (!pageId) {
throw new BadRequestException('PageId is required');
}
+ const page = await this.pageRepo.findById(pageId);
+
+ if (!page) {
+ throw new NotFoundException('Page not found');
+ }
+
+ const spaceAbility = await this.spaceAbility.createForUser(
+ user,
+ page.spaceId,
+ );
+ if (spaceAbility.cannot(SpaceCaslAction.Manage, SpaceCaslSubject.Page)) {
+ throw new ForbiddenException();
+ }
+
+ const spaceId = page.spaceId;
+
try {
- const fileResponse = await this.attachmentService.uploadFile(
- file,
- pageId,
- user.id,
- workspace.id,
- );
+ const fileResponse = await this.attachmentService.uploadFile({
+ filePromise: file,
+ pageId: pageId,
+ spaceId: spaceId,
+ userId: user.id,
+ workspaceId: workspace.id,
+ });
return res.send(fileResponse);
} catch (err: any) {
+ this.logger.error(err);
throw new BadRequestException('Error processing file upload.');
}
}
- @Get('/:fileId/:fileName')
+ @Public()
+ @UseGuards(JwtAuthGuard)
+ @Get('/files/:fileId/:fileName')
async getFile(
- @Req() req: any,
@Res() res: FastifyReply,
+ //@AuthUser() user: User,
+ @AuthWorkspace() workspace: Workspace,
@Param('fileId') fileId: string,
@Param('fileName') fileName?: string,
) {
- // TODO
+ if (!isValidUUID(fileId)) {
+ throw new NotFoundException('Invalid file id');
+ }
+
+ const attachment = await this.attachmentRepo.findById(fileId);
+ if (attachment.workspaceId !== workspace.id) {
+ throw new NotFoundException();
+ }
+
+ if (!attachment || !attachment.pageId) {
+ throw new NotFoundException('File record not found');
+ }
+
+ try {
+ const fileStream = await this.storageService.read(attachment.filePath);
+ res.headers({
+ 'Content-Type': getMimeType(attachment.filePath),
+ });
+ return res.send(fileStream);
+ } catch (err) {
+ this.logger.error(err);
+ throw new NotFoundException('File not found');
+ }
}
@UseGuards(JwtAuthGuard)
@HttpCode(HttpStatus.OK)
- @Post('upload-image')
+ @Post('attachments/upload-image')
@UseInterceptors(AttachmentInterceptor)
async uploadAvatarOrLogo(
@Req() req: any,
@@ -198,19 +248,13 @@ export class AttachmentController {
}
}
- @Get('/img/:attachmentType/:fileName')
+ @Get('attachments/img/:attachmentType/:fileName')
async getLogoOrAvatar(
- @Req() req: any,
@Res() res: FastifyReply,
+ @AuthWorkspace() workspace: Workspace,
@Param('attachmentType') attachmentType: AttachmentType,
@Param('fileName') fileName?: string,
) {
- const workspaceId = req.raw?.workspaceId;
-
- if (!workspaceId) {
- throw new BadRequestException('Invalid workspace');
- }
-
if (
!validAttachmentTypes.includes(attachmentType) ||
attachmentType === AttachmentType.File
@@ -218,12 +262,12 @@ export class AttachmentController {
throw new BadRequestException('Invalid image attachment type');
}
- const buildFilePath = `${getAttachmentFolderPath(attachmentType, workspaceId)}/${fileName}`;
+ const filePath = `${getAttachmentFolderPath(attachmentType, workspace.id)}/${fileName}`;
try {
- const fileStream = await this.storageService.read(buildFilePath);
+ const fileStream = await this.storageService.read(filePath);
res.headers({
- 'Content-Type': getMimeType(buildFilePath),
+ 'Content-Type': getMimeType(filePath),
});
return res.send(fileStream);
} catch (err) {
diff --git a/apps/server/src/core/attachment/attachment.utils.ts b/apps/server/src/core/attachment/attachment.utils.ts
index 71123db1..e2b34b13 100644
--- a/apps/server/src/core/attachment/attachment.utils.ts
+++ b/apps/server/src/core/attachment/attachment.utils.ts
@@ -26,7 +26,7 @@ export async function prepareFile(
const buffer = await file.toBuffer();
const sanitizedFilename = sanitize(file.filename).replace(/ /g, '_');
- const fileName = `${rand}_${sanitizedFilename}`;
+ const fileName = sanitizedFilename.slice(0, 255);
const fileSize = buffer.length;
const fileExtension = path.extname(file.filename).toLowerCase();
diff --git a/apps/server/src/core/attachment/services/attachment.service.ts b/apps/server/src/core/attachment/services/attachment.service.ts
index 19824eed..b71eb593 100644
--- a/apps/server/src/core/attachment/services/attachment.service.ts
+++ b/apps/server/src/core/attachment/services/attachment.service.ts
@@ -9,11 +9,7 @@ import {
} from '../attachment.utils';
import { v4 as uuid4 } from 'uuid';
import { AttachmentRepo } from '@docmost/db/repos/attachment/attachment.repo';
-import {
- AttachmentType,
- validFileExtensions,
- validImageExtensions,
-} from '../attachment.constants';
+import { AttachmentType, validImageExtensions } from '../attachment.constants';
import { KyselyDB, KyselyTransaction } from '@docmost/db/types/kysely.types';
import { Attachment } from '@docmost/db/types/entity.types';
import { InjectKysely } from 'nestjs-kysely';
@@ -34,31 +30,36 @@ export class AttachmentService {
@InjectKysely() private readonly db: KyselyDB,
) {}
- async uploadFile(
- filePromise: Promise,
- pageId: string,
- userId: string,
- workspaceId: string,
- ) {
+ async uploadFile(opts: {
+ filePromise: Promise;
+ pageId: string;
+ userId: string;
+ spaceId: string;
+ workspaceId: string;
+ }) {
+ const { filePromise, pageId, spaceId, userId, workspaceId } = opts;
const preparedFile: PreparedFile = await prepareFile(filePromise);
- validateFileType(preparedFile.fileExtension, validFileExtensions);
- const filePath = `${getAttachmentFolderPath(AttachmentType.File, workspaceId)}/${preparedFile.fileName}`;
+ const attachmentId = uuid4();
+ const filePath = `${getAttachmentFolderPath(AttachmentType.File, workspaceId)}/${attachmentId}/${preparedFile.fileName}`;
await this.uploadToDrive(filePath, preparedFile.buffer);
let attachment: Attachment = null;
try {
attachment = await this.saveAttachment({
+ attachmentId,
preparedFile,
filePath,
type: AttachmentType.File,
userId,
+ spaceId,
workspaceId,
pageId,
});
} catch (err) {
// delete uploaded file on error
+ console.error(err);
}
return attachment;
@@ -175,6 +176,7 @@ export class AttachmentService {
}
async saveAttachment(opts: {
+ attachmentId?: string;
preparedFile: PreparedFile;
filePath: string;
type: AttachmentType;
@@ -185,6 +187,7 @@ export class AttachmentService {
trx?: KyselyTransaction;
}): Promise {
const {
+ attachmentId,
preparedFile,
filePath,
type,
@@ -196,6 +199,7 @@ export class AttachmentService {
} = opts;
return this.attachmentRepo.insertAttachment(
{
+ id: attachmentId,
type: type,
filePath: filePath,
fileName: preparedFile.fileName,
diff --git a/package.json b/package.json
index a1666128..e96a04c2 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
"start": "pnpm --filter ./apps/server run start:prod",
"server:build": "nx run server:build",
"client:build": "nx run client:build",
- "editor-ext:editor-ext": "nx run editor-ext:build",
+ "editor-ext:build": "nx run @docmost/editor-ext:build",
"client:dev": "nx run client:dev",
"server:dev": "nx run server:start:dev",
"server:start": "nx run server:start:prod",
@@ -29,6 +29,7 @@
"@tiptap/extension-heading": "^2.4.0",
"@tiptap/extension-highlight": "^2.4.0",
"@tiptap/extension-history": "^2.4.0",
+ "@tiptap/extension-image": "^2.4.0",
"@tiptap/extension-link": "^2.4.0",
"@tiptap/extension-list-item": "^2.4.0",
"@tiptap/extension-list-keymap": "^2.4.0",
@@ -36,6 +37,10 @@
"@tiptap/extension-placeholder": "^2.4.0",
"@tiptap/extension-subscript": "^2.4.0",
"@tiptap/extension-superscript": "^2.4.0",
+ "@tiptap/extension-table": "^2.4.0",
+ "@tiptap/extension-table-cell": "^2.4.0",
+ "@tiptap/extension-table-header": "^2.4.0",
+ "@tiptap/extension-table-row": "^2.4.0",
"@tiptap/extension-task-item": "^2.4.0",
"@tiptap/extension-task-list": "^2.4.0",
"@tiptap/extension-text": "^2.4.0",
@@ -43,6 +48,7 @@
"@tiptap/extension-text-style": "^2.4.0",
"@tiptap/extension-typography": "^2.4.0",
"@tiptap/extension-underline": "^2.4.0",
+ "@tiptap/extension-youtube": "^2.4.0",
"@tiptap/html": "^2.4.0",
"@tiptap/pm": "^2.4.0",
"@tiptap/react": "^2.4.0",
@@ -51,7 +57,6 @@
"cross-env": "^7.0.3",
"fractional-indexing-jittered": "^0.9.1",
"ioredis": "^5.4.1",
- "tiptap-extension-global-drag-handle": "^0.1.8",
"y-indexeddb": "^9.0.12",
"yjs": "^13.6.15"
},
diff --git a/packages/editor-ext/package.json b/packages/editor-ext/package.json
index e07727eb..022c4b6a 100644
--- a/packages/editor-ext/package.json
+++ b/packages/editor-ext/package.json
@@ -6,8 +6,8 @@
"build": "tsc --build",
"dev": "tsc --watch"
},
- "dependencies": {},
"main": "dist/index.js",
"module": "./src/index.ts",
- "types": "dist/index.d.ts"
+ "types": "dist/index.d.ts",
+ "dependencies": {}
}
diff --git a/packages/editor-ext/src/index.ts b/packages/editor-ext/src/index.ts
index c2455185..dd043912 100644
--- a/packages/editor-ext/src/index.ts
+++ b/packages/editor-ext/src/index.ts
@@ -1,2 +1,10 @@
-export * from './lib/trailing-node';
-export * from './lib/comment/comment'
+export * from "./lib/trailing-node";
+export * from "./lib/comment/comment";
+export * from "./lib/utils";
+export * from "./lib/math";
+export * from "./lib/details";
+export * from "./lib/table";
+export * from "./lib/image";
+export * from "./lib/video";
+export * from "./lib/callout";
+export * from "./lib/media-utils";
diff --git a/packages/editor-ext/src/lib/callout/callout.ts b/packages/editor-ext/src/lib/callout/callout.ts
new file mode 100644
index 00000000..c756917b
--- /dev/null
+++ b/packages/editor-ext/src/lib/callout/callout.ts
@@ -0,0 +1,201 @@
+import {
+ findParentNode,
+ mergeAttributes,
+ Node,
+ wrappingInputRule,
+} from "@tiptap/core";
+import { TextSelection } from "@tiptap/pm/state";
+import { ReactNodeViewRenderer } from "@tiptap/react";
+import { CalloutType, getValidCalloutType } from "./utils";
+
+export interface CalloutOptions {
+ HTMLAttributes: Record;
+ view: any;
+}
+
+export interface CalloutAttributes {
+ /**
+ * The type of callout.
+ */
+ type: CalloutType;
+}
+
+declare module "@tiptap/core" {
+ interface Commands {
+ callout: {
+ setCallout: (attributes?: CalloutAttributes) => ReturnType;
+ unsetCallout: () => ReturnType;
+ toggleCallout: (attributes?: CalloutAttributes) => ReturnType;
+ updateCalloutType: (type: CalloutType) => ReturnType;
+ };
+ }
+}
+/**
+ * Matches a callout to a `:::` as input.
+ */
+export const inputRegex = /^:::([a-z]+)?[\s\n]$/;
+
+export const Callout = Node.create({
+ name: "callout",
+
+ addOptions() {
+ return {
+ HTMLAttributes: {},
+ view: null,
+ };
+ },
+
+ content: "block+",
+ group: "block",
+ defining: true,
+
+ addAttributes() {
+ return {
+ type: {
+ default: "info",
+ parseHTML: (element) => element.getAttribute("data-callout-type"),
+ renderHTML: (attributes) => ({
+ "data-callout-type": attributes.type,
+ }),
+ },
+ };
+ },
+
+ parseHTML() {
+ return [
+ {
+ tag: `div[data-type="${this.name}"]`,
+ },
+ ];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return [
+ "div",
+ mergeAttributes(
+ { "data-type": this.name },
+ this.options.HTMLAttributes,
+ HTMLAttributes,
+ ),
+ 0,
+ ];
+ },
+
+ addCommands() {
+ return {
+ setCallout:
+ (attributes) =>
+ ({ commands }) => {
+ return commands.setNode(this.name, attributes);
+ },
+
+ unsetCallout:
+ () =>
+ ({ commands }) => {
+ return commands.lift(this.name);
+ },
+
+ toggleCallout:
+ (attributes) =>
+ ({ commands }) => {
+ return commands.toggleWrap(this.name, attributes);
+ },
+
+ updateCalloutType:
+ (type: string) =>
+ ({ commands }) =>
+ commands.updateAttributes("callout", {
+ type: getValidCalloutType(type),
+ }),
+ };
+ },
+
+ addNodeView() {
+ return ReactNodeViewRenderer(this.options.view);
+ },
+
+ addKeyboardShortcuts() {
+ return {
+ //"Mod-Shift-c": () => this.editor.commands.toggleCallout(),
+
+ /**
+ * Handle the backspace key when deleting content.
+ * Aims to stop merging callouts when deleting content in between.
+ */
+ Backspace: ({ editor }) => {
+ const { state, view } = editor;
+ const { selection } = state;
+
+ // If the selection is not empty, return false
+ // and let other extension handle the deletion.
+ if (!selection.empty) {
+ return false;
+ }
+
+ const { $from } = selection;
+
+ // If not at the start of current node, no joining will happen
+ if ($from.parentOffset !== 0) {
+ return false;
+ }
+
+ const previousPosition = $from.before($from.depth) - 1;
+
+ // If nothing above to join with
+ if (previousPosition < 1) {
+ return false;
+ }
+
+ const previousPos = state.doc.resolve(previousPosition);
+
+ // If resolving previous position fails, bail out
+ if (!previousPos?.parent) {
+ return false;
+ }
+
+ const previousNode = previousPos.parent;
+ const parentNode = findParentNode(() => true)(selection);
+
+ if (!parentNode) {
+ return false;
+ }
+
+ const { node, pos, depth } = parentNode;
+
+ // If current node is nested
+ if (depth !== 1) {
+ return false;
+ }
+
+ // If previous node is a callout, cut current node's content into it
+ if (node.type !== this.type && previousNode.type === this.type) {
+ const { content, nodeSize } = node;
+ const { tr } = state;
+
+ tr.delete(pos, pos + nodeSize);
+ tr.setSelection(
+ TextSelection.near(tr.doc.resolve(previousPosition - 1)),
+ );
+ tr.insert(previousPosition - 1, content);
+
+ view.dispatch(tr);
+
+ return true;
+ }
+ return false;
+ },
+ };
+ },
+
+ addInputRules() {
+ return [
+ wrappingInputRule({
+ find: inputRegex,
+ type: this.type,
+ getAttributes: (match) => ({
+ type: getValidCalloutType(match[1]),
+ }),
+ }),
+ ];
+ },
+});
diff --git a/packages/editor-ext/src/lib/callout/index.ts b/packages/editor-ext/src/lib/callout/index.ts
new file mode 100644
index 00000000..1dac69ec
--- /dev/null
+++ b/packages/editor-ext/src/lib/callout/index.ts
@@ -0,0 +1,2 @@
+export { Callout } from "./callout";
+export * from "./utils";
diff --git a/packages/editor-ext/src/lib/callout/utils.ts b/packages/editor-ext/src/lib/callout/utils.ts
new file mode 100644
index 00000000..6484aa3b
--- /dev/null
+++ b/packages/editor-ext/src/lib/callout/utils.ts
@@ -0,0 +1,8 @@
+export type CalloutType = "default" | "info" | "success" | "warning" | "danger";
+const validCalloutTypes = ["default", "info", "success", "warning", "danger"];
+
+export function getValidCalloutType(value: string): string {
+ if (value) {
+ return validCalloutTypes.includes(value) ? value : "info";
+ }
+}
diff --git a/packages/editor-ext/src/lib/details/details-content.ts b/packages/editor-ext/src/lib/details/details-content.ts
new file mode 100644
index 00000000..1fb5f76c
--- /dev/null
+++ b/packages/editor-ext/src/lib/details/details-content.ts
@@ -0,0 +1,111 @@
+import {
+ Node,
+ defaultBlockAt,
+ findParentNode,
+ mergeAttributes,
+} from "@tiptap/core";
+import { Selection } from "@tiptap/pm/state";
+
+export interface DetailsContentOptions {
+ HTMLAttributes: Record;
+}
+
+export const DetailsContent = Node.create({
+ name: "detailsContent",
+ group: "block",
+ content: "block*",
+ defining: true,
+ selectable: false,
+ addOptions() {
+ return {
+ HTMLAttributes: {},
+ };
+ },
+
+ parseHTML() {
+ return [
+ {
+ tag: `div[data-type="${this.name}"]`,
+ },
+ ];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return [
+ "div",
+ mergeAttributes(
+ { "data-type": this.name },
+ this.options.HTMLAttributes,
+ HTMLAttributes,
+ ),
+ 0,
+ ];
+ },
+
+ addKeyboardShortcuts() {
+ return {
+ Enter: ({ editor }) => {
+ const view = editor.view;
+ const state = editor.state;
+ const selection = state.selection;
+
+ const findNode = findParentNode((node) => node.type.name === this.name)(
+ selection,
+ );
+ if (!selection.empty || !findNode || !findNode.node.childCount) {
+ return false;
+ }
+
+ const childCount = findNode.node.childCount;
+ if (!(childCount === selection.$from.index(findNode.depth) + 1)) {
+ return false;
+ }
+
+ const fillNode =
+ findNode.node.type.contentMatch.defaultType?.createAndFill();
+ if (!fillNode) {
+ return false;
+ }
+
+ const lastNode = findNode.node.child(childCount - 1);
+ if (!lastNode.eq(fillNode)) {
+ return false;
+ }
+
+ const rootNode = selection.$from.node(-3);
+ if (!rootNode) {
+ return false;
+ }
+
+ const indexAfter = selection.$from.indexAfter(-3);
+ const nodeType = defaultBlockAt(rootNode.contentMatchAt(indexAfter));
+ if (
+ !nodeType ||
+ !rootNode.canReplaceWith(indexAfter, indexAfter, nodeType)
+ ) {
+ return false;
+ }
+
+ const defaultNode = nodeType.createAndFill();
+ if (!defaultNode) {
+ return false;
+ }
+
+ const tr = state.tr;
+ const after = selection.$from.after(-2);
+ tr.replaceWith(after, after, defaultNode);
+ tr.setSelection(Selection.near(tr.doc.resolve(after), 1));
+
+ const from = state.doc
+ .resolve(findNode.pos + 1)
+ .posAtIndex(childCount - 1, findNode.depth);
+ const to = from + lastNode.nodeSize;
+ tr.delete(from, to);
+ tr.scrollIntoView();
+ view.dispatch(tr);
+
+ return true;
+ },
+ };
+ },
+});
diff --git a/packages/editor-ext/src/lib/details/details-summary.ts b/packages/editor-ext/src/lib/details/details-summary.ts
new file mode 100644
index 00000000..74f180df
--- /dev/null
+++ b/packages/editor-ext/src/lib/details/details-summary.ts
@@ -0,0 +1,96 @@
+import { Node, defaultBlockAt, mergeAttributes } from "@tiptap/core";
+import { Selection } from "@tiptap/pm/state";
+
+export interface DetailsSummaryOptions {
+ HTMLAttributes: Record;
+}
+
+export const DetailsSummary = Node.create({
+ name: "detailsSummary",
+ group: "block",
+ content: "inline*",
+ defining: true,
+ isolating: true,
+ selectable: false,
+ addOptions() {
+ return {
+ HTMLAttributes: {},
+ };
+ },
+ parseHTML() {
+ return [
+ {
+ tag: "summary",
+ },
+ ];
+ },
+ renderHTML({ HTMLAttributes }) {
+ return [
+ "summary",
+ mergeAttributes(
+ { "data-type": this.name },
+ this.options.HTMLAttributes,
+ HTMLAttributes,
+ ),
+ 0,
+ ];
+ },
+ addKeyboardShortcuts() {
+ return {
+ Backspace: ({ editor }) => {
+ const state = editor.state;
+ const selection = state.selection;
+ if (selection.$anchor.parent.type.name !== this.name) {
+ return false;
+ }
+ if (selection.$anchor.parentOffset !== 0) {
+ return false;
+ }
+ return editor.chain().unsetDetails().focus().run();
+ },
+ Enter: ({ editor }) => {
+ const view = editor.view;
+ const state = editor.state;
+
+ const head = state.selection.$head;
+ if (head.parent.type.name !== this.name) {
+ return false;
+ }
+
+ const hasOffset =
+ // @ts-ignore
+ view.domAtPos(head.after() + 1).node.offsetParent !== null;
+ const findNode = hasOffset
+ ? state.doc.nodeAt(head.after())
+ : head.node(-2);
+ if (!findNode) {
+ return false;
+ }
+
+ const indexAfter = hasOffset ? 0 : head.indexAfter(-1);
+ const nodeType = defaultBlockAt(findNode.contentMatchAt(indexAfter));
+ if (
+ !nodeType ||
+ !findNode.canReplaceWith(indexAfter, indexAfter, nodeType)
+ ) {
+ return false;
+ }
+
+ const defaultNode = nodeType.createAndFill();
+ if (!defaultNode) {
+ return false;
+ }
+
+ const tr = state.tr;
+ const after = hasOffset ? head.after() + 1 : head.after(-1);
+ tr.replaceWith(after, after, defaultNode);
+ tr.setSelection(Selection.near(tr.doc.resolve(after), 1));
+
+ tr.scrollIntoView();
+ view.dispatch(tr);
+
+ return true;
+ },
+ };
+ },
+});
diff --git a/packages/editor-ext/src/lib/details/details.ts b/packages/editor-ext/src/lib/details/details.ts
new file mode 100644
index 00000000..4842fbac
--- /dev/null
+++ b/packages/editor-ext/src/lib/details/details.ts
@@ -0,0 +1,236 @@
+import {
+ Node,
+ findChildren,
+ findParentNode,
+ mergeAttributes,
+ wrappingInputRule,
+} from "@tiptap/core";
+import { icon, setAttributes } from "../utils";
+
+declare module "@tiptap/core" {
+ interface Commands {
+ details: {
+ setDetails: () => ReturnType;
+ unsetDetails: () => ReturnType;
+ toggleDetails: () => ReturnType;
+ };
+ }
+}
+
+export interface DetailsOptions {
+ HTMLAttributes: Record;
+}
+
+export const Details = Node.create({
+ name: "details",
+ group: "block",
+ content: "detailsSummary detailsContent",
+ defining: true,
+ isolating: true,
+ allowGapCursor: false,
+ addOptions() {
+ return {
+ HTMLAttributes: {},
+ };
+ },
+
+ addAttributes() {
+ return {
+ open: {
+ default: false,
+ parseHTML: (e) => e.getAttribute("open"),
+ renderHTML: (a) => (a.open ? { open: "" } : {}),
+ },
+ };
+ },
+
+ parseHTML() {
+ return [
+ {
+ tag: "details",
+ },
+ ];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return [
+ "details",
+ mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
+ 0,
+ ];
+ },
+
+ addNodeView() {
+ return ({ node, editor, getPos }) => {
+ const dom = document.createElement("div");
+ const btn = document.createElement("button");
+ const ico = document.createElement("div");
+ const div = document.createElement("div");
+
+ for (const [key, value] of Object.entries(
+ mergeAttributes(this.options.HTMLAttributes),
+ )) {
+ if (value !== undefined && value !== null) {
+ dom.setAttribute(key, value);
+ }
+ }
+
+ dom.setAttribute("data-type", this.name);
+ btn.setAttribute("data-type", `${this.name}Button`);
+ div.setAttribute("data-type", `${this.name}Container`);
+ if (node.attrs.open) {
+ dom.setAttribute("open", "true");
+ } else {
+ dom.removeAttribute("open");
+ }
+
+ ico.innerHTML = icon("right-line");
+ btn.addEventListener("click", () => {
+ const open = !dom.hasAttribute("open");
+
+ if (!editor.isEditable) {
+ // In readonly mode, toggle the 'open' attribute without updating the document state.
+ if (open) {
+ dom.setAttribute("open", "true");
+ } else {
+ dom.removeAttribute("open");
+ }
+ return;
+ }
+
+ setAttributes(editor, getPos, { ...node.attrs, open });
+ });
+
+ btn.append(ico);
+ dom.append(btn);
+ dom.append(div);
+ return {
+ dom,
+ contentDOM: div,
+ update: (updatedNode) => {
+ if (updatedNode.type !== this.type) {
+ return false;
+ }
+ if (updatedNode.attrs.open) {
+ dom.setAttribute("open", "true");
+ } else {
+ dom.removeAttribute("open");
+ }
+ return true;
+ },
+ };
+ };
+ },
+
+ addCommands() {
+ return {
+ setDetails: () => {
+ return ({ state, chain }) => {
+ const range = state.selection.$from.blockRange(state.selection.$to);
+ if (!range) {
+ return false;
+ }
+
+ const slice = state.doc.slice(range.start, range.end);
+ if (
+ !state.schema.nodes.detailsContent.contentMatch.matchFragment(
+ slice.content,
+ )
+ ) {
+ return false;
+ }
+
+ return chain()
+ .insertContentAt(
+ {
+ from: range.start,
+ to: range.end,
+ },
+ {
+ type: this.name,
+ attrs: {
+ open: true,
+ },
+ content: [
+ {
+ type: "detailsSummary",
+ },
+ {
+ type: "detailsContent",
+ content: slice.toJSON()?.content ?? [],
+ },
+ ],
+ },
+ )
+ .setTextSelection(range.start + 2)
+ .run();
+ };
+ },
+
+ unsetDetails: () => {
+ return ({ state, chain }) => {
+ const parent = findParentNode((node) => node.type === this.type)(
+ state.selection,
+ );
+ if (!parent) {
+ return false;
+ }
+
+ const summary = findChildren(
+ parent.node,
+ (node) => node.type.name === "detailsSummary",
+ );
+ const content = findChildren(
+ parent.node,
+ (node) => node.type.name === "detailsContent",
+ );
+ if (!summary.length || !content.length) {
+ return false;
+ }
+
+ const range = {
+ from: parent.pos,
+ to: parent.pos + parent.node.nodeSize,
+ };
+ const defaultType = state.doc.resolve(range.from).parent.type
+ .contentMatch.defaultType;
+ return chain()
+ .insertContentAt(range, [
+ defaultType?.create(null, summary[0].node.content).toJSON(),
+ ...(content[0].node.content.toJSON() ?? []),
+ ])
+ .setTextSelection(range.from + 1)
+ .run();
+ };
+ },
+
+ toggleDetails: () => {
+ return ({ state, chain }) => {
+ const node = findParentNode((node) => node.type === this.type)(
+ state.selection,
+ );
+ if (node) {
+ return chain().unsetDetails().run();
+ } else {
+ return chain().setDetails().run();
+ }
+ };
+ },
+ };
+ },
+
+ addInputRules() {
+ return [
+ wrappingInputRule({
+ find: /^:::details\s$/,
+ type: this.type,
+ }),
+ ];
+ },
+
+ addKeyboardShortcuts() {
+ return {
+ "Mod-Alt-d": () => this.editor.commands.toggleDetails(),
+ };
+ },
+});
diff --git a/packages/editor-ext/src/lib/details/index.ts b/packages/editor-ext/src/lib/details/index.ts
new file mode 100644
index 00000000..de5dbc6d
--- /dev/null
+++ b/packages/editor-ext/src/lib/details/index.ts
@@ -0,0 +1,3 @@
+export { Details } from "./details";
+export { DetailsSummary } from "./details-summary";
+export { DetailsContent } from "./details-content";
diff --git a/packages/editor-ext/src/lib/image/image-upload.ts b/packages/editor-ext/src/lib/image/image-upload.ts
new file mode 100644
index 00000000..fef472af
--- /dev/null
+++ b/packages/editor-ext/src/lib/image/image-upload.ts
@@ -0,0 +1,125 @@
+import { type EditorState, Plugin, PluginKey } from "@tiptap/pm/state";
+import { Decoration, DecorationSet } from "@tiptap/pm/view";
+import { IAttachment } from "client/src/lib/types";
+import { MediaUploadOptions, UploadFn } from "../media-utils";
+
+const uploadKey = new PluginKey("image-upload");
+
+export const ImageUploadPlugin = ({
+ placeHolderClass,
+}: {
+ placeHolderClass: string;
+}) =>
+ new Plugin({
+ key: uploadKey,
+ state: {
+ init() {
+ return DecorationSet.empty;
+ },
+ apply(tr, set) {
+ set = set.map(tr.mapping, tr.doc);
+ // See if the transaction adds or removes any placeholders
+ //@-ts-expect-error - not yet sure what the type I need here
+ const action = tr.getMeta(this);
+ if (action?.add) {
+ const { id, pos, src } = action.add;
+
+ const placeholder = document.createElement("div");
+ placeholder.setAttribute("class", "img-placeholder");
+ const image = document.createElement("img");
+ image.setAttribute("class", placeHolderClass);
+ image.src = src;
+ placeholder.appendChild(image);
+ const deco = Decoration.widget(pos + 1, placeholder, {
+ id,
+ });
+ set = set.add(tr.doc, [deco]);
+ } else if (action?.remove) {
+ set = set.remove(
+ set.find(
+ undefined,
+ undefined,
+ (spec) => spec.id == action.remove.id,
+ ),
+ );
+ }
+ return set;
+ },
+ },
+ props: {
+ decorations(state) {
+ return this.getState(state);
+ },
+ },
+ });
+
+function findPlaceholder(state: EditorState, id: {}) {
+ const decos = uploadKey.getState(state) as DecorationSet;
+ const found = decos.find(undefined, undefined, (spec) => spec.id == id);
+ return found.length ? found[0]?.from : null;
+}
+
+export const handleImageUpload =
+ ({ validateFn, onUpload }: MediaUploadOptions): UploadFn =>
+ async (file, view, pos, pageId) => {
+ // check if the file is an image
+ const validated = validateFn?.(file);
+ // @ts-ignore
+ if (!validated) return;
+ // A fresh object to act as the ID for this upload
+ const id = {};
+
+ // Replace the selection with a placeholder
+ const tr = view.state.tr;
+ if (!tr.selection.empty) tr.deleteSelection();
+
+ const reader = new FileReader();
+ reader.readAsDataURL(file);
+ reader.onload = () => {
+ tr.setMeta(uploadKey, {
+ add: {
+ id,
+ pos,
+ src: reader.result,
+ },
+ });
+ view.dispatch(tr);
+ };
+
+ await onUpload(file, pageId).then(
+ (attachment: IAttachment) => {
+ const { schema } = view.state;
+
+ const pos = findPlaceholder(view.state, id);
+
+ // If the content around the placeholder has been deleted, drop
+ // the image
+ if (pos == null) return;
+
+ // Otherwise, insert it at the placeholder's position, and remove
+ // the placeholder
+
+ if (!attachment) return;
+
+ const node = schema.nodes.image?.create({
+ src: `/files/${attachment.id}/${attachment.fileName}`,
+ attachmentId: attachment.id,
+ title: attachment.fileName,
+ size: attachment.fileSize,
+ });
+ if (!node) return;
+
+ const transaction = view.state.tr
+ .replaceWith(pos, pos, node)
+ .setMeta(uploadKey, { remove: { id } });
+ view.dispatch(transaction);
+ },
+ () => {
+ // Deletes the image placeholder on error
+ const transaction = view.state.tr
+ .delete(pos, pos)
+ .setMeta(uploadKey, { remove: { id } });
+ view.dispatch(transaction);
+ },
+ );
+ };
diff --git a/packages/editor-ext/src/lib/image/image.ts b/packages/editor-ext/src/lib/image/image.ts
new file mode 100644
index 00000000..810ea376
--- /dev/null
+++ b/packages/editor-ext/src/lib/image/image.ts
@@ -0,0 +1,148 @@
+import Image from "@tiptap/extension-image";
+import { ImageOptions as DefaultImageOptions } from "@tiptap/extension-image";
+import { ReactNodeViewRenderer } from "@tiptap/react";
+import { ImageUploadPlugin } from "./image-upload";
+import { mergeAttributes, Range } from "@tiptap/core";
+
+export interface ImageOptions extends DefaultImageOptions {
+ view: any;
+}
+export interface ImageAttributes {
+ src?: string;
+ alt?: string;
+ title?: string;
+ align?: string;
+ attachmentId?: string;
+ size?: number;
+ width?: number;
+}
+
+declare module "@tiptap/core" {
+ interface Commands {
+ imageBlock: {
+ setImage: (attributes: ImageAttributes) => ReturnType;
+ setImageAt: (
+ attributes: ImageAttributes & { pos: number | Range },
+ ) => ReturnType;
+ setImageAlign: (align: "left" | "center" | "right") => ReturnType;
+ setImageWidth: (width: number) => ReturnType;
+ };
+ }
+}
+
+export const TiptapImage = Image.extend({
+ name: "image",
+
+ inline: false,
+ group: "block",
+ isolating: true,
+ atom: true,
+ defining: true,
+
+ addOptions() {
+ return {
+ ...this.parent?.(),
+ view: null,
+ };
+ },
+
+ addAttributes() {
+ return {
+ src: {
+ default: "",
+ parseHTML: (element) => element.getAttribute("src"),
+ renderHTML: (attributes) => ({
+ src: attributes.src,
+ }),
+ },
+ width: {
+ default: "100%",
+ parseHTML: (element) => element.getAttribute("data-width"),
+ renderHTML: (attributes: ImageAttributes) => ({
+ "data-width": attributes.width,
+ }),
+ },
+ align: {
+ default: "center",
+ parseHTML: (element) => element.getAttribute("data-align"),
+ renderHTML: (attributes: ImageAttributes) => ({
+ "data-align": attributes.align,
+ }),
+ },
+ alt: {
+ default: undefined,
+ parseHTML: (element) => element.getAttribute("alt"),
+ renderHTML: (attributes: ImageAttributes) => ({
+ alt: attributes.alt,
+ }),
+ },
+ attachmentId: {
+ default: undefined,
+ parseHTML: (element) => element.getAttribute("data-attachment-id"),
+ renderHTML: (attributes: ImageAttributes) => ({
+ "data-attachment-id": attributes.align,
+ }),
+ },
+ size: {
+ default: null,
+ parseHTML: (element) => element.getAttribute("data-size"),
+ renderHTML: (attributes: ImageAttributes) => ({
+ "data-size": attributes.size,
+ }),
+ },
+ };
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return [
+ "img",
+ mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
+ ];
+ },
+
+ addCommands() {
+ return {
+ setImage:
+ (attrs: ImageAttributes) =>
+ ({ commands }) => {
+ return commands.insertContent({
+ type: "image",
+ attrs: attrs,
+ });
+ },
+
+ setImageAt:
+ (attrs) =>
+ ({ commands }) => {
+ return commands.insertContentAt(attrs.pos, {
+ type: "image",
+ attrs: attrs,
+ });
+ },
+
+ setImageAlign:
+ (align) =>
+ ({ commands }) =>
+ commands.updateAttributes("image", { align }),
+
+ setImageWidth:
+ (width) =>
+ ({ commands }) =>
+ commands.updateAttributes("image", {
+ width: `${Math.max(0, Math.min(100, width))}%`,
+ }),
+ };
+ },
+
+ addNodeView() {
+ return ReactNodeViewRenderer(this.options.view);
+ },
+
+ addProseMirrorPlugins() {
+ return [
+ ImageUploadPlugin({
+ placeHolderClass: "image-upload",
+ }),
+ ];
+ },
+});
diff --git a/packages/editor-ext/src/lib/image/index.ts b/packages/editor-ext/src/lib/image/index.ts
new file mode 100644
index 00000000..fda17edd
--- /dev/null
+++ b/packages/editor-ext/src/lib/image/index.ts
@@ -0,0 +1,2 @@
+export { TiptapImage } from "./image";
+export * from "./image-upload";
diff --git a/packages/editor-ext/src/lib/math/index.ts b/packages/editor-ext/src/lib/math/index.ts
new file mode 100644
index 00000000..1331fdb0
--- /dev/null
+++ b/packages/editor-ext/src/lib/math/index.ts
@@ -0,0 +1,2 @@
+export { MathInline } from "./math-inline";
+export { MathBlock } from "./math-block";
diff --git a/packages/editor-ext/src/lib/math/math-block.ts b/packages/editor-ext/src/lib/math/math-block.ts
new file mode 100644
index 00000000..ce14afb7
--- /dev/null
+++ b/packages/editor-ext/src/lib/math/math-block.ts
@@ -0,0 +1,95 @@
+import { Node, nodeInputRule } from "@tiptap/core";
+import { ReactNodeViewRenderer } from "@tiptap/react";
+
+declare module "@tiptap/core" {
+ interface Commands {
+ mathBlock: {
+ setMathBlock: () => ReturnType;
+ };
+ }
+}
+
+export interface MathBlockOptions {
+ HTMLAttributes: Record;
+ view: any;
+}
+
+export interface MathBlockAttributes {
+ katex: string;
+}
+
+export const inputRegex = /(?:^|\s)((?:\$\$\$)((?:[^$]+))(?:\$\$\$))$/;
+
+export const MathBlock = Node.create({
+ name: "mathBlock",
+ group: "block",
+ atom: true,
+
+ addOptions() {
+ return {
+ HTMLAttributes: {},
+ view: null,
+ };
+ },
+
+ addAttributes() {
+ return {
+ katex: {
+ default: "",
+ parseHTML: (element) => element.innerHTML.split("$")[1],
+ },
+ };
+ },
+
+ parseHTML() {
+ return [
+ {
+ tag: "div",
+ getAttrs: (node: HTMLElement) => {
+ return node.hasAttribute("data-katex") ? {} : false;
+ },
+ },
+ ];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return [
+ "div",
+ {},
+ ["div", { "data-katex": true }, `$${HTMLAttributes.katex}$`],
+ ];
+ },
+
+ addNodeView() {
+ return ReactNodeViewRenderer(this.options.view);
+ },
+
+ renderText({ node }) {
+ return node.attrs.katex;
+ },
+
+ addCommands() {
+ return {
+ setMathBlock:
+ (attributes?: Record) =>
+ ({ commands }) => {
+ return commands.insertContent({
+ type: this.name,
+ attrs: attributes,
+ });
+ },
+ };
+ },
+
+ addInputRules() {
+ return [
+ nodeInputRule({
+ find: inputRegex,
+ type: this.type,
+ getAttributes: (match) => ({
+ katex: match[1].replaceAll("$", ""),
+ }),
+ }),
+ ];
+ },
+});
diff --git a/packages/editor-ext/src/lib/math/math-inline.ts b/packages/editor-ext/src/lib/math/math-inline.ts
new file mode 100644
index 00000000..c4955673
--- /dev/null
+++ b/packages/editor-ext/src/lib/math/math-inline.ts
@@ -0,0 +1,92 @@
+import { Node, nodeInputRule, wrappingInputRule } from "@tiptap/core";
+import { ReactNodeViewRenderer } from "@tiptap/react";
+
+declare module "@tiptap/core" {
+ interface Commands {
+ mathInline: {
+ setMathInline: () => ReturnType;
+ };
+ }
+}
+
+export interface MathInlineOption {
+ HTMLAttributes: Record;
+ view: any;
+}
+
+export const inputRegex = /(?:^|\s)((?:\$\$)((?:[^$]+))(?:\$\$))$/;
+
+export const MathInline = Node.create({
+ name: "mathInline",
+ group: "inline",
+ inline: true,
+ atom: true,
+
+ addOptions() {
+ return {
+ HTMLAttributes: {},
+ view: null,
+ };
+ },
+
+ addAttributes() {
+ return {
+ katex: {
+ default: "",
+ parseHTML: (element) => element.innerHTML.split("$")[1],
+ },
+ };
+ },
+
+ parseHTML() {
+ return [
+ {
+ tag: "span",
+ getAttrs: (node: HTMLElement) => {
+ return node.hasAttribute("data-katex") ? {} : false;
+ },
+ },
+ ];
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return [
+ "div",
+ {},
+ ["span", { "data-katex": true }, `$${HTMLAttributes.katex}$`],
+ ];
+ },
+
+ renderText({ node }) {
+ return node.attrs.katex;
+ },
+
+ addNodeView() {
+ return ReactNodeViewRenderer(this.options.view);
+ },
+
+ addCommands() {
+ return {
+ setMathInline:
+ (attributes?: Record) =>
+ ({ commands }) => {
+ return commands.insertContent({
+ type: this.name,
+ attrs: attributes,
+ });
+ },
+ };
+ },
+
+ addInputRules() {
+ return [
+ nodeInputRule({
+ find: inputRegex,
+ type: this.type,
+ getAttributes: (match) => ({
+ katex: match[1].replaceAll("$", ""),
+ }),
+ }),
+ ];
+ },
+});
diff --git a/packages/editor-ext/src/lib/media-utils.ts b/packages/editor-ext/src/lib/media-utils.ts
new file mode 100644
index 00000000..039dd406
--- /dev/null
+++ b/packages/editor-ext/src/lib/media-utils.ts
@@ -0,0 +1,51 @@
+import type { EditorView } from "@tiptap/pm/view";
+
+export type UploadFn = (
+ file: File,
+ view: EditorView,
+ pos: number,
+ pageId: string,
+) => void;
+
+export const handleMediaPaste = (
+ view: EditorView,
+ event: ClipboardEvent,
+ uploadFn: UploadFn,
+ pageId: string,
+) => {
+ if (event.clipboardData?.files.length) {
+ event.preventDefault();
+ const [file] = Array.from(event.clipboardData.files);
+ const pos = view.state.selection.from;
+
+ if (file) uploadFn(file, view, pos, pageId);
+ return true;
+ }
+ return false;
+};
+
+export const handleMediaDrop = (
+ view: EditorView,
+ event: DragEvent,
+ moved: boolean,
+ uploadFn: UploadFn,
+ pageId: string,
+) => {
+ if (!moved && event.dataTransfer?.files.length) {
+ event.preventDefault();
+ const [file] = Array.from(event.dataTransfer.files);
+ const coordinates = view.posAtCoords({
+ left: event.clientX,
+ top: event.clientY,
+ });
+ // here we deduct 1 from the pos or else the image will create an extra node
+ if (file) uploadFn(file, view, coordinates?.pos ?? 0 - 1, pageId);
+ return true;
+ }
+ return false;
+};
+
+export interface MediaUploadOptions {
+ validateFn?: (file: File) => void;
+ onUpload: (file: File, pageId: string) => Promise;
+}
diff --git a/packages/editor-ext/src/lib/table/cell.ts b/packages/editor-ext/src/lib/table/cell.ts
new file mode 100644
index 00000000..17ab1e29
--- /dev/null
+++ b/packages/editor-ext/src/lib/table/cell.ts
@@ -0,0 +1,6 @@
+import { TableCell as TiptapTableCell } from "@tiptap/extension-table-cell";
+
+export const TableCell = TiptapTableCell.extend({
+ name: "tableCell",
+ content: "paragraph+",
+});
diff --git a/packages/editor-ext/src/lib/table/header.ts b/packages/editor-ext/src/lib/table/header.ts
new file mode 100644
index 00000000..a37c4cbb
--- /dev/null
+++ b/packages/editor-ext/src/lib/table/header.ts
@@ -0,0 +1,3 @@
+import TiptapTableHeader from "@tiptap/extension-table-header";
+
+export const TableHeader = TiptapTableHeader.configure();
diff --git a/packages/editor-ext/src/lib/table/index.ts b/packages/editor-ext/src/lib/table/index.ts
new file mode 100644
index 00000000..2917d704
--- /dev/null
+++ b/packages/editor-ext/src/lib/table/index.ts
@@ -0,0 +1,4 @@
+export * from "./table-extension";
+export * from "./header";
+export * from "./row";
+export * from "./cell";
diff --git a/packages/editor-ext/src/lib/table/row.ts b/packages/editor-ext/src/lib/table/row.ts
new file mode 100644
index 00000000..3aa67dcd
--- /dev/null
+++ b/packages/editor-ext/src/lib/table/row.ts
@@ -0,0 +1,6 @@
+import TiptapTableRow from "@tiptap/extension-table-row";
+
+export const TableRow = TiptapTableRow.extend({
+ allowGapCursor: false,
+ content: "(tableCell | tableHeader)*",
+});
diff --git a/packages/editor-ext/src/lib/table/table-extension.ts b/packages/editor-ext/src/lib/table/table-extension.ts
new file mode 100644
index 00000000..217952b5
--- /dev/null
+++ b/packages/editor-ext/src/lib/table/table-extension.ts
@@ -0,0 +1,7 @@
+import TiptapTable from "@tiptap/extension-table";
+
+export const Table = TiptapTable.configure({
+ resizable: true,
+ lastColumnResizable: false,
+ allowTableNodeSelection: true,
+});
diff --git a/packages/editor-ext/src/lib/utils.ts b/packages/editor-ext/src/lib/utils.ts
new file mode 100644
index 00000000..e80a1d8e
--- /dev/null
+++ b/packages/editor-ext/src/lib/utils.ts
@@ -0,0 +1,373 @@
+// @ts-nocheck
+import { Editor, findParentNode } from "@tiptap/core";
+import { Selection, Transaction } from "@tiptap/pm/state";
+import { CellSelection, TableMap } from "@tiptap/pm/tables";
+import { Node, ResolvedPos } from "@tiptap/pm/model";
+import { Table } from "./table/table-extension";
+
+export const isRectSelected = (rect: any) => (selection: CellSelection) => {
+ const map = TableMap.get(selection.$anchorCell.node(-1));
+ const start = selection.$anchorCell.start(-1);
+ const cells = map.cellsInRect(rect);
+ const selectedCells = map.cellsInRect(
+ map.rectBetween(
+ selection.$anchorCell.pos - start,
+ selection.$headCell.pos - start,
+ ),
+ );
+
+ for (let i = 0, count = cells.length; i < count; i += 1) {
+ if (selectedCells.indexOf(cells[i]) === -1) {
+ return false;
+ }
+ }
+
+ return true;
+};
+
+export const findTable = (selection: Selection) =>
+ findParentNode(
+ (node) => node.type.spec.tableRole && node.type.spec.tableRole === "table",
+ )(selection);
+
+export const isCellSelection = (selection: any) =>
+ selection instanceof CellSelection;
+
+export const isColumnSelected = (columnIndex: number) => (selection: any) => {
+ if (isCellSelection(selection)) {
+ const map = TableMap.get(selection.$anchorCell.node(-1));
+
+ return isRectSelected({
+ left: columnIndex,
+ right: columnIndex + 1,
+ top: 0,
+ bottom: map.height,
+ })(selection);
+ }
+
+ return false;
+};
+
+export const isRowSelected = (rowIndex: number) => (selection: any) => {
+ if (isCellSelection(selection)) {
+ const map = TableMap.get(selection.$anchorCell.node(-1));
+
+ return isRectSelected({
+ left: 0,
+ right: map.width,
+ top: rowIndex,
+ bottom: rowIndex + 1,
+ })(selection);
+ }
+
+ return false;
+};
+
+export const isTableSelected = (selection: any) => {
+ if (isCellSelection(selection)) {
+ const map = TableMap.get(selection.$anchorCell.node(-1));
+
+ return isRectSelected({
+ left: 0,
+ right: map.width,
+ top: 0,
+ bottom: map.height,
+ })(selection);
+ }
+
+ return false;
+};
+
+export const getCellsInColumn =
+ (columnIndex: number | number[]) => (selection: Selection) => {
+ const table = findTable(selection);
+ if (table) {
+ const map = TableMap.get(table.node);
+ const indexes = Array.isArray(columnIndex)
+ ? columnIndex
+ : Array.from([columnIndex]);
+
+ return indexes.reduce(
+ (acc, index) => {
+ if (index >= 0 && index <= map.width - 1) {
+ const cells = map.cellsInRect({
+ left: index,
+ right: index + 1,
+ top: 0,
+ bottom: map.height,
+ });
+
+ return acc.concat(
+ cells.map((nodePos) => {
+ const node = table.node.nodeAt(nodePos);
+ const pos = nodePos + table.start;
+
+ return { pos, start: pos + 1, node };
+ }),
+ );
+ }
+
+ return acc;
+ },
+ [] as { pos: number; start: number; node: Node | null | undefined }[],
+ );
+ }
+ return null;
+ };
+
+export const getCellsInRow =
+ (rowIndex: number | number[]) => (selection: Selection) => {
+ const table = findTable(selection);
+
+ if (table) {
+ const map = TableMap.get(table.node);
+ const indexes = Array.isArray(rowIndex)
+ ? rowIndex
+ : Array.from([rowIndex]);
+
+ return indexes.reduce(
+ (acc, index) => {
+ if (index >= 0 && index <= map.height - 1) {
+ const cells = map.cellsInRect({
+ left: 0,
+ right: map.width,
+ top: index,
+ bottom: index + 1,
+ });
+
+ return acc.concat(
+ cells.map((nodePos) => {
+ const node = table.node.nodeAt(nodePos);
+ const pos = nodePos + table.start;
+ return { pos, start: pos + 1, node };
+ }),
+ );
+ }
+
+ return acc;
+ },
+ [] as { pos: number; start: number; node: Node | null | undefined }[],
+ );
+ }
+
+ return null;
+ };
+
+export const getCellsInTable = (selection: Selection) => {
+ const table = findTable(selection);
+
+ if (table) {
+ const map = TableMap.get(table.node);
+ const cells = map.cellsInRect({
+ left: 0,
+ right: map.width,
+ top: 0,
+ bottom: map.height,
+ });
+
+ return cells.map((nodePos) => {
+ const node = table.node.nodeAt(nodePos);
+ const pos = nodePos + table.start;
+
+ return { pos, start: pos + 1, node };
+ });
+ }
+
+ return null;
+};
+
+export const findParentNodeClosestToPos = (
+ $pos: ResolvedPos,
+ predicate: (node: Node) => boolean,
+) => {
+ for (let i = $pos.depth; i > 0; i -= 1) {
+ const node = $pos.node(i);
+
+ if (predicate(node)) {
+ return {
+ pos: i > 0 ? $pos.before(i) : 0,
+ start: $pos.start(i),
+ depth: i,
+ node,
+ };
+ }
+ }
+
+ return null;
+};
+
+export const findCellClosestToPos = ($pos: ResolvedPos) => {
+ const predicate = (node: Node) =>
+ node.type.spec.tableRole && /cell/i.test(node.type.spec.tableRole);
+
+ return findParentNodeClosestToPos($pos, predicate);
+};
+
+const select =
+ (type: "row" | "column") => (index: number) => (tr: Transaction) => {
+ const table = findTable(tr.selection);
+ const isRowSelection = type === "row";
+
+ if (table) {
+ const map = TableMap.get(table.node);
+
+ // Check if the index is valid
+ if (index >= 0 && index < (isRowSelection ? map.height : map.width)) {
+ const left = isRowSelection ? 0 : index;
+ const top = isRowSelection ? index : 0;
+ const right = isRowSelection ? map.width : index + 1;
+ const bottom = isRowSelection ? index + 1 : map.height;
+
+ const cellsInFirstRow = map.cellsInRect({
+ left,
+ top,
+ right: isRowSelection ? right : left + 1,
+ bottom: isRowSelection ? top + 1 : bottom,
+ });
+
+ const cellsInLastRow =
+ bottom - top === 1
+ ? cellsInFirstRow
+ : map.cellsInRect({
+ left: isRowSelection ? left : right - 1,
+ top: isRowSelection ? bottom - 1 : top,
+ right,
+ bottom,
+ });
+
+ const head = table.start + cellsInFirstRow[0];
+ const anchor = table.start + cellsInLastRow[cellsInLastRow.length - 1];
+ const $head = tr.doc.resolve(head);
+ const $anchor = tr.doc.resolve(anchor);
+
+ // @ts-ignore
+ return tr.setSelection(new CellSelection($anchor, $head));
+ }
+ }
+ return tr;
+ };
+
+export const selectColumn = select("column");
+
+export const selectRow = select("row");
+
+export const selectTable = (tr: Transaction) => {
+ const table = findTable(tr.selection);
+
+ if (table) {
+ const { map } = TableMap.get(table.node);
+
+ if (map && map.length) {
+ const head = table.start + map[0];
+ const anchor = table.start + map[map.length - 1];
+ const $head = tr.doc.resolve(head);
+ const $anchor = tr.doc.resolve(anchor);
+
+ // @ts-ignore
+ return tr.setSelection(new CellSelection($anchor, $head));
+ }
+ }
+
+ return tr;
+};
+
+export const isColumnGripSelected = ({
+ editor,
+ view,
+ state,
+ from,
+}: {
+ editor: Editor;
+ view: EditorView;
+ state: EditorState;
+ from: number;
+}) => {
+ const domAtPos = view.domAtPos(from).node as HTMLElement;
+ const nodeDOM = view.nodeDOM(from) as HTMLElement;
+ const node = nodeDOM || domAtPos;
+
+ if (
+ !editor.isActive(Table.name) ||
+ !node ||
+ isTableSelected(state.selection)
+ ) {
+ return false;
+ }
+
+ let container = node;
+
+ while (container && !["TD", "TH"].includes(container.tagName)) {
+ container = container.parentElement!;
+ }
+
+ const gripColumn =
+ container &&
+ container.querySelector &&
+ container.querySelector("a.grip-column.selected");
+
+ return !!gripColumn;
+};
+
+export const isRowGripSelected = ({
+ editor,
+ view,
+ state,
+ from,
+}: {
+ editor: Editor;
+ view: EditorView;
+ state: EditorState;
+ from: number;
+}) => {
+ const domAtPos = view.domAtPos(from).node as HTMLElement;
+ const nodeDOM = view.nodeDOM(from) as HTMLElement;
+ const node = nodeDOM || domAtPos;
+
+ if (
+ !editor.isActive(Table.name) ||
+ !node ||
+ isTableSelected(state.selection)
+ ) {
+ return false;
+ }
+
+ let container = node;
+
+ while (container && !["TD", "TH"].includes(container.tagName)) {
+ container = container.parentElement!;
+ }
+
+ const gripRow =
+ container &&
+ container.querySelector &&
+ container.querySelector("a.grip-row.selected");
+
+ return !!gripRow;
+};
+
+export function parseAttributes(value: string) {
+ const regex = /([^=\s]+)="?([^"]+)"?/g;
+ const attrs: Record = {};
+ let match: RegExpExecArray | null;
+ // eslint-disable-next-line no-cond-assign
+ while ((match = regex.exec(value))) {
+ attrs[match[1]] = match[2];
+ }
+ return attrs;
+}
+
+export function setAttributes(
+ editor: Editor,
+ getPos: (() => number) | boolean,
+ attrs: Record,
+) {
+ if (editor.isEditable && typeof getPos === "function") {
+ editor.view.dispatch(
+ editor.view.state.tr.setNodeMarkup(getPos(), undefined, attrs),
+ );
+ }
+}
+
+export function icon(name: string) {
+ return ``;
+}
diff --git a/packages/editor-ext/src/lib/video/index.ts b/packages/editor-ext/src/lib/video/index.ts
new file mode 100644
index 00000000..4aa6075c
--- /dev/null
+++ b/packages/editor-ext/src/lib/video/index.ts
@@ -0,0 +1,2 @@
+export { TiptapVideo } from "./video";
+export * from "./video-upload";
diff --git a/packages/editor-ext/src/lib/video/video-upload.ts b/packages/editor-ext/src/lib/video/video-upload.ts
new file mode 100644
index 00000000..168ce5e2
--- /dev/null
+++ b/packages/editor-ext/src/lib/video/video-upload.ts
@@ -0,0 +1,125 @@
+import { type EditorState, Plugin, PluginKey } from "@tiptap/pm/state";
+import { Decoration, DecorationSet } from "@tiptap/pm/view";
+import { IAttachment } from "client/src/lib/types";
+import { MediaUploadOptions, UploadFn } from "../media-utils";
+
+const uploadKey = new PluginKey("video-upload");
+
+export const VideoUploadPlugin = ({
+ placeHolderClass,
+}: {
+ placeHolderClass: string;
+}) =>
+ new Plugin({
+ key: uploadKey,
+ state: {
+ init() {
+ return DecorationSet.empty;
+ },
+ apply(tr, set) {
+ set = set.map(tr.mapping, tr.doc);
+ // See if the transaction adds or removes any placeholders
+ //@-ts-expect-error - not yet sure what the type I need here
+ const action = tr.getMeta(this);
+ if (action?.add) {
+ const { id, pos, src } = action.add;
+
+ const placeholder = document.createElement("div");
+ placeholder.setAttribute("class", "video-placeholder");
+ const video = document.createElement("video");
+ video.setAttribute("class", placeHolderClass);
+ video.src = src;
+ placeholder.appendChild(video);
+ const deco = Decoration.widget(pos + 1, placeholder, {
+ id,
+ });
+ set = set.add(tr.doc, [deco]);
+ } else if (action?.remove) {
+ set = set.remove(
+ set.find(
+ undefined,
+ undefined,
+ (spec) => spec.id == action.remove.id,
+ ),
+ );
+ }
+ return set;
+ },
+ },
+ props: {
+ decorations(state) {
+ return this.getState(state);
+ },
+ },
+ });
+
+function findPlaceholder(state: EditorState, id: {}) {
+ const decos = uploadKey.getState(state) as DecorationSet;
+ const found = decos.find(undefined, undefined, (spec) => spec.id == id);
+ return found.length ? found[0]?.from : null;
+}
+
+export const handleVideoUpload =
+ ({ validateFn, onUpload }: MediaUploadOptions): UploadFn =>
+ async (file, view, pos, pageId) => {
+ // check if the file is an image
+ const validated = validateFn?.(file);
+ // @ts-ignore
+ if (!validated) return;
+ // A fresh object to act as the ID for this upload
+ const id = {};
+
+ // Replace the selection with a placeholder
+ const tr = view.state.tr;
+ if (!tr.selection.empty) tr.deleteSelection();
+
+ const reader = new FileReader();
+ reader.readAsDataURL(file);
+ reader.onload = () => {
+ tr.setMeta(uploadKey, {
+ add: {
+ id,
+ pos,
+ src: reader.result,
+ },
+ });
+ view.dispatch(tr);
+ };
+
+ await onUpload(file, pageId).then(
+ (attachment: IAttachment) => {
+ const { schema } = view.state;
+
+ const pos = findPlaceholder(view.state, id);
+
+ // If the content around the placeholder has been deleted, drop
+ // the image
+ if (pos == null) return;
+
+ // Otherwise, insert it at the placeholder's position, and remove
+ // the placeholder
+
+ if (!attachment) return;
+
+ const node = schema.nodes.video?.create({
+ src: `/files/${attachment.id}/${attachment.fileName}`,
+ attachmentId: attachment.id,
+ title: attachment.fileName,
+ size: attachment.fileSize,
+ });
+ if (!node) return;
+
+ const transaction = view.state.tr
+ .replaceWith(pos, pos, node)
+ .setMeta(uploadKey, { remove: { id } });
+ view.dispatch(transaction);
+ },
+ () => {
+ // Deletes the image placeholder on error
+ const transaction = view.state.tr
+ .delete(pos, pos)
+ .setMeta(uploadKey, { remove: { id } });
+ view.dispatch(transaction);
+ },
+ );
+ };
diff --git a/packages/editor-ext/src/lib/video/video.ts b/packages/editor-ext/src/lib/video/video.ts
new file mode 100644
index 00000000..2599c45d
--- /dev/null
+++ b/packages/editor-ext/src/lib/video/video.ts
@@ -0,0 +1,146 @@
+import { ReactNodeViewRenderer } from "@tiptap/react";
+import { VideoUploadPlugin } from "./video-upload";
+import { mergeAttributes, Range, Node, nodeInputRule } from "@tiptap/core";
+
+export interface VideoOptions {
+ view: any;
+ HTMLAttributes: Record;
+}
+export interface VideoAttributes {
+ src?: string;
+ title?: string;
+ align?: string;
+ attachmentId?: string;
+ size?: number;
+ width?: number;
+}
+
+declare module "@tiptap/core" {
+ interface Commands {
+ videoBlock: {
+ setVideo: (attributes: VideoAttributes) => ReturnType;
+ setVideoAt: (
+ attributes: VideoAttributes & { pos: number | Range },
+ ) => ReturnType;
+ setVideoAlign: (align: "left" | "center" | "right") => ReturnType;
+ setVideoWidth: (width: number) => ReturnType;
+ };
+ }
+}
+
+const VIDEO_INPUT_REGEX = /!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\)/;
+
+export const TiptapVideo = Node.create({
+ name: "video",
+
+ group: "block",
+ isolating: true,
+ atom: true,
+ defining: true,
+ draggable: true,
+
+ addOptions() {
+ return {
+ view: null,
+ HTMLAttributes: {},
+ };
+ },
+
+ addAttributes() {
+ return {
+ src: {
+ default: "",
+ parseHTML: (element) => element.getAttribute("src"),
+ renderHTML: (attributes) => ({
+ src: attributes.src,
+ }),
+ },
+ attachmentId: {
+ default: undefined,
+ parseHTML: (element) => element.getAttribute("data-attachment-id"),
+ renderHTML: (attributes: VideoAttributes) => ({
+ "data-attachment-id": attributes.align,
+ }),
+ },
+ width: {
+ default: "100%",
+ parseHTML: (element) => element.getAttribute("data-width"),
+ renderHTML: (attributes: VideoAttributes) => ({
+ "data-width": attributes.width,
+ }),
+ },
+ size: {
+ default: null,
+ parseHTML: (element) => element.getAttribute("data-size"),
+ renderHTML: (attributes: VideoAttributes) => ({
+ "data-size": attributes.size,
+ }),
+ },
+ align: {
+ default: "center",
+ parseHTML: (element) => element.getAttribute("data-align"),
+ renderHTML: (attributes: VideoAttributes) => ({
+ "data-align": attributes.align,
+ }),
+ },
+ };
+ },
+
+ renderHTML({ HTMLAttributes }) {
+ return [
+ "video",
+ { controls: "true", ...HTMLAttributes },
+ ["source", HTMLAttributes],
+ ];
+ },
+
+ addCommands() {
+ return {
+ setVideo:
+ (attrs: VideoAttributes) =>
+ ({ commands }) => {
+ return commands.insertContent({
+ type: "video",
+ attrs: attrs,
+ });
+ },
+
+ setVideoAlign:
+ (align) =>
+ ({ commands }) =>
+ commands.updateAttributes("video", { align }),
+
+ setVideoWidth:
+ (width) =>
+ ({ commands }) =>
+ commands.updateAttributes("video", {
+ width: `${Math.max(0, Math.min(100, width))}%`,
+ }),
+ };
+ },
+
+ addNodeView() {
+ return ReactNodeViewRenderer(this.options.view);
+ },
+
+ addInputRules() {
+ return [
+ nodeInputRule({
+ find: VIDEO_INPUT_REGEX,
+ type: this.type,
+ getAttributes: (match) => {
+ const [, , src] = match;
+ return { src };
+ },
+ }),
+ ];
+ },
+
+ addProseMirrorPlugins() {
+ return [
+ VideoUploadPlugin({
+ placeHolderClass: "video-upload",
+ }),
+ ];
+ },
+});
diff --git a/packages/editor-ext/tsconfig.json b/packages/editor-ext/tsconfig.json
index 93b9e97e..efbfcd61 100644
--- a/packages/editor-ext/tsconfig.json
+++ b/packages/editor-ext/tsconfig.json
@@ -7,7 +7,7 @@
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
- "target": "ES2021",
+ "target": "ES2022",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 242f91f8..b126c5a5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -53,6 +53,9 @@ importers:
'@tiptap/extension-history':
specifier: ^2.4.0
version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)
+ '@tiptap/extension-image':
+ specifier: ^2.4.0
+ version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))
'@tiptap/extension-link':
specifier: ^2.4.0
version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)
@@ -74,6 +77,18 @@ importers:
'@tiptap/extension-superscript':
specifier: ^2.4.0
version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))
+ '@tiptap/extension-table':
+ specifier: ^2.4.0
+ version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)
+ '@tiptap/extension-table-cell':
+ specifier: ^2.4.0
+ version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))
+ '@tiptap/extension-table-header':
+ specifier: ^2.4.0
+ version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))
+ '@tiptap/extension-table-row':
+ specifier: ^2.4.0
+ version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))
'@tiptap/extension-task-item':
specifier: ^2.4.0
version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)
@@ -95,6 +110,9 @@ importers:
'@tiptap/extension-underline':
specifier: ^2.4.0
version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))
+ '@tiptap/extension-youtube':
+ specifier: ^2.4.0
+ version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))
'@tiptap/html':
specifier: ^2.4.0
version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)
@@ -119,9 +137,6 @@ importers:
ioredis:
specifier: ^5.4.1
version: 5.4.1
- tiptap-extension-global-drag-handle:
- specifier: ^0.1.8
- version: 0.1.8
y-indexeddb:
specifier: ^9.0.12
version: 9.0.12(yjs@13.6.15)
@@ -131,10 +146,10 @@ importers:
devDependencies:
'@nx/js':
specifier: 19.1.2
- version: 19.1.2(@babel/traverse@7.24.6)(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(nx@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2)))(typescript@5.4.5)
+ version: 19.1.2(@babel/traverse@7.24.6)(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(nx@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11)))(typescript@5.4.5)
nx:
specifier: 19.1.2
- version: 19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2))
+ version: 19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11))
tsx:
specifier: ^4.11.2
version: 4.11.2
@@ -172,11 +187,14 @@ importers:
specifier: ^7.10.1
version: 7.10.1(@mantine/core@7.10.1(@mantine/hooks@7.10.1(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mantine/hooks@7.10.1(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@tabler/icons-react':
- specifier: ^3.5.0
- version: 3.5.0(react@18.3.1)
+ specifier: ^3.6.0
+ version: 3.6.0(react@18.3.1)
'@tanstack/react-query':
specifier: ^5.40.0
version: 5.40.0(react@18.3.1)
+ '@tiptap/extension-code-block-lowlight':
+ specifier: ^2.4.0
+ version: 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/extension-code-block@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)
axios:
specifier: ^1.7.2
version: 1.7.2
@@ -201,6 +219,12 @@ importers:
jwt-decode:
specifier: ^4.0.0
version: 4.0.0
+ katex:
+ specifier: ^0.16.10
+ version: 0.16.10
+ lowlight:
+ specifier: ^3.1.0
+ version: 3.1.0
react:
specifier: ^18.3.1
version: 18.3.1
@@ -216,6 +240,9 @@ importers:
react-helmet-async:
specifier: ^2.0.5
version: 2.0.5(react@18.3.1)
+ react-moveable:
+ specifier: ^0.56.0
+ version: 0.56.0
react-router-dom:
specifier: ^6.23.1
version: 6.23.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -238,6 +265,9 @@ importers:
'@types/js-cookie':
specifier: ^3.0.6
version: 3.0.6
+ '@types/katex':
+ specifier: ^0.16.7
+ version: 0.16.7
'@types/node':
specifier: 20.14.0
version: 20.14.0
@@ -258,7 +288,7 @@ importers:
version: 7.11.0(eslint@9.4.0)(typescript@5.4.5)
'@vitejs/plugin-react':
specifier: ^4.3.0
- version: 4.3.0(vite@5.2.12(@types/node@20.14.0)(sugarss@4.0.1(postcss@8.4.38))(terser@5.29.2))
+ version: 4.3.0(vite@5.2.12(@types/node@20.14.0)(less@4.2.0)(sugarss@4.0.1(postcss@8.4.38))(terser@5.29.2))
eslint:
specifier: ^9.4.0
version: 9.4.0
@@ -288,7 +318,7 @@ importers:
version: 5.4.5
vite:
specifier: ^5.2.12
- version: 5.2.12(@types/node@20.14.0)(sugarss@4.0.1(postcss@8.4.38))(terser@5.29.2)
+ version: 5.2.12(@types/node@20.14.0)(less@4.2.0)(sugarss@4.0.1(postcss@8.4.38))(terser@5.29.2)
apps/server:
dependencies:
@@ -433,7 +463,7 @@ importers:
devDependencies:
'@nestjs/cli':
specifier: ^10.3.2
- version: 10.3.2(@swc/core@1.3.101(@swc/helpers@0.5.2))
+ version: 10.3.2(@swc/core@1.5.25(@swc/helpers@0.5.11))
'@nestjs/schematics':
specifier: ^10.1.1
version: 10.1.1(chokidar@3.6.0)(typescript@5.4.5)
@@ -490,10 +520,10 @@ importers:
version: 9.1.0(eslint@9.4.0)
eslint-plugin-prettier:
specifier: ^5.1.3
- version: 5.1.3(@types/eslint@8.56.6)(eslint-config-prettier@9.1.0(eslint@9.4.0))(eslint@9.4.0)(prettier@3.3.0)
+ version: 5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@9.4.0))(eslint@9.4.0)(prettier@3.3.0)
jest:
specifier: ^29.7.0
- version: 29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5))
+ version: 29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5))
kysely-codegen:
specifier: ^0.15.0
version: 0.15.0(kysely@0.27.3)(pg@8.11.5)
@@ -502,7 +532,7 @@ importers:
version: 3.3.0
react-email:
specifier: ^2.1.4
- version: 2.1.4(@swc/helpers@0.5.2)(babel-plugin-macros@2.8.0)(eslint@9.4.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5))
+ version: 2.1.4(@swc/helpers@0.5.11)(babel-plugin-macros@2.8.0)(eslint@9.4.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5))
source-map-support:
specifier: ^0.5.21
version: 0.5.21
@@ -511,13 +541,13 @@ importers:
version: 7.0.0
ts-jest:
specifier: ^29.1.4
- version: 29.1.4(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5)))(typescript@5.4.5)
+ version: 29.1.4(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5)))(typescript@5.4.5)
ts-loader:
specifier: ^9.5.1
- version: 9.5.1(typescript@5.4.5)(webpack@5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11))
+ version: 9.5.1(typescript@5.4.5)(webpack@5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.11))(esbuild@0.19.11))
ts-node:
specifier: ^10.9.2
- version: 10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5)
+ version: 10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5)
tsconfig-paths:
specifier: ^4.2.0
version: 4.2.0
@@ -736,10 +766,6 @@ packages:
resolution: {integrity: sha512-cWgAwmbFYNCFzPwxL705+lWps0F3ZvOckufd2KKoEZUmtpVw9/txUXNrPySUXSmRTSRhoatIMABNfStWR043bQ==}
engines: {node: '>=16.0.0'}
- '@babel/code-frame@7.23.5':
- resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==}
- engines: {node: '>=6.9.0'}
-
'@babel/code-frame@7.24.2':
resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==}
engines: {node: '>=6.9.0'}
@@ -941,10 +967,6 @@ packages:
resolution: {integrity: sha512-V2PI+NqnyFu1i0GyTd/O/cTpxzQCYioSkUIRmgo7gFEHKKCg5w46+r/A6WeUR1+P3TeQ49dspGPNd/E3n9AnnA==}
engines: {node: '>=6.9.0'}
- '@babel/highlight@7.23.4':
- resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==}
- engines: {node: '>=6.9.0'}
-
'@babel/highlight@7.24.2':
resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==}
engines: {node: '>=6.9.0'}
@@ -1504,6 +1526,9 @@ packages:
'@casl/ability': ^3.0.0 || ^4.0.0 || ^5.1.0 || ^6.0.0
react: ^16.0.0 || ^17.0.0 || ^18.0.0
+ '@cfcs/core@0.0.6':
+ resolution: {integrity: sha512-FxfJMwoLB8MEMConeXUCqtMGqxdtePQxRBOiGip9ULcYYam3WfCgoY6xdnMaSkYvRvmosp5iuG+TiPofm65+Pw==}
+
'@colors/colors@1.5.0':
resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
engines: {node: '>=0.1.90'}
@@ -1517,6 +1542,21 @@ packages:
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'}
+ '@daybrush/utils@1.13.0':
+ resolution: {integrity: sha512-ALK12C6SQNNHw1enXK+UO8bdyQ+jaWNQ1Af7Z3FNxeAwjYhQT7do+TRE4RASAJ3ObaS2+TJ7TXR3oz2Gzbw0PQ==}
+
+ '@egjs/agent@2.4.3':
+ resolution: {integrity: sha512-XvksSENe8wPeFlEVouvrOhKdx8HMniJ3by7sro2uPF3M6QqWwjzVcmvwoPtdjiX8O1lfRoLhQMp1a7NGlVTdIA==}
+
+ '@egjs/children-differ@1.0.1':
+ resolution: {integrity: sha512-DRvyqMf+CPCOzAopQKHtW+X8iN6Hy6SFol+/7zCUiE5y4P/OB8JP8FtU4NxtZwtafvSL4faD5KoQYPj3JHzPFQ==}
+
+ '@egjs/component@3.0.5':
+ resolution: {integrity: sha512-cLcGizTrrUNA2EYE3MBmEDt2tQv1joVP1Q3oDisZ5nw0MZDx2kcgEXM+/kZpfa/PAkFvYVhRUZwytIQWoN3V/w==}
+
+ '@egjs/list-differ@1.0.1':
+ resolution: {integrity: sha512-OTFTDQcWS+1ZREOdCWuk5hCBgYO4OsD30lXcOCyVOAjXMhgL5rBRDnt/otb6Nz8CzU0L/igdcaQBDLWc4t9gvg==}
+
'@emoji-mart/data@1.2.1':
resolution: {integrity: sha512-no2pQMWiBy6gpBEiqGeU77/bFejDqUTRY7KX+0+iur13op3bqUsXdnwoZs6Xb1zbv0gAj5VvS1PWoUUckSr5Dw==}
@@ -3015,6 +3055,15 @@ packages:
cpu: [x64]
os: [win32]
+ '@scena/dragscroll@1.4.0':
+ resolution: {integrity: sha512-3O8daaZD9VXA9CP3dra6xcgt/qrm0mg0xJCwiX6druCteQ9FFsXffkF8PrqxY4Z4VJ58fFKEa0RlKqbsi/XnRA==}
+
+ '@scena/event-emitter@1.0.5':
+ resolution: {integrity: sha512-AzY4OTb0+7ynefmWFQ6hxDdk0CySAq/D4efljfhtRHCOP7MBF9zUfhKG3TJiroVjASqVgkRJFdenS8ArZo6Olg==}
+
+ '@scena/matrix@1.1.1':
+ resolution: {integrity: sha512-JVKBhN0tm2Srl+Yt+Ywqu0oLgLcdemDQlD1OxmN9jaCTwaFPZ7tY8n6dhVgMEaR9qcR7r+kAlMXnSfNyYdE+Vg==}
+
'@selderee/plugin-htmlparser2@0.11.0':
resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==}
@@ -3241,60 +3290,120 @@ packages:
cpu: [arm64]
os: [darwin]
+ '@swc/core-darwin-arm64@1.5.25':
+ resolution: {integrity: sha512-YbD0SBgVJS2DM0vwJTU5m7+wOyCjHPBDMf3nCBJQzFZzOLzK11eRW7SzU2jhJHr9HI9sKcNFfN4lIC2Sj+4inA==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [darwin]
+
'@swc/core-darwin-x64@1.3.101':
resolution: {integrity: sha512-B085j8XOx73Fg15KsHvzYWG262bRweGr3JooO1aW5ec5pYbz5Ew9VS5JKYS03w2UBSxf2maWdbPz2UFAxg0whw==}
engines: {node: '>=10'}
cpu: [x64]
os: [darwin]
+ '@swc/core-darwin-x64@1.5.25':
+ resolution: {integrity: sha512-OhP4TROT6gQuozn+ah0Y4UidSdgDmxwtQq3lgCUIAxJYErJAQ82/Y0kve2UaNmkSGjOHU+/b4siHPrYTkXOk0Q==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [darwin]
+
'@swc/core-linux-arm-gnueabihf@1.3.101':
resolution: {integrity: sha512-9xLKRb6zSzRGPqdz52Hy5GuB1lSjmLqa0lST6MTFads3apmx4Vgs8Y5NuGhx/h2I8QM4jXdLbpqQlifpzTlSSw==}
engines: {node: '>=10'}
cpu: [arm]
os: [linux]
+ '@swc/core-linux-arm-gnueabihf@1.5.25':
+ resolution: {integrity: sha512-tNmUfrAHxN2gvYPyYNnHx2CYlPO7DGAUuK/bZrqawu++djcg+atAV3eI3XYJgmHId7/sYAlDQ9wjkrOLofFjVg==}
+ engines: {node: '>=10'}
+ cpu: [arm]
+ os: [linux]
+
'@swc/core-linux-arm64-gnu@1.3.101':
resolution: {integrity: sha512-oE+r1lo7g/vs96Weh2R5l971dt+ZLuhaUX+n3BfDdPxNHfObXgKMjO7E+QS5RbGjv/AwiPCxQmbdCp/xN5ICJA==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
+ '@swc/core-linux-arm64-gnu@1.5.25':
+ resolution: {integrity: sha512-stzpke+bRaNFM/HrZPRjX0aQZ86S/2DChVCwb8NAV1n5lu9mz1CS750y7WbbtX/KZjk92FsCeRy2qwkvjI0gWw==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [linux]
+
'@swc/core-linux-arm64-musl@1.3.101':
resolution: {integrity: sha512-OGjYG3H4BMOTnJWJyBIovCez6KiHF30zMIu4+lGJTCrxRI2fAjGLml3PEXj8tC3FMcud7U2WUn6TdG0/te2k6g==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
+ '@swc/core-linux-arm64-musl@1.5.25':
+ resolution: {integrity: sha512-UckUfDYedish/bj2V1jgQDGgouLhyRpG7jgF3mp8jHir11V2K6JiTyjFoz99eOiclS3+hNdr4QLJ+ifrQMJNZw==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [linux]
+
'@swc/core-linux-x64-gnu@1.3.101':
resolution: {integrity: sha512-/kBMcoF12PRO/lwa8Z7w4YyiKDcXQEiLvM+S3G9EvkoKYGgkkz4Q6PSNhF5rwg/E3+Hq5/9D2R+6nrkF287ihg==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
+ '@swc/core-linux-x64-gnu@1.5.25':
+ resolution: {integrity: sha512-LwbJEgNT3lXbvz4WFzVNXNvs8DvxpoXjMZk9K9Hig8tmZQJKHC2qZTGomcyK5EFzfj2HBuBXZnAEW8ZT9PcEaA==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [linux]
+
'@swc/core-linux-x64-musl@1.3.101':
resolution: {integrity: sha512-kDN8lm4Eew0u1p+h1l3JzoeGgZPQ05qDE0czngnjmfpsH2sOZxVj1hdiCwS5lArpy7ktaLu5JdRnx70MkUzhXw==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
+ '@swc/core-linux-x64-musl@1.5.25':
+ resolution: {integrity: sha512-rsepMTgml0EkswWkBpg3Wrjj5eqjwTzZN5omAn1klzXSZnClTrfeHvBuoIJYVr1yx+jmBkqySgME2p7+magUAw==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [linux]
+
'@swc/core-win32-arm64-msvc@1.3.101':
resolution: {integrity: sha512-9Wn8TTLWwJKw63K/S+jjrZb9yoJfJwCE2RV5vPCCWmlMf3U1AXj5XuWOLUX+Rp2sGKau7wZKsvywhheWm+qndQ==}
engines: {node: '>=10'}
cpu: [arm64]
os: [win32]
+ '@swc/core-win32-arm64-msvc@1.5.25':
+ resolution: {integrity: sha512-DJDsLBsRBV3uQBShRK2x6fqzABp9RLNVxDUpTTvUjc7qywJ8vS/yn+POK/zCyVEqLagf1z/8D5CEQ+RAIJq1NA==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [win32]
+
'@swc/core-win32-ia32-msvc@1.3.101':
resolution: {integrity: sha512-onO5KvICRVlu2xmr4//V2je9O2XgS1SGKpbX206KmmjcJhXN5EYLSxW9qgg+kgV5mip+sKTHTAu7IkzkAtElYA==}
engines: {node: '>=10'}
cpu: [ia32]
os: [win32]
+ '@swc/core-win32-ia32-msvc@1.5.25':
+ resolution: {integrity: sha512-BARL1ulHol53MEKC1ZVWM3A3FP757UUgG5Q8v97za+4a1SaIgbwvAQyHDxMYWi9+ij+OapK8YnWjJcFa17g8dw==}
+ engines: {node: '>=10'}
+ cpu: [ia32]
+ os: [win32]
+
'@swc/core-win32-x64-msvc@1.3.101':
resolution: {integrity: sha512-T3GeJtNQV00YmiVw/88/nxJ/H43CJvFnpvBHCVn17xbahiVUOPOduh3rc9LgAkKiNt/aV8vU3OJR+6PhfMR7UQ==}
engines: {node: '>=10'}
cpu: [x64]
os: [win32]
+ '@swc/core-win32-x64-msvc@1.5.25':
+ resolution: {integrity: sha512-o+MHUWrQI9iR6EusEV8eNU2Ezi3KtlhUR4gfptQN5MbVzlgjTvQbhiKpE1GYOxp+0BLBbKRwITKOcdhxfEJ2Uw==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [win32]
+
'@swc/core@1.3.101':
resolution: {integrity: sha512-w5aQ9qYsd/IYmXADAnkXPGDMTqkQalIi+kfFf/MHRKTpaOL7DHjMXwPp/n8hJ0qNjRvchzmPtOqtPBiER50d8A==}
engines: {node: '>=10'}
@@ -3304,22 +3413,37 @@ packages:
'@swc/helpers':
optional: true
+ '@swc/core@1.5.25':
+ resolution: {integrity: sha512-qdGEIdLVoTjEQ7w72UyyQ0wLFY4XbHfZiidmPHKJQsvSXzdpHXxPdlTCea/mY4AhMqo/M+pvkJSXJAxZnFl7qw==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@swc/helpers': '*'
+ peerDependenciesMeta:
+ '@swc/helpers':
+ optional: true
+
'@swc/counter@0.1.3':
resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
+ '@swc/helpers@0.5.11':
+ resolution: {integrity: sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==}
+
'@swc/helpers@0.5.2':
resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==}
'@swc/types@0.1.6':
resolution: {integrity: sha512-/JLo/l2JsT/LRd80C3HfbmVpxOAJ11FO2RCEslFrgzLltoP9j8XIbsyDcfCt2WWyX+CM96rBoNM+IToAkFOugg==}
- '@tabler/icons-react@3.5.0':
- resolution: {integrity: sha512-bn05XKZV3ZfOv5Jr1FCTmVPOQGBVJoA4NefrnR919rqg6WGXAa08NovONHJGSuMxXUMV3b9Cni85diIW/E9yuw==}
+ '@swc/types@0.1.7':
+ resolution: {integrity: sha512-scHWahbHF0eyj3JsxG9CFJgFdFNaVQCNAimBlT6PzS3n/HptxqREjsm4OH6AN3lYcffZYSPxXW8ua2BEHp0lJQ==}
+
+ '@tabler/icons-react@3.6.0':
+ resolution: {integrity: sha512-mkYGxlphNzvKq32teL+Z8wZW7I9zDftmNPX38UnZVCGjss2qbg0puqLhi1unfm5Y0CSefg+iAQrsjSL+DHx9YA==}
peerDependencies:
react: '>= 16'
- '@tabler/icons@3.5.0':
- resolution: {integrity: sha512-I53dC3ZSHQ2MZFGvDYJelfXm91L2bTTixS4w5jTAulLhHbCZso5Bih4Rk/NYZxlngLQMKHvEYwZQ+6w/WluKiA==}
+ '@tabler/icons@3.6.0':
+ resolution: {integrity: sha512-Zv0Ofc64RCMpZ2F8CvsWAphrSjerx5hEErt/RMmE+W8r4E5l5Lizi+My9KbbZQ4NyAtrtrOX80OY1oROZrRzEA==}
'@tanstack/eslint-plugin-query@5.35.6':
resolution: {integrity: sha512-XhVRLsJFJMWYNzArPzy1MWSpx2BSUnc8Zof+fvsgaAnWBy9tjNXH3DFftZoNMGA8Mw1dPIdDPkEQcSku3m80Jw==}
@@ -3360,6 +3484,13 @@ packages:
peerDependencies:
'@tiptap/core': ^2.0.0
+ '@tiptap/extension-code-block-lowlight@2.4.0':
+ resolution: {integrity: sha512-j0SdFq66A97Cn7bQOMqFYBaYsmOltZZ6o4uDZH6fdTvEFbfXTdtTYs2awsNSbW+w/DtivKZCvAX1FRLR3/g/5A==}
+ peerDependencies:
+ '@tiptap/core': ^2.0.0
+ '@tiptap/extension-code-block': ^2.0.0
+ '@tiptap/pm': ^2.0.0
+
'@tiptap/extension-code-block@2.4.0':
resolution: {integrity: sha512-QWGdv1D56TBGbbJSj2cIiXGJEKguPiAl9ONzJ/Ql1ZksiQsYwx0YHriXX6TOC//T4VIf6NSClHEtwtxWBQ/Csg==}
peerDependencies:
@@ -3440,6 +3571,11 @@ packages:
'@tiptap/core': ^2.0.0
'@tiptap/pm': ^2.0.0
+ '@tiptap/extension-image@2.4.0':
+ resolution: {integrity: sha512-NIVhRPMO/ONo8OywEd+8zh0Q6Q7EbFHtBxVsvfOKj9KtZkaXQfUO4MzONTyptkvAchTpj9pIzeaEY5fyU87gFA==}
+ peerDependencies:
+ '@tiptap/core': ^2.0.0
+
'@tiptap/extension-italic@2.4.0':
resolution: {integrity: sha512-aaW/L9q+KNHHK+X73MPloHeIsT191n3VLd3xm6uUcFDnUNvzYJ/q65/1ZicdtCaOLvTutxdrEvhbkrVREX6a8g==}
peerDependencies:
@@ -3499,6 +3635,27 @@ packages:
peerDependencies:
'@tiptap/core': ^2.0.0
+ '@tiptap/extension-table-cell@2.4.0':
+ resolution: {integrity: sha512-zylResMWLvV17Z6+GEDjvvl+YpJqJhNMyJsZPZNx/72OcNCDN3p2d6RGFwhpnCpdzZDD6LGaIgWaTj9oeg53SA==}
+ peerDependencies:
+ '@tiptap/core': ^2.0.0
+
+ '@tiptap/extension-table-header@2.4.0':
+ resolution: {integrity: sha512-FZCOyJHSFsMTCfBh49J1DlwgpUIM5Ivpr57Za8FVvUkk8RKUIOKpNsZqxE+Wrw+2Bvy5H4X7Azb588x0NDqfOQ==}
+ peerDependencies:
+ '@tiptap/core': ^2.0.0
+
+ '@tiptap/extension-table-row@2.4.0':
+ resolution: {integrity: sha512-K4FDI4YzyLWZbhIZYYL15uqs6M3QsPZGTpTdkSaxcKMLholcskDSHhJmySxnrjI0+JNAtyIiqlWBfA1/9Zyhng==}
+ peerDependencies:
+ '@tiptap/core': ^2.0.0
+
+ '@tiptap/extension-table@2.4.0':
+ resolution: {integrity: sha512-ceIUnPSqVCb+qC0XZSgApoG3dL3MRvWrGl1nIMxEqPgMsD/MP6MsYV1Lx/GmtdUlEEsV1624cGTBiRzeCuWkZA==}
+ peerDependencies:
+ '@tiptap/core': ^2.0.0
+ '@tiptap/pm': ^2.0.0
+
'@tiptap/extension-task-item@2.4.0':
resolution: {integrity: sha512-x40vdHnmDiBbA2pjWR/92wVGb6jT13Nk2AhRUI/oP/r4ZGKpTypoB7heDnvLBgH0Y5a51dFqU+G1SFFL30u5uA==}
peerDependencies:
@@ -3535,6 +3692,11 @@ packages:
peerDependencies:
'@tiptap/core': ^2.0.0
+ '@tiptap/extension-youtube@2.4.0':
+ resolution: {integrity: sha512-Ew6Oik9DaqP0xgQSUIWwozqeToJVOY4nqjRoKExGRuLdzgZeS+SmEA22ITBMcnZSJj8XBMgGBLcCWi+A7x1KAg==}
+ peerDependencies:
+ '@tiptap/core': ^2.0.0
+
'@tiptap/html@2.4.0':
resolution: {integrity: sha512-iM0sa6t0Hb5GTXnjdKvMDtD3KZgA4Mwx3QADeqfR10EjfPNlkh/BHU83oIhss/2JVRBXiUUDnNxW9cfpHX37/g==}
peerDependencies:
@@ -3612,6 +3774,9 @@ packages:
'@types/eslint-scope@3.7.7':
resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==}
+ '@types/eslint@8.56.10':
+ resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==}
+
'@types/eslint@8.56.6':
resolution: {integrity: sha512-ymwc+qb1XkjT/gfoQwxIeHZ6ixH23A+tCT2ADSA/DPVKzAjwYkTXBMCQ/f6fe4wEa85Lhp26VPeUxI7wMhAi7A==}
@@ -3630,6 +3795,9 @@ packages:
'@types/graceful-fs@4.1.9':
resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==}
+ '@types/hast@3.0.4':
+ resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
+
'@types/http-errors@2.0.4':
resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==}
@@ -3660,6 +3828,9 @@ packages:
'@types/jsonwebtoken@9.0.6':
resolution: {integrity: sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==}
+ '@types/katex@0.16.7':
+ resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==}
+
'@types/methods@1.1.4':
resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==}
@@ -3738,6 +3909,9 @@ packages:
'@types/throttle-debounce@2.1.0':
resolution: {integrity: sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ==}
+ '@types/unist@3.0.2':
+ resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==}
+
'@types/uuid@9.0.8':
resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==}
@@ -4391,6 +4565,10 @@ packages:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
+ commander@8.3.0:
+ resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
+ engines: {node: '>= 12'}
+
comment-json@4.2.3:
resolution: {integrity: sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==}
engines: {node: '>= 6'}
@@ -4428,6 +4606,9 @@ packages:
cookiejar@2.1.4:
resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==}
+ copy-anything@2.0.6:
+ resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==}
+
core-js-compat@3.35.0:
resolution: {integrity: sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw==}
@@ -4475,6 +4656,12 @@ packages:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
+ css-styled@1.0.8:
+ resolution: {integrity: sha512-tCpP7kLRI8dI95rCh3Syl7I+v7PP+2JYOzWkl0bUEoSbJM+u8ITbutjlQVf0NC2/g4ULROJPi16sfwDIO8/84g==}
+
+ css-to-mat@1.1.1:
+ resolution: {integrity: sha512-kvpxFYZb27jRd2vium35G7q5XZ2WJ9rWjDUMNT36M3Hc41qCrLXFM5iEKMGXcrPsKfXEN+8l/riB4QzwwwiEyQ==}
+
css-what@6.1.0:
resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==}
engines: {node: '>= 6'}
@@ -4551,6 +4738,10 @@ packages:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'}
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
detect-libc@2.0.3:
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
engines: {node: '>=8'}
@@ -4566,6 +4757,9 @@ packages:
resolution: {integrity: sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==}
hasBin: true
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
dezalgo@1.0.4:
resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==}
@@ -4695,6 +4889,10 @@ packages:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
+ errno@0.1.8:
+ resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
+ hasBin: true
+
error-ex@1.3.2:
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
@@ -5020,6 +5218,9 @@ packages:
react-dom:
optional: true
+ framework-utils@1.1.0:
+ resolution: {integrity: sha512-KAfqli5PwpFJ8o3psRNs8svpMGyCSAe8nmGcjQ0zZBWN2H6dZDnq+ABp3N3hdUmFeMrLtjOCTXD4yplUJIWceg==}
+
fs-constants@1.0.0:
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
@@ -5061,6 +5262,9 @@ packages:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'}
+ gesto@1.19.4:
+ resolution: {integrity: sha512-hfr/0dWwh0Bnbb88s3QVJd1ZRJeOWcgHPPwmiH6NnafDYvhTsxg+SLYu+q/oPNh9JS3V+nlr6fNs8kvPAtcRDQ==}
+
get-caller-file@2.0.5:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*}
@@ -5175,6 +5379,10 @@ packages:
resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==}
engines: {node: '>=8'}
+ highlight.js@11.9.0:
+ resolution: {integrity: sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==}
+ engines: {node: '>=12.0.0'}
+
hoist-non-react-statics@3.3.2:
resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
@@ -5208,6 +5416,10 @@ packages:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
+ iconv-lite@0.6.3:
+ resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
+ engines: {node: '>=0.10.0'}
+
ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
@@ -5215,6 +5427,11 @@ packages:
resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
engines: {node: '>= 4'}
+ image-size@0.5.5:
+ resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==}
+ engines: {node: '>=0.10.0'}
+ hasBin: true
+
import-fresh@3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
engines: {node: '>=6'}
@@ -5327,6 +5544,9 @@ packages:
resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==}
engines: {node: '>=12'}
+ is-what@3.14.1:
+ resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==}
+
is-wsl@2.2.0:
resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
engines: {node: '>=8'}
@@ -5608,6 +5828,16 @@ packages:
resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==}
engines: {node: '>=18'}
+ katex@0.16.10:
+ resolution: {integrity: sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA==}
+ hasBin: true
+
+ keycode@2.2.1:
+ resolution: {integrity: sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg==}
+
+ keycon@1.4.0:
+ resolution: {integrity: sha512-p1NAIxiRMH3jYfTeXRs2uWbVJ1WpEjpi8ktzUyBJsX7/wn2qu2VRXktneBLNtKNxJmlUYxRi9gOJt1DuthXR7A==}
+
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@@ -5665,6 +5895,11 @@ packages:
leac@0.6.0:
resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==}
+ less@4.2.0:
+ resolution: {integrity: sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==}
+ engines: {node: '>=6'}
+ hasBin: true
+
leven@3.1.0:
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
engines: {node: '>=6'}
@@ -5776,6 +6011,9 @@ packages:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
+ lowlight@3.1.0:
+ resolution: {integrity: sha512-CEbNVoSikAxwDMDPjXlqlFYiZLkDJHwyGu/MfOsJnF3d7f3tds5J3z8s/l9TMXhzfsJCCJEAsD78842mwmg0PQ==}
+
lru-cache@10.2.0:
resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==}
engines: {node: 14 || >=16.14}
@@ -5795,6 +6033,10 @@ packages:
resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==}
engines: {node: '>=12'}
+ make-dir@2.1.0:
+ resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==}
+ engines: {node: '>=6'}
+
make-dir@3.1.0:
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
engines: {node: '>=8'}
@@ -5856,6 +6098,11 @@ packages:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
+ mime@1.6.0:
+ resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
mime@2.6.0:
resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==}
engines: {node: '>=4.0.0'}
@@ -5960,6 +6207,11 @@ packages:
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+ needle@3.3.1:
+ resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==}
+ engines: {node: '>= 4.4.x'}
+ hasBin: true
+
negotiator@0.6.3:
resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
engines: {node: '>= 0.6'}
@@ -6131,6 +6383,9 @@ packages:
resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
engines: {node: '>=0.10.0'}
+ overlap-area@1.1.0:
+ resolution: {integrity: sha512-3dlJgJCaVeXH0/eZjYVJvQiLVVrPO4U1ZGqlATtx6QGO3b5eNM6+JgUKa7oStBTdYuGTk7gVoABCW6Tp+dhRdw==}
+
p-limit@2.3.0:
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
engines: {node: '>=6'}
@@ -6163,6 +6418,10 @@ packages:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'}
+ parse-node-version@1.0.1:
+ resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==}
+ engines: {node: '>= 0.10'}
+
parseley@0.12.1:
resolution: {integrity: sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==}
@@ -6273,6 +6532,10 @@ packages:
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
engines: {node: '>=0.10.0'}
+ pify@4.0.1:
+ resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
+ engines: {node: '>=6'}
+
pino-abstract-transport@1.2.0:
resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==}
@@ -6507,6 +6770,9 @@ packages:
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+ prr@1.0.1:
+ resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
+
punycode.js@2.3.1:
resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
engines: {node: '>=6'}
@@ -6537,6 +6803,9 @@ packages:
react: '>= 16.14'
react-dom: '>= 16.14'
+ react-css-styled@1.1.9:
+ resolution: {integrity: sha512-M7fJZ3IWFaIHcZEkoFOnkjdiUFmwd8d+gTh2bpqMOcnxy/0Gsykw4dsL4QBiKsxcGow6tETUa4NAUcmJF+/nfw==}
+
react-dnd-html5-backend@14.1.0:
resolution: {integrity: sha512-6ONeqEC3XKVf4eVmMTe0oPds+c5B9Foyj8p/ZKLb7kL2qh9COYxiBHv3szd6gztqi/efkmriywLUVlPotqoJyw==}
@@ -6584,6 +6853,9 @@ packages:
react-is@18.2.0:
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
+ react-moveable@0.56.0:
+ resolution: {integrity: sha512-FmJNmIOsOA36mdxbrc/huiE4wuXSRlmon/o+/OrfNhSiYYYL0AV5oObtPluEhb2Yr/7EfYWBHTxF5aWAvjg1SA==}
+
react-number-format@5.3.1:
resolution: {integrity: sha512-qpYcQLauIeEhCZUZY9jXZnnroOtdy3jYaS1zQ3M1Sr6r/KMOBEIGNIb7eKT19g2N1wbYgFgvDzs19hw5TrB8XQ==}
peerDependencies:
@@ -6640,6 +6912,9 @@ packages:
peerDependencies:
react: '>=16.8'
+ react-selecto@1.26.3:
+ resolution: {integrity: sha512-Ubik7kWSnZyQEBNro+1k38hZaI1tJarE+5aD/qsqCOA1uUBSjgKVBy3EWRzGIbdmVex7DcxznFZLec/6KZNvwQ==}
+
react-style-singleton@2.2.1:
resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==}
engines: {node: '>=10'}
@@ -6841,6 +7116,9 @@ packages:
sanitize-filename-ts@1.0.2:
resolution: {integrity: sha512-bON2VOJoappmaBHlnxvBNk5R7HkUAsirf5m1M5Kz15uZykDGbHfGPCQNcEQKR8HrQhgh9CmQ6Xe9y71yM9ywkw==}
+ sax@1.4.1:
+ resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
+
scheduler@0.23.2:
resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
@@ -6854,6 +7132,13 @@ packages:
selderee@0.11.0:
resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==}
+ selecto@1.26.3:
+ resolution: {integrity: sha512-gZHgqMy5uyB6/2YDjv3Qqaf7bd2hTDOpPdxXlrez4R3/L0GiEWDCFaUfrflomgqdb3SxHF2IXY0Jw0EamZi7cw==}
+
+ semver@5.7.2:
+ resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
+ hasBin: true
+
semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
@@ -6863,6 +7148,11 @@ packages:
engines: {node: '>=10'}
hasBin: true
+ semver@7.6.2:
+ resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==}
+ engines: {node: '>=10'}
+ hasBin: true
+
serialize-javascript@6.0.2:
resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
@@ -7178,9 +7468,6 @@ packages:
tippy.js@6.3.7:
resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==}
- tiptap-extension-global-drag-handle@0.1.8:
- resolution: {integrity: sha512-alLZm385Ot9USqmO5s4HAPHgQnIScuuMxAXgxqVEBhKPkN/Zl8ICEW5caPx+b7kFUOGVDcgbRFDR+My4A91iXw==}
-
tmp@0.0.33:
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
engines: {node: '>=0.6.0'}
@@ -8236,11 +8523,6 @@ snapshots:
'@smithy/types': 3.0.0
tslib: 2.6.2
- '@babel/code-frame@7.23.5':
- dependencies:
- '@babel/highlight': 7.23.4
- chalk: 2.4.2
-
'@babel/code-frame@7.24.2':
dependencies:
'@babel/highlight': 7.24.2
@@ -8520,12 +8802,6 @@ snapshots:
'@babel/template': 7.24.6
'@babel/types': 7.24.6
- '@babel/highlight@7.23.4':
- dependencies:
- '@babel/helper-validator-identifier': 7.22.20
- chalk: 2.4.2
- js-tokens: 4.0.0
-
'@babel/highlight@7.24.2':
dependencies:
'@babel/helper-validator-identifier': 7.22.20
@@ -9130,7 +9406,7 @@ snapshots:
'@babel/template@7.22.15':
dependencies:
- '@babel/code-frame': 7.23.5
+ '@babel/code-frame': 7.24.6
'@babel/parser': 7.24.1
'@babel/types': 7.24.0
@@ -9205,6 +9481,10 @@ snapshots:
'@casl/ability': 6.7.1
react: 18.3.1
+ '@cfcs/core@0.0.6':
+ dependencies:
+ '@egjs/component': 3.0.5
+
'@colors/colors@1.5.0':
optional: true
@@ -9216,6 +9496,18 @@ snapshots:
dependencies:
'@jridgewell/trace-mapping': 0.3.9
+ '@daybrush/utils@1.13.0': {}
+
+ '@egjs/agent@2.4.3': {}
+
+ '@egjs/children-differ@1.0.1':
+ dependencies:
+ '@egjs/list-differ': 1.0.1
+
+ '@egjs/component@3.0.5': {}
+
+ '@egjs/list-differ@1.0.1': {}
+
'@emoji-mart/data@1.2.1': {}
'@emoji-mart/react@1.1.1(emoji-mart@5.6.0)(react@18.3.1)':
@@ -9579,7 +9871,7 @@ snapshots:
jest-util: 29.7.0
slash: 3.0.0
- '@jest/core@29.7.0(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5))':
+ '@jest/core@29.7.0(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5))':
dependencies:
'@jest/console': 29.7.0
'@jest/reporters': 29.7.0
@@ -9593,7 +9885,7 @@ snapshots:
exit: 0.1.2
graceful-fs: 4.2.11
jest-changed-files: 29.7.0
- jest-config: 29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5))
+ jest-config: 29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5))
jest-haste-map: 29.7.0
jest-message-util: 29.7.0
jest-regex-util: 29.6.3
@@ -9870,7 +10162,7 @@ snapshots:
bullmq: 5.7.14
tslib: 2.6.2
- '@nestjs/cli@10.3.2(@swc/core@1.3.101(@swc/helpers@0.5.2))':
+ '@nestjs/cli@10.3.2(@swc/core@1.5.25(@swc/helpers@0.5.11))':
dependencies:
'@angular-devkit/core': 17.1.2(chokidar@3.6.0)
'@angular-devkit/schematics': 17.1.2(chokidar@3.6.0)
@@ -9880,7 +10172,7 @@ snapshots:
chokidar: 3.6.0
cli-table3: 0.6.3
commander: 4.1.1
- fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.90.1(@swc/core@1.3.101(@swc/helpers@0.5.2)))
+ fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.90.1(@swc/core@1.5.25(@swc/helpers@0.5.11)))
glob: 10.3.10
inquirer: 8.2.6
node-emoji: 1.11.0
@@ -9892,10 +10184,10 @@ snapshots:
tsconfig-paths: 4.2.0
tsconfig-paths-webpack-plugin: 4.1.0
typescript: 5.3.3
- webpack: 5.90.1(@swc/core@1.3.101(@swc/helpers@0.5.2))
+ webpack: 5.90.1(@swc/core@1.5.25(@swc/helpers@0.5.11))
webpack-node-externals: 3.0.0
optionalDependencies:
- '@swc/core': 1.3.101(@swc/helpers@0.5.2)
+ '@swc/core': 1.5.25(@swc/helpers@0.5.11)
transitivePeerDependencies:
- esbuild
- uglify-js
@@ -10071,15 +10363,15 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.17.1
- '@nrwl/devkit@19.1.2(nx@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2)))':
+ '@nrwl/devkit@19.1.2(nx@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11)))':
dependencies:
- '@nx/devkit': 19.1.2(nx@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2)))
+ '@nx/devkit': 19.1.2(nx@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11)))
transitivePeerDependencies:
- nx
- '@nrwl/js@19.1.2(@babel/traverse@7.24.6)(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(nx@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2)))(typescript@5.4.5)':
+ '@nrwl/js@19.1.2(@babel/traverse@7.24.6)(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(nx@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11)))(typescript@5.4.5)':
dependencies:
- '@nx/js': 19.1.2(@babel/traverse@7.24.6)(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(nx@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2)))(typescript@5.4.5)
+ '@nx/js': 19.1.2(@babel/traverse@7.24.6)(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(nx@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11)))(typescript@5.4.5)
transitivePeerDependencies:
- '@babel/traverse'
- '@swc-node/register'
@@ -10092,18 +10384,18 @@ snapshots:
- typescript
- verdaccio
- '@nrwl/tao@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2))':
+ '@nrwl/tao@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11))':
dependencies:
- nx: 19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2))
+ nx: 19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11))
tslib: 2.6.2
transitivePeerDependencies:
- '@swc-node/register'
- '@swc/core'
- debug
- '@nrwl/workspace@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2))':
+ '@nrwl/workspace@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11))':
dependencies:
- '@nx/workspace': 19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2))
+ '@nx/workspace': 19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11))
transitivePeerDependencies:
- '@swc-node/register'
- '@swc/core'
@@ -10117,20 +10409,20 @@ snapshots:
transitivePeerDependencies:
- encoding
- '@nx/devkit@19.1.2(nx@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2)))':
+ '@nx/devkit@19.1.2(nx@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11)))':
dependencies:
- '@nrwl/devkit': 19.1.2(nx@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2)))
+ '@nrwl/devkit': 19.1.2(nx@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11)))
ejs: 3.1.9
enquirer: 2.3.6
ignore: 5.3.1
minimatch: 9.0.3
- nx: 19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2))
+ nx: 19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11))
semver: 7.6.0
tmp: 0.2.1
tslib: 2.6.2
yargs-parser: 21.1.1
- '@nx/js@19.1.2(@babel/traverse@7.24.6)(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(nx@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2)))(typescript@5.4.5)':
+ '@nx/js@19.1.2(@babel/traverse@7.24.6)(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(nx@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11)))(typescript@5.4.5)':
dependencies:
'@babel/core': 7.24.3
'@babel/plugin-proposal-decorators': 7.23.7(@babel/core@7.24.3)
@@ -10139,9 +10431,9 @@ snapshots:
'@babel/preset-env': 7.23.8(@babel/core@7.24.3)
'@babel/preset-typescript': 7.23.3(@babel/core@7.24.3)
'@babel/runtime': 7.23.7
- '@nrwl/js': 19.1.2(@babel/traverse@7.24.6)(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(nx@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2)))(typescript@5.4.5)
- '@nx/devkit': 19.1.2(nx@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2)))
- '@nx/workspace': 19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2))
+ '@nrwl/js': 19.1.2(@babel/traverse@7.24.6)(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(nx@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11)))(typescript@5.4.5)
+ '@nx/devkit': 19.1.2(nx@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11)))
+ '@nx/workspace': 19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11))
babel-plugin-const-enum: 1.2.0(@babel/core@7.24.3)
babel-plugin-macros: 2.8.0
babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.24.3)(@babel/traverse@7.24.6)
@@ -10158,7 +10450,7 @@ snapshots:
ora: 5.3.0
semver: 7.6.0
source-map-support: 0.5.19
- ts-node: 10.9.1(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5)
+ ts-node: 10.9.1(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5)
tsconfig-paths: 4.2.0
tslib: 2.6.2
transitivePeerDependencies:
@@ -10202,13 +10494,13 @@ snapshots:
'@nx/nx-win32-x64-msvc@19.1.2':
optional: true
- '@nx/workspace@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2))':
+ '@nx/workspace@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11))':
dependencies:
- '@nrwl/workspace': 19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2))
- '@nx/devkit': 19.1.2(nx@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2)))
+ '@nrwl/workspace': 19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11))
+ '@nx/devkit': 19.1.2(nx@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11)))
chalk: 4.1.2
enquirer: 2.3.6
- nx: 19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2))
+ nx: 19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11))
tslib: 2.6.2
yargs-parser: 21.1.1
transitivePeerDependencies:
@@ -10758,6 +11050,19 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.13.2':
optional: true
+ '@scena/dragscroll@1.4.0':
+ dependencies:
+ '@daybrush/utils': 1.13.0
+ '@scena/event-emitter': 1.0.5
+
+ '@scena/event-emitter@1.0.5':
+ dependencies:
+ '@daybrush/utils': 1.13.0
+
+ '@scena/matrix@1.1.1':
+ dependencies:
+ '@daybrush/utils': 1.13.0
+
'@selderee/plugin-htmlparser2@0.11.0':
dependencies:
domhandler: 5.0.3
@@ -11110,34 +11415,64 @@ snapshots:
'@swc/core-darwin-arm64@1.3.101':
optional: true
+ '@swc/core-darwin-arm64@1.5.25':
+ optional: true
+
'@swc/core-darwin-x64@1.3.101':
optional: true
+ '@swc/core-darwin-x64@1.5.25':
+ optional: true
+
'@swc/core-linux-arm-gnueabihf@1.3.101':
optional: true
+ '@swc/core-linux-arm-gnueabihf@1.5.25':
+ optional: true
+
'@swc/core-linux-arm64-gnu@1.3.101':
optional: true
+ '@swc/core-linux-arm64-gnu@1.5.25':
+ optional: true
+
'@swc/core-linux-arm64-musl@1.3.101':
optional: true
+ '@swc/core-linux-arm64-musl@1.5.25':
+ optional: true
+
'@swc/core-linux-x64-gnu@1.3.101':
optional: true
+ '@swc/core-linux-x64-gnu@1.5.25':
+ optional: true
+
'@swc/core-linux-x64-musl@1.3.101':
optional: true
+ '@swc/core-linux-x64-musl@1.5.25':
+ optional: true
+
'@swc/core-win32-arm64-msvc@1.3.101':
optional: true
+ '@swc/core-win32-arm64-msvc@1.5.25':
+ optional: true
+
'@swc/core-win32-ia32-msvc@1.3.101':
optional: true
+ '@swc/core-win32-ia32-msvc@1.5.25':
+ optional: true
+
'@swc/core-win32-x64-msvc@1.3.101':
optional: true
- '@swc/core@1.3.101(@swc/helpers@0.5.2)':
+ '@swc/core-win32-x64-msvc@1.5.25':
+ optional: true
+
+ '@swc/core@1.3.101(@swc/helpers@0.5.11)':
dependencies:
'@swc/counter': 0.1.3
'@swc/types': 0.1.6
@@ -11152,10 +11487,33 @@ snapshots:
'@swc/core-win32-arm64-msvc': 1.3.101
'@swc/core-win32-ia32-msvc': 1.3.101
'@swc/core-win32-x64-msvc': 1.3.101
- '@swc/helpers': 0.5.2
+ '@swc/helpers': 0.5.11
+
+ '@swc/core@1.5.25(@swc/helpers@0.5.11)':
+ dependencies:
+ '@swc/counter': 0.1.3
+ '@swc/types': 0.1.7
+ optionalDependencies:
+ '@swc/core-darwin-arm64': 1.5.25
+ '@swc/core-darwin-x64': 1.5.25
+ '@swc/core-linux-arm-gnueabihf': 1.5.25
+ '@swc/core-linux-arm64-gnu': 1.5.25
+ '@swc/core-linux-arm64-musl': 1.5.25
+ '@swc/core-linux-x64-gnu': 1.5.25
+ '@swc/core-linux-x64-musl': 1.5.25
+ '@swc/core-win32-arm64-msvc': 1.5.25
+ '@swc/core-win32-ia32-msvc': 1.5.25
+ '@swc/core-win32-x64-msvc': 1.5.25
+ '@swc/helpers': 0.5.11
+ optional: true
'@swc/counter@0.1.3': {}
+ '@swc/helpers@0.5.11':
+ dependencies:
+ tslib: 2.6.2
+ optional: true
+
'@swc/helpers@0.5.2':
dependencies:
tslib: 2.6.2
@@ -11164,12 +11522,17 @@ snapshots:
dependencies:
'@swc/counter': 0.1.3
- '@tabler/icons-react@3.5.0(react@18.3.1)':
+ '@swc/types@0.1.7':
dependencies:
- '@tabler/icons': 3.5.0
+ '@swc/counter': 0.1.3
+ optional: true
+
+ '@tabler/icons-react@3.6.0(react@18.3.1)':
+ dependencies:
+ '@tabler/icons': 3.6.0
react: 18.3.1
- '@tabler/icons@3.5.0': {}
+ '@tabler/icons@3.6.0': {}
'@tanstack/eslint-plugin-query@5.35.6(eslint@9.4.0)(typescript@5.4.5)':
dependencies:
@@ -11208,6 +11571,12 @@ snapshots:
dependencies:
'@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
+ '@tiptap/extension-code-block-lowlight@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/extension-code-block@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)':
+ dependencies:
+ '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
+ '@tiptap/extension-code-block': 2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)
+ '@tiptap/pm': 2.4.0
+
'@tiptap/extension-code-block@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)':
dependencies:
'@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
@@ -11275,6 +11644,10 @@ snapshots:
'@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
'@tiptap/pm': 2.4.0
+ '@tiptap/extension-image@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))':
+ dependencies:
+ '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
+
'@tiptap/extension-italic@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))':
dependencies:
'@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
@@ -11324,6 +11697,23 @@ snapshots:
dependencies:
'@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
+ '@tiptap/extension-table-cell@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))':
+ dependencies:
+ '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
+
+ '@tiptap/extension-table-header@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))':
+ dependencies:
+ '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
+
+ '@tiptap/extension-table-row@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))':
+ dependencies:
+ '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
+
+ '@tiptap/extension-table@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)':
+ dependencies:
+ '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
+ '@tiptap/pm': 2.4.0
+
'@tiptap/extension-task-item@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)':
dependencies:
'@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
@@ -11353,6 +11743,10 @@ snapshots:
dependencies:
'@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
+ '@tiptap/extension-youtube@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))':
+ dependencies:
+ '@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
+
'@tiptap/html@2.4.0(@tiptap/core@2.4.0(@tiptap/pm@2.4.0))(@tiptap/pm@2.4.0)':
dependencies:
'@tiptap/core': 2.4.0(@tiptap/pm@2.4.0)
@@ -11477,6 +11871,12 @@ snapshots:
'@types/eslint': 8.56.6
'@types/estree': 1.0.5
+ '@types/eslint@8.56.10':
+ dependencies:
+ '@types/estree': 1.0.5
+ '@types/json-schema': 7.0.15
+ optional: true
+
'@types/eslint@8.56.6':
dependencies:
'@types/estree': 1.0.5
@@ -11507,6 +11907,10 @@ snapshots:
dependencies:
'@types/node': 20.14.0
+ '@types/hast@3.0.4':
+ dependencies:
+ '@types/unist': 3.0.2
+
'@types/http-errors@2.0.4': {}
'@types/istanbul-lib-coverage@2.0.6': {}
@@ -11540,6 +11944,8 @@ snapshots:
dependencies:
'@types/node': 20.14.0
+ '@types/katex@0.16.7': {}
+
'@types/methods@1.1.4': {}
'@types/mime-types@2.1.4': {}
@@ -11627,15 +12033,17 @@ snapshots:
'@types/throttle-debounce@2.1.0': {}
+ '@types/unist@3.0.2': {}
+
'@types/uuid@9.0.8': {}
'@types/validator@13.11.9': {}
- '@types/webpack@5.28.5(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11)':
+ '@types/webpack@5.28.5(@swc/core@1.3.101(@swc/helpers@0.5.11))(esbuild@0.19.11)':
dependencies:
'@types/node': 20.14.0
tapable: 2.2.1
- webpack: 5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11)
+ webpack: 5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.11))(esbuild@0.19.11)
transitivePeerDependencies:
- '@swc/core'
- esbuild
@@ -11790,14 +12198,14 @@ snapshots:
dependencies:
'@ucast/core': 1.10.2
- '@vitejs/plugin-react@4.3.0(vite@5.2.12(@types/node@20.14.0)(sugarss@4.0.1(postcss@8.4.38))(terser@5.29.2))':
+ '@vitejs/plugin-react@4.3.0(vite@5.2.12(@types/node@20.14.0)(less@4.2.0)(sugarss@4.0.1(postcss@8.4.38))(terser@5.29.2))':
dependencies:
'@babel/core': 7.24.6
'@babel/plugin-transform-react-jsx-self': 7.24.6(@babel/core@7.24.6)
'@babel/plugin-transform-react-jsx-source': 7.24.6(@babel/core@7.24.6)
'@types/babel__core': 7.20.5
react-refresh: 0.14.2
- vite: 5.2.12(@types/node@20.14.0)(sugarss@4.0.1(postcss@8.4.38))(terser@5.29.2)
+ vite: 5.2.12(@types/node@20.14.0)(less@4.2.0)(sugarss@4.0.1(postcss@8.4.38))(terser@5.29.2)
transitivePeerDependencies:
- supports-color
@@ -12378,6 +12786,8 @@ snapshots:
commander@4.1.1: {}
+ commander@8.3.0: {}
+
comment-json@4.2.3:
dependencies:
array-timsort: 1.0.3
@@ -12411,6 +12821,11 @@ snapshots:
cookiejar@2.1.4: {}
+ copy-anything@2.0.6:
+ dependencies:
+ is-what: 3.14.1
+ optional: true
+
core-js-compat@3.35.0:
dependencies:
browserslist: 4.23.0
@@ -12439,13 +12854,13 @@ snapshots:
optionalDependencies:
typescript: 5.3.3
- create-jest@29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5)):
+ create-jest@29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5)):
dependencies:
'@jest/types': 29.6.3
chalk: 4.1.2
exit: 0.1.2
graceful-fs: 4.2.11
- jest-config: 29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5))
+ jest-config: 29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5))
jest-util: 29.7.0
prompts: 2.4.2
transitivePeerDependencies:
@@ -12472,6 +12887,15 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
+ css-styled@1.0.8:
+ dependencies:
+ '@daybrush/utils': 1.13.0
+
+ css-to-mat@1.1.1:
+ dependencies:
+ '@daybrush/utils': 1.13.0
+ '@scena/matrix': 1.1.1
+
css-what@6.1.0: {}
cssesc@3.0.0: {}
@@ -12518,6 +12942,8 @@ snapshots:
depd@2.0.0: {}
+ dequal@2.0.3: {}
+
detect-libc@2.0.3: {}
detect-newline@3.1.0: {}
@@ -12531,6 +12957,10 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
+
dezalgo@1.0.4:
dependencies:
asap: 2.0.6
@@ -12668,6 +13098,11 @@ snapshots:
entities@4.5.0: {}
+ errno@0.1.8:
+ dependencies:
+ prr: 1.0.1
+ optional: true
+
error-ex@1.3.2:
dependencies:
is-arrayish: 0.2.1
@@ -12757,14 +13192,14 @@ snapshots:
eslint: 9.4.0
eslint-plugin-turbo: 1.10.12(eslint@9.4.0)
- eslint-plugin-prettier@5.1.3(@types/eslint@8.56.6)(eslint-config-prettier@9.1.0(eslint@9.4.0))(eslint@9.4.0)(prettier@3.3.0):
+ eslint-plugin-prettier@5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@9.4.0))(eslint@9.4.0)(prettier@3.3.0):
dependencies:
eslint: 9.4.0
prettier: 3.3.0
prettier-linter-helpers: 1.0.0
synckit: 0.8.8
optionalDependencies:
- '@types/eslint': 8.56.6
+ '@types/eslint': 8.56.10
eslint-config-prettier: 9.1.0(eslint@9.4.0)
eslint-plugin-react-hooks@4.6.2(eslint@9.4.0):
@@ -13035,7 +13470,7 @@ snapshots:
cross-spawn: 7.0.3
signal-exit: 4.1.0
- fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.90.1(@swc/core@1.3.101(@swc/helpers@0.5.2))):
+ fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.90.1(@swc/core@1.5.25(@swc/helpers@0.5.11))):
dependencies:
'@babel/code-frame': 7.24.2
chalk: 4.1.2
@@ -13050,7 +13485,7 @@ snapshots:
semver: 7.6.0
tapable: 2.2.1
typescript: 5.3.3
- webpack: 5.90.1(@swc/core@1.3.101(@swc/helpers@0.5.2))
+ webpack: 5.90.1(@swc/core@1.5.25(@swc/helpers@0.5.11))
form-data@4.0.0:
dependencies:
@@ -13078,6 +13513,8 @@ snapshots:
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
+ framework-utils@1.1.0: {}
+
fs-constants@1.0.0: {}
fs-extra@10.1.0:
@@ -13121,6 +13558,11 @@ snapshots:
gensync@1.0.0-beta.2: {}
+ gesto@1.19.4:
+ dependencies:
+ '@daybrush/utils': 1.13.0
+ '@scena/event-emitter': 1.0.5
+
get-caller-file@2.0.5: {}
get-intrinsic@1.2.4:
@@ -13238,6 +13680,8 @@ snapshots:
hexoid@1.0.0: {}
+ highlight.js@11.9.0: {}
+
hoist-non-react-statics@3.3.2:
dependencies:
react-is: 16.13.1
@@ -13284,10 +13728,18 @@ snapshots:
dependencies:
safer-buffer: 2.1.2
+ iconv-lite@0.6.3:
+ dependencies:
+ safer-buffer: 2.1.2
+ optional: true
+
ieee754@1.2.1: {}
ignore@5.3.1: {}
+ image-size@0.5.5:
+ optional: true
+
import-fresh@3.3.0:
dependencies:
parent-module: 1.0.1
@@ -13425,6 +13877,9 @@ snapshots:
is-unicode-supported@1.3.0: {}
+ is-what@3.14.1:
+ optional: true
+
is-wsl@2.2.0:
dependencies:
is-docker: 2.2.1
@@ -13453,7 +13908,7 @@ snapshots:
'@babel/parser': 7.24.1
'@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.2
- semver: 7.6.0
+ semver: 7.6.2
transitivePeerDependencies:
- supports-color
@@ -13523,16 +13978,16 @@ snapshots:
- babel-plugin-macros
- supports-color
- jest-cli@29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5)):
+ jest-cli@29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5)):
dependencies:
- '@jest/core': 29.7.0(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5))
+ '@jest/core': 29.7.0(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5))
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
chalk: 4.1.2
- create-jest: 29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5))
+ create-jest: 29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5))
exit: 0.1.2
import-local: 3.1.0
- jest-config: 29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5))
+ jest-config: 29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5))
jest-util: 29.7.0
jest-validate: 29.7.0
yargs: 17.7.2
@@ -13542,7 +13997,7 @@ snapshots:
- supports-color
- ts-node
- jest-config@29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5)):
+ jest-config@29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5)):
dependencies:
'@babel/core': 7.24.3
'@jest/test-sequencer': 29.7.0
@@ -13568,7 +14023,7 @@ snapshots:
strip-json-comments: 3.1.1
optionalDependencies:
'@types/node': 20.14.0
- ts-node: 10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5)
+ ts-node: 10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5)
transitivePeerDependencies:
- babel-plugin-macros
- supports-color
@@ -13794,12 +14249,12 @@ snapshots:
merge-stream: 2.0.0
supports-color: 8.1.1
- jest@29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5)):
+ jest@29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5)):
dependencies:
- '@jest/core': 29.7.0(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5))
+ '@jest/core': 29.7.0(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5))
'@jest/types': 29.6.3
import-local: 3.1.0
- jest-cli: 29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5))
+ jest-cli: 29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5))
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
@@ -13895,6 +14350,19 @@ snapshots:
jwt-decode@4.0.0: {}
+ katex@0.16.10:
+ dependencies:
+ commander: 8.3.0
+
+ keycode@2.2.1: {}
+
+ keycon@1.4.0:
+ dependencies:
+ '@cfcs/core': 0.0.6
+ '@daybrush/utils': 1.13.0
+ '@scena/event-emitter': 1.0.5
+ keycode: 2.2.1
+
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
@@ -13926,6 +14394,21 @@ snapshots:
leac@0.6.0: {}
+ less@4.2.0:
+ dependencies:
+ copy-anything: 2.0.6
+ parse-node-version: 1.0.1
+ tslib: 2.6.2
+ optionalDependencies:
+ errno: 0.1.8
+ graceful-fs: 4.2.11
+ image-size: 0.5.5
+ make-dir: 2.1.0
+ mime: 1.6.0
+ needle: 3.3.1
+ source-map: 0.6.1
+ optional: true
+
leven@3.1.0: {}
levn@0.4.1:
@@ -14012,6 +14495,12 @@ snapshots:
dependencies:
js-tokens: 4.0.0
+ lowlight@3.1.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ devlop: 1.1.0
+ highlight.js: 11.9.0
+
lru-cache@10.2.0: {}
lru-cache@5.1.1:
@@ -14028,13 +14517,19 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
+ make-dir@2.1.0:
+ dependencies:
+ pify: 4.0.1
+ semver: 5.7.2
+ optional: true
+
make-dir@3.1.0:
dependencies:
semver: 6.3.1
make-dir@4.0.0:
dependencies:
- semver: 7.6.0
+ semver: 7.6.2
make-error@1.3.6: {}
@@ -14083,6 +14578,9 @@ snapshots:
dependencies:
mime-db: 1.52.0
+ mime@1.6.0:
+ optional: true
+
mime@2.6.0: {}
mime@3.0.0: {}
@@ -14172,6 +14670,12 @@ snapshots:
natural-compare@1.4.0: {}
+ needle@3.3.1:
+ dependencies:
+ iconv-lite: 0.6.3
+ sax: 1.4.1
+ optional: true
+
negotiator@0.6.3: {}
neo-async@2.6.2: {}
@@ -14263,9 +14767,9 @@ snapshots:
gauge: 3.0.2
set-blocking: 2.0.0
- nx@19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2)):
+ nx@19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11)):
dependencies:
- '@nrwl/tao': 19.1.2(@swc/core@1.3.101(@swc/helpers@0.5.2))
+ '@nrwl/tao': 19.1.2(@swc/core@1.5.25(@swc/helpers@0.5.11))
'@yarnpkg/lockfile': 1.1.0
'@yarnpkg/parsers': 3.0.0-rc.46
'@zkochan/js-yaml': 0.0.7
@@ -14309,7 +14813,7 @@ snapshots:
'@nx/nx-linux-x64-musl': 19.1.2
'@nx/nx-win32-arm64-msvc': 19.1.2
'@nx/nx-win32-x64-msvc': 19.1.2
- '@swc/core': 1.3.101(@swc/helpers@0.5.2)
+ '@swc/core': 1.5.25(@swc/helpers@0.5.11)
transitivePeerDependencies:
- debug
@@ -14385,6 +14889,10 @@ snapshots:
os-tmpdir@1.0.2: {}
+ overlap-area@1.1.0:
+ dependencies:
+ '@daybrush/utils': 1.13.0
+
p-limit@2.3.0:
dependencies:
p-try: 2.2.0
@@ -14416,6 +14924,9 @@ snapshots:
json-parse-even-better-errors: 2.3.1
lines-and-columns: 1.2.4
+ parse-node-version@1.0.1:
+ optional: true
+
parseley@0.12.1:
dependencies:
leac: 0.6.0
@@ -14514,6 +15025,9 @@ snapshots:
pify@2.3.0: {}
+ pify@4.0.1:
+ optional: true
+
pino-abstract-transport@1.2.0:
dependencies:
readable-stream: 4.5.2
@@ -14555,13 +15069,13 @@ snapshots:
camelcase-css: 2.0.1
postcss: 8.4.38
- postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5)):
+ postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5)):
dependencies:
lilconfig: 3.1.1
yaml: 2.4.2
optionalDependencies:
postcss: 8.4.38
- ts-node: 10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5)
+ ts-node: 10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5)
postcss-mixins@9.0.4(postcss@8.4.38):
dependencies:
@@ -14784,6 +15298,9 @@ snapshots:
proxy-from-env@1.1.0: {}
+ prr@1.0.1:
+ optional: true
+
punycode.js@2.3.1: {}
punycode@2.3.1: {}
@@ -14816,6 +15333,11 @@ snapshots:
- '@types/node'
- '@types/react'
+ react-css-styled@1.1.9:
+ dependencies:
+ css-styled: 1.0.8
+ framework-utils: 1.1.0
+
react-dnd-html5-backend@14.1.0:
dependencies:
dnd-core: 14.0.1
@@ -14838,7 +15360,7 @@ snapshots:
react: 18.3.1
scheduler: 0.23.2
- react-email@2.1.4(@swc/helpers@0.5.2)(babel-plugin-macros@2.8.0)(eslint@9.4.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5)):
+ react-email@2.1.4(@swc/helpers@0.5.11)(babel-plugin-macros@2.8.0)(eslint@9.4.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5)):
dependencies:
'@babel/core': 7.24.5
'@babel/parser': 7.24.5
@@ -14848,10 +15370,10 @@ snapshots:
'@radix-ui/react-slot': 1.0.2(@types/react@18.3.3)(react@18.3.1)
'@radix-ui/react-toggle-group': 1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-tooltip': 1.0.7(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- '@swc/core': 1.3.101(@swc/helpers@0.5.2)
+ '@swc/core': 1.3.101(@swc/helpers@0.5.11)
'@types/react': 18.3.3
'@types/react-dom': 18.3.0
- '@types/webpack': 5.28.5(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11)
+ '@types/webpack': 5.28.5(@swc/core@1.3.101(@swc/helpers@0.5.11))(esbuild@0.19.11)
autoprefixer: 10.4.14(postcss@8.4.38)
chalk: 4.1.2
chokidar: 3.5.3
@@ -14879,7 +15401,7 @@ snapshots:
source-map-js: 1.0.2
stacktrace-parser: 0.1.10
tailwind-merge: 2.2.0
- tailwindcss: 3.4.0(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5))
+ tailwindcss: 3.4.0(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5))
typescript: 5.1.6
transitivePeerDependencies:
- '@opentelemetry/api'
@@ -14912,6 +15434,22 @@ snapshots:
react-is@18.2.0: {}
+ react-moveable@0.56.0:
+ dependencies:
+ '@daybrush/utils': 1.13.0
+ '@egjs/agent': 2.4.3
+ '@egjs/children-differ': 1.0.1
+ '@egjs/list-differ': 1.0.1
+ '@scena/dragscroll': 1.4.0
+ '@scena/event-emitter': 1.0.5
+ '@scena/matrix': 1.1.1
+ css-to-mat: 1.1.1
+ framework-utils: 1.1.0
+ gesto: 1.19.4
+ overlap-area: 1.1.0
+ react-css-styled: 1.1.9
+ react-selecto: 1.26.3
+
react-number-format@5.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
prop-types: 15.8.1
@@ -14966,6 +15504,10 @@ snapshots:
'@remix-run/router': 1.16.1
react: 18.3.1
+ react-selecto@1.26.3:
+ dependencies:
+ selecto: 1.26.3
+
react-style-singleton@2.2.1(@types/react@18.3.3)(react@18.3.1):
dependencies:
get-nonce: 1.0.1
@@ -15178,6 +15720,9 @@ snapshots:
dependencies:
truncate-utf8-bytes: 1.0.2
+ sax@1.4.1:
+ optional: true
+
scheduler@0.23.2:
dependencies:
loose-envify: 1.4.0
@@ -15194,12 +15739,30 @@ snapshots:
dependencies:
parseley: 0.12.1
+ selecto@1.26.3:
+ dependencies:
+ '@daybrush/utils': 1.13.0
+ '@egjs/children-differ': 1.0.1
+ '@scena/dragscroll': 1.4.0
+ '@scena/event-emitter': 1.0.5
+ css-styled: 1.0.8
+ css-to-mat: 1.1.1
+ framework-utils: 1.1.0
+ gesto: 1.19.4
+ keycon: 1.4.0
+ overlap-area: 1.1.0
+
+ semver@5.7.2:
+ optional: true
+
semver@6.3.1: {}
semver@7.6.0:
dependencies:
lru-cache: 6.0.0
+ semver@7.6.2: {}
+
serialize-javascript@6.0.2:
dependencies:
randombytes: 2.1.0
@@ -15483,7 +16046,7 @@ snapshots:
dependencies:
'@babel/runtime': 7.23.7
- tailwindcss@3.4.0(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5)):
+ tailwindcss@3.4.0(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5)):
dependencies:
'@alloc/quick-lru': 5.2.0
arg: 5.0.2
@@ -15502,7 +16065,7 @@ snapshots:
postcss: 8.4.38
postcss-import: 15.1.0(postcss@8.4.38)
postcss-js: 4.0.1(postcss@8.4.38)
- postcss-load-config: 4.0.2(postcss@8.4.38)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5))
+ postcss-load-config: 4.0.2(postcss@8.4.38)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5))
postcss-nested: 6.0.1(postcss@8.4.38)
postcss-selector-parser: 6.0.15
resolve: 1.22.8
@@ -15529,28 +16092,27 @@ snapshots:
mkdirp: 1.0.4
yallist: 4.0.0
- terser-webpack-plugin@5.3.10(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11)(webpack@5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11)):
+ terser-webpack-plugin@5.3.10(@swc/core@1.5.25(@swc/helpers@0.5.11))(webpack@5.90.1(@swc/core@1.5.25(@swc/helpers@0.5.11))):
dependencies:
'@jridgewell/trace-mapping': 0.3.25
jest-worker: 27.5.1
schema-utils: 3.3.0
serialize-javascript: 6.0.2
terser: 5.29.2
- webpack: 5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11)
+ webpack: 5.90.1(@swc/core@1.5.25(@swc/helpers@0.5.11))
optionalDependencies:
- '@swc/core': 1.3.101(@swc/helpers@0.5.2)
- esbuild: 0.19.11
+ '@swc/core': 1.5.25(@swc/helpers@0.5.11)
- terser-webpack-plugin@5.3.10(@swc/core@1.3.101(@swc/helpers@0.5.2))(webpack@5.90.1(@swc/core@1.3.101(@swc/helpers@0.5.2))):
+ terser-webpack-plugin@5.3.10(@swc/core@1.5.25(@swc/helpers@0.5.11))(webpack@5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.11))(esbuild@0.19.11)):
dependencies:
'@jridgewell/trace-mapping': 0.3.25
jest-worker: 27.5.1
schema-utils: 3.3.0
serialize-javascript: 6.0.2
terser: 5.29.2
- webpack: 5.90.1(@swc/core@1.3.101(@swc/helpers@0.5.2))
+ webpack: 5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.11))(esbuild@0.19.11)
optionalDependencies:
- '@swc/core': 1.3.101(@swc/helpers@0.5.2)
+ '@swc/core': 1.5.25(@swc/helpers@0.5.11)
terser@5.29.2:
dependencies:
@@ -15587,8 +16149,6 @@ snapshots:
dependencies:
'@popperjs/core': 2.11.8
- tiptap-extension-global-drag-handle@0.1.8: {}
-
tmp@0.0.33:
dependencies:
os-tmpdir: 1.0.2
@@ -15623,11 +16183,11 @@ snapshots:
ts-interface-checker@0.1.13: {}
- ts-jest@29.1.4(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5)))(typescript@5.4.5):
+ ts-jest@29.1.4(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5)))(typescript@5.4.5):
dependencies:
bs-logger: 0.2.6
fast-json-stable-stringify: 2.1.0
- jest: 29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5))
+ jest: 29.7.0(@types/node@20.14.0)(babel-plugin-macros@2.8.0)(ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5))
jest-util: 29.7.0
json5: 2.2.3
lodash.memoize: 4.1.2
@@ -15641,7 +16201,7 @@ snapshots:
'@jest/types': 29.6.3
babel-jest: 29.7.0(@babel/core@7.24.3)
- ts-loader@9.5.1(typescript@5.4.5)(webpack@5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11)):
+ ts-loader@9.5.1(typescript@5.4.5)(webpack@5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.11))(esbuild@0.19.11)):
dependencies:
chalk: 4.1.2
enhanced-resolve: 5.16.0
@@ -15649,9 +16209,9 @@ snapshots:
semver: 7.6.0
source-map: 0.7.4
typescript: 5.4.5
- webpack: 5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11)
+ webpack: 5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.11))(esbuild@0.19.11)
- ts-node@10.9.1(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5):
+ ts-node@10.9.1(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5):
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.9
@@ -15669,9 +16229,9 @@ snapshots:
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
optionalDependencies:
- '@swc/core': 1.3.101(@swc/helpers@0.5.2)
+ '@swc/core': 1.5.25(@swc/helpers@0.5.11)
- ts-node@10.9.2(@swc/core@1.3.101(@swc/helpers@0.5.2))(@types/node@20.14.0)(typescript@5.4.5):
+ ts-node@10.9.2(@swc/core@1.5.25(@swc/helpers@0.5.11))(@types/node@20.14.0)(typescript@5.4.5):
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.9
@@ -15689,7 +16249,7 @@ snapshots:
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
optionalDependencies:
- '@swc/core': 1.3.101(@swc/helpers@0.5.2)
+ '@swc/core': 1.5.25(@swc/helpers@0.5.11)
tsconfig-paths-webpack-plugin@4.1.0:
dependencies:
@@ -15827,7 +16387,7 @@ snapshots:
vary@1.1.2: {}
- vite@5.2.12(@types/node@20.14.0)(sugarss@4.0.1(postcss@8.4.38))(terser@5.29.2):
+ vite@5.2.12(@types/node@20.14.0)(less@4.2.0)(sugarss@4.0.1(postcss@8.4.38))(terser@5.29.2):
dependencies:
esbuild: 0.20.2
postcss: 8.4.38
@@ -15835,6 +16395,7 @@ snapshots:
optionalDependencies:
'@types/node': 20.14.0
fsevents: 2.3.3
+ less: 4.2.0
sugarss: 4.0.1(postcss@8.4.38)
terser: 5.29.2
@@ -15859,7 +16420,7 @@ snapshots:
webpack-sources@3.2.3: {}
- webpack@5.90.1(@swc/core@1.3.101(@swc/helpers@0.5.2)):
+ webpack@5.90.1(@swc/core@1.5.25(@swc/helpers@0.5.11)):
dependencies:
'@types/eslint-scope': 3.7.7
'@types/estree': 1.0.5
@@ -15882,7 +16443,7 @@ snapshots:
neo-async: 2.6.2
schema-utils: 3.3.0
tapable: 2.2.1
- terser-webpack-plugin: 5.3.10(@swc/core@1.3.101(@swc/helpers@0.5.2))(webpack@5.90.1(@swc/core@1.3.101(@swc/helpers@0.5.2)))
+ terser-webpack-plugin: 5.3.10(@swc/core@1.5.25(@swc/helpers@0.5.11))(webpack@5.90.1(@swc/core@1.5.25(@swc/helpers@0.5.11)))
watchpack: 2.4.1
webpack-sources: 3.2.3
transitivePeerDependencies:
@@ -15890,7 +16451,7 @@ snapshots:
- esbuild
- uglify-js
- webpack@5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11):
+ webpack@5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.11))(esbuild@0.19.11):
dependencies:
'@types/eslint-scope': 3.7.7
'@types/estree': 1.0.5
@@ -15913,7 +16474,7 @@ snapshots:
neo-async: 2.6.2
schema-utils: 3.3.0
tapable: 2.2.1
- terser-webpack-plugin: 5.3.10(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11)(webpack@5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.2))(esbuild@0.19.11))
+ terser-webpack-plugin: 5.3.10(@swc/core@1.5.25(@swc/helpers@0.5.11))(webpack@5.91.0(@swc/core@1.3.101(@swc/helpers@0.5.11))(esbuild@0.19.11))
watchpack: 2.4.1
webpack-sources: 3.2.3
transitivePeerDependencies: