diff --git a/package.json b/package.json
index bf0868c..fbcdbd1 100644
--- a/package.json
+++ b/package.json
@@ -9,11 +9,16 @@
"start": "next start"
},
"dependencies": {
- "tiktoken": "^1.0.11",
"@radix-ui/react-checkbox": "^1.0.3",
"@radix-ui/react-popover": "^1.0.5",
"@radix-ui/react-select": "^1.2.0",
"@tanstack/react-query": "^4.20.2",
+ "@tiptap/core": "^2.3.0",
+ "@tiptap/extension-document": "^2.3.0",
+ "@tiptap/extension-paragraph": "^2.3.0",
+ "@tiptap/extension-text": "^2.3.0",
+ "@tiptap/pm": "^2.3.0",
+ "@tiptap/react": "^2.3.0",
"@trpc/client": "^10.9.0",
"@trpc/next": "^10.9.0",
"@trpc/react-query": "^10.9.0",
@@ -31,6 +36,7 @@
"superjson": "1.9.1",
"tailwind-merge": "^1.10.0",
"tailwindcss-animate": "^1.0.5",
+ "tiktoken": "^1.0.11",
"zod": "^3.20.6"
},
"devDependencies": {
diff --git a/src/components/RichEditor.tsx b/src/components/RichEditor.tsx
new file mode 100644
index 0000000..d33879a
--- /dev/null
+++ b/src/components/RichEditor.tsx
@@ -0,0 +1,227 @@
+import Document from "@tiptap/extension-document";
+import Paragraph from "@tiptap/extension-paragraph";
+import Text from "@tiptap/extension-text";
+import {
+ EditorContent,
+ Extension,
+ useEditor,
+ type JSONContent,
+} from "@tiptap/react";
+import { useEffect, useMemo } from "react";
+import { Plugin, PluginKey } from "@tiptap/pm/state";
+
+import { type Node } from "@tiptap/pm/model";
+import { Decoration, DecorationSet } from "@tiptap/pm/view";
+import Graphemer from "graphemer";
+import { cn } from "~/utils/cn";
+import { type UserModelChoice, getUserSelectedEncoder } from "~/utils/model";
+
+const COLORS = [
+ "bg-sky-200",
+ "bg-amber-200",
+ "bg-blue-200",
+ "bg-green-200",
+ "bg-orange-200",
+ "bg-cyan-200",
+ "bg-gray-200",
+ "bg-purple-200",
+ "bg-indigo-200",
+ "bg-lime-200",
+ "bg-rose-200",
+ "bg-violet-200",
+ "bg-yellow-200",
+ "bg-emerald-200",
+ "bg-zinc-200",
+ "bg-red-200",
+ "bg-fuchsia-200",
+ "bg-pink-200",
+ "bg-teal-200",
+];
+
+function convertTextToJSONContent(content: string | null | undefined) {
+ if (content == null) return [];
+ const lines = content.split("\n");
+ return lines.map(
+ (line): JSONContent => ({
+ type: "paragraph",
+ content: line ? [{ type: "text", text: line }] : [],
+ })
+ );
+}
+
+function convertMessageToJSONContent(
+ content: string | null | undefined
+): JSONContent {
+ if (typeof content === "string") {
+ return {
+ type: "doc",
+ content: convertTextToJSONContent(content),
+ };
+ }
+
+ return { type: "doc", content: [] };
+}
+
+const key = new PluginKey("tiktokenizer");
+
+function binarySearch(haystack: number[], needle: number) {
+ let left = 0;
+ let right = haystack.length - 1;
+
+ while (left <= right) {
+ const cursor = (left + right) >> 1;
+ if (haystack[cursor]! <= needle) left = cursor + 1;
+ else right = cursor - 1;
+ }
+
+ return needle + left;
+}
+
+export const TokenHighlighter = Extension.create<{ model: UserModelChoice }>({
+ name: "colorHighlighter",
+
+ addProseMirrorPlugins() {
+ const encoder = getUserSelectedEncoder(this.options.model);
+
+ const graphemer = new Graphemer();
+ const textDecoder = new TextDecoder();
+
+ function getTokenDecorations(doc: Node): DecorationSet {
+ let text = "";
+ const bounds: number[] = [];
+
+ doc.descendants((node, position) => {
+ const insert = (position > 0 ? `\n` : "") + node.textContent;
+ bounds.push(text.length);
+ text += insert;
+
+ return false;
+ });
+
+ const encoding = encoder.encode(text, "all");
+
+ let textAcc = 0;
+ let byteAcc: number[] = [];
+ let tokenAcc: number[] = [];
+ let inputGraphemes = graphemer.splitGraphemes(text);
+
+ const decorations: Decoration[] = [];
+ for (let idx = 0; idx < encoding.length; idx++) {
+ const token = encoding[idx]!;
+ byteAcc.push(...encoder.decode_single_token_bytes(token));
+ tokenAcc.push(token);
+
+ const segmentText = textDecoder.decode(new Uint8Array(byteAcc));
+ const graphemes = graphemer.splitGraphemes(segmentText);
+
+ if (graphemes.every((item, idx) => inputGraphemes[idx] === item)) {
+ decorations.push(
+ Decoration.inline(
+ binarySearch(bounds, textAcc),
+ binarySearch(bounds, textAcc + segmentText.length),
+ { class: cn(COLORS[decorations.length % COLORS.length]) }
+ )
+ );
+
+ textAcc += segmentText.length;
+
+ byteAcc = [];
+ tokenAcc = [];
+ inputGraphemes = inputGraphemes.slice(graphemes.length);
+ }
+ }
+
+ return DecorationSet.create(doc, decorations);
+ }
+
+ return [
+ new Plugin({
+ key,
+ state: {
+ init: (_, { doc }) => getTokenDecorations(doc),
+ apply: (transaction, oldState) =>
+ transaction.docChanged
+ ? getTokenDecorations(transaction.doc)
+ : oldState,
+ },
+ props: {
+ decorations(state) {
+ return this.getState(state);
+ },
+ },
+ }),
+ ];
+ },
+});
+
+export function RichEditor(props: {
+ value: string;
+ onChange: (value: string) => void;
+ model: UserModelChoice;
+}) {
+ const content = useMemo(
+ () => convertMessageToJSONContent(props.value),
+ [props.value]
+ );
+
+ const editor = useEditor(
+ {
+ extensions: [
+ Document,
+ Paragraph,
+ Text,
+ TokenHighlighter.configure({ model: props.model }),
+ ],
+ editorProps: {
+ attributes: { class: cn("outline-none p-3 border rounded-md") },
+ },
+
+ content,
+ onUpdate: ({ editor }) => {
+ const json = editor.getJSON();
+ const values: Array<{ type: "text"; text: string }> = [];
+
+ // assume root is type="doc"
+ for (const child of json.content ?? []) {
+ switch (child.type) {
+ case "paragraph": {
+ const text = (
+ child.content
+ ?.map((i) => i.text)
+ .filter((x): x is string => x != null) ?? []
+ ).join("");
+
+ values.push({ type: "text" as const, text });
+ break;
+ }
+ case "text": {
+ if (child.text)
+ values.push({ type: "text" as const, text: child.text });
+ break;
+ }
+ }
+ }
+
+ let result: string = values
+ .filter((i): i is { type: "text"; text: string } => i.type === "text")
+ .map((i) => i.text)
+ .join("\n");
+ props.onChange?.(result);
+ },
+ },
+ [props.model]
+ );
+
+ useEffect(() => {
+ if (!editor) return;
+ let { from, to } = editor.state.selection;
+ editor.commands.setContent(content, false, { preserveWhitespace: "full" });
+ editor.commands.setTextSelection({ from, to });
+ }, [editor, content]);
+
+ return (
+
+
+
+ );
+}
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index eb845c3..07417f4 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -16,41 +16,11 @@ import {
} from "~/sections/EncoderSelect";
import { TokenViewer } from "~/sections/TokenViewer";
import { TextArea } from "~/components/Input";
-import {
- encoding_for_model,
- get_encoding,
- type TiktokenModel,
- type TiktokenEncoding,
-} from "tiktoken";
+import { type TiktokenModel, type TiktokenEncoding } from "tiktoken";
import { getSegments } from "~/utils/segments";
import { useRouter } from "next/router";
-
-function getUserSelectedEncoder(
- params: { model: TiktokenModel } | { encoder: TiktokenEncoding }
-) {
- if ("model" in params) {
- if (
- params.model === "gpt-4" ||
- params.model === "gpt-4-32k" ||
- params.model === "gpt-3.5-turbo" ||
- params.model === "gpt-4-1106-preview"
- ) {
- return encoding_for_model(params.model, {
- "<|im_start|>": 100264,
- "<|im_end|>": 100265,
- "<|im_sep|>": 100266,
- });
- }
-
- return encoding_for_model(params.model);
- }
-
- if ("encoder" in params) {
- return get_encoding(params.encoder);
- }
-
- throw new Error("Invalid params");
-}
+import { RichEditor } from "~/components/RichEditor";
+import { getUserSelectedEncoder } from "../utils/model";
function isChatModel(
params: { model: TiktokenModel } | { encoder: TiktokenEncoding }
@@ -130,6 +100,8 @@ const Home: NextPage> = (
/>
+
+
{isChatModel(params) && (
diff --git a/src/utils/model.tsx b/src/utils/model.tsx
new file mode 100644
index 0000000..b7fe640
--- /dev/null
+++ b/src/utils/model.tsx
@@ -0,0 +1,35 @@
+import {
+ encoding_for_model,
+ get_encoding,
+ type TiktokenModel,
+ type TiktokenEncoding,
+} from "tiktoken";
+
+export type UserModelChoice =
+ | { model: TiktokenModel }
+ | { encoder: TiktokenEncoding };
+
+export function getUserSelectedEncoder(params: UserModelChoice) {
+ if ("model" in params) {
+ if (
+ params.model === "gpt-4" ||
+ params.model === "gpt-4-32k" ||
+ params.model === "gpt-3.5-turbo" ||
+ params.model === "gpt-4-1106-preview"
+ ) {
+ return encoding_for_model(params.model, {
+ "<|im_start|>": 100264,
+ "<|im_end|>": 100265,
+ "<|im_sep|>": 100266,
+ });
+ }
+
+ return encoding_for_model(params.model);
+ }
+
+ if ("encoder" in params) {
+ return get_encoding(params.encoder);
+ }
+
+ throw new Error("Invalid params");
+}
diff --git a/yarn.lock b/yarn.lock
index ef0bfc7..5fd8ba0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -293,6 +293,11 @@
tiny-glob "^0.2.9"
tslib "^2.4.0"
+"@popperjs/core@^2.9.0":
+ version "2.11.8"
+ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f"
+ integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==
+
"@radix-ui/number@1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-1.0.0.tgz#4c536161d0de750b3f5d55860fc3de46264f897b"
@@ -705,6 +710,11 @@
dependencies:
"@babel/runtime" "^7.13.10"
+"@remirror/core-constants@^2.0.2":
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/@remirror/core-constants/-/core-constants-2.0.2.tgz#f05eccdc69e3a65e7d524b52548f567904a11a1a"
+ integrity sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==
+
"@rushstack/eslint-patch@^1.1.3":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728"
@@ -730,6 +740,72 @@
"@tanstack/query-core" "4.24.10"
use-sync-external-store "^1.2.0"
+"@tiptap/core@^2.3.0":
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.3.0.tgz#5a0b41b63af62860dec6d6b689e2893118f76e83"
+ integrity sha512-Gk2JN3i5CMkYGmsbyFI7cBUftWa+F7QYmeCLTWfbuy+hCM2OBsnYVKxhggFPGXRL5KLBEgBWeCeWMHfIw3B2MA==
+
+"@tiptap/extension-bubble-menu@^2.3.0":
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.3.0.tgz#3447dcc68aaaa76c8327cb636976164986b270c7"
+ integrity sha512-dqyfQ8idTlhapvt0fxCGvkyjw92pBEwPqmkJ01h3EE8wTh53j0ytOHyMSf1KBuzardxpd8Yya3zlrAcR0Z3DlQ==
+ dependencies:
+ tippy.js "^6.3.7"
+
+"@tiptap/extension-document@^2.3.0":
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.3.0.tgz#a15e17a48f6d24f317f73a7fff79385a2524f081"
+ integrity sha512-WC55SMrtlsNOnHXpzbXDzJOp7eKmZV0rXooKmvCDqoiLO/DKpyQXyF+0UHfcRPmUAi2GWFPaer7+p1H9xzcjXg==
+
+"@tiptap/extension-floating-menu@^2.3.0":
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.3.0.tgz#ac61ffeac479cdf019a270d23464fd08af6ab931"
+ integrity sha512-bNY43/yU/+wGfmk2eDV7EPDAN/akbC+YnSKTA5VPJADzscvlrL2HlQrxbd/STIdlwKqdPU5MokcvCChhfZ4f6w==
+ dependencies:
+ tippy.js "^6.3.7"
+
+"@tiptap/extension-paragraph@^2.3.0":
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.3.0.tgz#959928b57785f4647d807fffe76e63719f2e53c4"
+ integrity sha512-peCpA7DFqkd0cHb+cHv4YHNoMsXG8tKFNJlCHpLmsZWl2hWmpKgKmUrXAUfzjcFSvkZxn0xYc5oWbqUgg+2LzA==
+
+"@tiptap/extension-text@^2.3.0":
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.3.0.tgz#2ebd13dcb4f54b9f72af25fc1015eec474afe89d"
+ integrity sha512-zkudl0TyKRy/8vHtyo5dMzjBRD0HEUnsS8YOsjR4xwQq5EYUXleRgM1s6lb6Yms2sLUAZRWdDddoQ686iq4zQg==
+
+"@tiptap/pm@^2.3.0":
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-2.3.0.tgz#3f971d5d26401ba0db306f2ee1e317acb8ff6c91"
+ integrity sha512-4WYqShZBwDyReKvapC0nmeYdOtZbZ31y4MjolpKQaSD4I7kg/oZspC+byUGdvIRsNpRN7i2X0IyvdISKk8gw5Q==
+ dependencies:
+ prosemirror-changeset "^2.2.1"
+ prosemirror-collab "^1.3.1"
+ prosemirror-commands "^1.5.2"
+ prosemirror-dropcursor "^1.8.1"
+ prosemirror-gapcursor "^1.3.2"
+ prosemirror-history "^1.3.2"
+ prosemirror-inputrules "^1.3.0"
+ prosemirror-keymap "^1.2.2"
+ prosemirror-markdown "^1.12.0"
+ prosemirror-menu "^1.2.4"
+ prosemirror-model "^1.19.4"
+ prosemirror-schema-basic "^1.2.2"
+ prosemirror-schema-list "^1.3.0"
+ prosemirror-state "^1.4.3"
+ prosemirror-tables "^1.3.5"
+ prosemirror-trailing-node "^2.0.7"
+ prosemirror-transform "^1.8.0"
+ prosemirror-view "^1.32.7"
+
+"@tiptap/react@^2.3.0":
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/@tiptap/react/-/react-2.3.0.tgz#b9a7c29a8bae38a28a3d6ab910da11290addcc58"
+ integrity sha512-ThgFJQTWYKRClTV2Zg0wBRqfy0EGz3U4NOey7jwncUjSjx5+o9nXbfQAYWDKQFfWyE+wnrBTYfddEP9pHNX5cQ==
+ dependencies:
+ "@tiptap/extension-bubble-menu" "^2.3.0"
+ "@tiptap/extension-floating-menu" "^2.3.0"
+
"@trpc/client@^10.9.0":
version "10.13.2"
resolved "https://registry.yarnpkg.com/@trpc/client/-/client-10.13.2.tgz#9303f6b47d587cbf5d3d1cccfa0032174dbe9fae"
@@ -1325,6 +1401,11 @@ copy-anything@^3.0.2:
dependencies:
is-what "^4.1.8"
+crelt@^1.0.0:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/crelt/-/crelt-1.0.6.tgz#7cc898ea74e190fb6ef9dae57f8f81cf7302df72"
+ integrity sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==
+
cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
@@ -1486,6 +1567,11 @@ enhanced-resolve@^5.10.0:
graceful-fs "^4.2.4"
tapable "^2.2.0"
+entities@^4.4.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
+ integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
+
es-abstract@^1.19.0, es-abstract@^1.20.4:
version "1.21.1"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.1.tgz#e6105a099967c08377830a0c9cb589d570dd86c6"
@@ -2441,6 +2527,13 @@ lilconfig@^2.0.5, lilconfig@^2.0.6:
resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4"
integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==
+linkify-it@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-5.0.0.tgz#9ef238bfa6dc70bd8e7f9572b52d369af569b421"
+ integrity sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==
+ dependencies:
+ uc.micro "^2.0.0"
+
local-pkg@^0.4.3:
version "0.4.3"
resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.4.3.tgz#0ff361ab3ae7f1c19113d9bb97b98b905dbc4963"
@@ -2496,6 +2589,18 @@ magic-string@^0.30.0:
dependencies:
"@jridgewell/sourcemap-codec" "^1.4.13"
+markdown-it@^14.0.0:
+ version "14.1.0"
+ resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-14.1.0.tgz#3c3c5992883c633db4714ccb4d7b5935d98b7d45"
+ integrity sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==
+ dependencies:
+ argparse "^2.0.1"
+ entities "^4.4.0"
+ linkify-it "^5.0.0"
+ mdurl "^2.0.0"
+ punycode.js "^2.3.1"
+ uc.micro "^2.1.0"
+
md5-hex@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-3.0.1.tgz#be3741b510591434b2784d79e556eefc2c9a8e5c"
@@ -2503,6 +2608,11 @@ md5-hex@^3.0.1:
dependencies:
blueimp-md5 "^2.10.0"
+mdurl@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-2.0.0.tgz#80676ec0433025dd3e17ee983d0fe8de5a2237e0"
+ integrity sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==
+
merge2@^1.3.0, merge2@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
@@ -2704,6 +2814,11 @@ optionator@^0.9.1:
type-check "^0.4.0"
word-wrap "^1.2.3"
+orderedmap@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-2.1.1.tgz#61481269c44031c449915497bf5a4ad273c512d2"
+ integrity sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==
+
p-limit@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
@@ -2886,6 +3001,164 @@ prop-types@^15.8.1:
object-assign "^4.1.1"
react-is "^16.13.1"
+prosemirror-changeset@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz#dae94b63aec618fac7bb9061648e6e2a79988383"
+ integrity sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==
+ dependencies:
+ prosemirror-transform "^1.0.0"
+
+prosemirror-collab@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz#0e8c91e76e009b53457eb3b3051fb68dad029a33"
+ integrity sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==
+ dependencies:
+ prosemirror-state "^1.0.0"
+
+prosemirror-commands@^1.0.0, prosemirror-commands@^1.5.2:
+ version "1.5.2"
+ resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz#e94aeea52286f658cd984270de9b4c3fff580852"
+ integrity sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==
+ dependencies:
+ prosemirror-model "^1.0.0"
+ prosemirror-state "^1.0.0"
+ prosemirror-transform "^1.0.0"
+
+prosemirror-dropcursor@^1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz#49b9fb2f583e0d0f4021ff87db825faa2be2832d"
+ integrity sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==
+ dependencies:
+ prosemirror-state "^1.0.0"
+ prosemirror-transform "^1.1.0"
+ prosemirror-view "^1.1.0"
+
+prosemirror-gapcursor@^1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz#5fa336b83789c6199a7341c9493587e249215cb4"
+ integrity sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==
+ dependencies:
+ prosemirror-keymap "^1.0.0"
+ prosemirror-model "^1.0.0"
+ prosemirror-state "^1.0.0"
+ prosemirror-view "^1.0.0"
+
+prosemirror-history@^1.0.0, prosemirror-history@^1.3.2:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.4.0.tgz#1edbce630aaf21b808e5a5cd798a09976ecb1827"
+ integrity sha512-UUiGzDVcqo1lovOPdi9YxxUps3oBFWAIYkXLu3Ot+JPv1qzVogRbcizxK3LhHmtaUxclohgiOVesRw5QSlMnbQ==
+ dependencies:
+ prosemirror-state "^1.2.2"
+ prosemirror-transform "^1.0.0"
+ prosemirror-view "^1.31.0"
+ rope-sequence "^1.3.0"
+
+prosemirror-inputrules@^1.3.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz#ef1519bb2cb0d1e0cec74bad1a97f1c1555068bb"
+ integrity sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==
+ dependencies:
+ prosemirror-state "^1.0.0"
+ prosemirror-transform "^1.0.0"
+
+prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz#14a54763a29c7b2704f561088ccf3384d14eb77e"
+ integrity sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==
+ dependencies:
+ prosemirror-state "^1.0.0"
+ w3c-keyname "^2.2.0"
+
+prosemirror-markdown@^1.12.0:
+ version "1.12.0"
+ resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.12.0.tgz#d2de09d37897abf7adb6293d925ff132dac5b0a6"
+ integrity sha512-6F5HS8Z0HDYiS2VQDZzfZP6A0s/I0gbkJy8NCzzDMtcsz3qrfqyroMMeoSjAmOhDITyon11NbXSzztfKi+frSQ==
+ dependencies:
+ markdown-it "^14.0.0"
+ prosemirror-model "^1.0.0"
+
+prosemirror-menu@^1.2.4:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz#3cfdc7c06d10f9fbd1bce29082c498bd11a0a79a"
+ integrity sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==
+ dependencies:
+ crelt "^1.0.0"
+ prosemirror-commands "^1.0.0"
+ prosemirror-history "^1.0.0"
+ prosemirror-state "^1.0.0"
+
+prosemirror-model@^1.0.0, prosemirror-model@^1.19.0, prosemirror-model@^1.19.4, prosemirror-model@^1.20.0, prosemirror-model@^1.8.1:
+ version "1.20.0"
+ resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.20.0.tgz#4bdc5221f7a58de9fb35d0919687b7e0c765ad53"
+ integrity sha512-q7AY7vMjKYqDCeoedgUiAgrLabliXxndJuuFmcmc2+YU1SblvnOiG2WEACF2lwAZsMlfLpiAilA3L+TWlDqIsQ==
+ dependencies:
+ orderedmap "^2.0.0"
+
+prosemirror-schema-basic@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.2.tgz#6695f5175e4628aab179bf62e5568628b9cfe6c7"
+ integrity sha512-/dT4JFEGyO7QnNTe9UaKUhjDXbTNkiWTq/N4VpKaF79bBjSExVV2NXmJpcM7z/gD7mbqNjxbmWW5nf1iNSSGnw==
+ dependencies:
+ prosemirror-model "^1.19.0"
+
+prosemirror-schema-list@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.3.0.tgz#05374702cf35a3ba5e7ec31079e355a488d52519"
+ integrity sha512-Hz/7gM4skaaYfRPNgr421CU4GSwotmEwBVvJh5ltGiffUJwm7C8GfN/Bc6DR1EKEp5pDKhODmdXXyi9uIsZl5A==
+ dependencies:
+ prosemirror-model "^1.0.0"
+ prosemirror-state "^1.0.0"
+ prosemirror-transform "^1.7.3"
+
+prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.4.3:
+ version "1.4.3"
+ resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.4.3.tgz#94aecf3ffd54ec37e87aa7179d13508da181a080"
+ integrity sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==
+ dependencies:
+ prosemirror-model "^1.0.0"
+ prosemirror-transform "^1.0.0"
+ prosemirror-view "^1.27.0"
+
+prosemirror-tables@^1.3.5:
+ version "1.3.7"
+ resolved "https://registry.yarnpkg.com/prosemirror-tables/-/prosemirror-tables-1.3.7.tgz#9d296bd432d2bc7dca90f14e5c3b5c5f61277f7a"
+ integrity sha512-oEwX1wrziuxMtwFvdDWSFHVUWrFJWt929kVVfHvtTi8yvw+5ppxjXZkMG/fuTdFo+3DXyIPSKfid+Be1npKXDA==
+ dependencies:
+ prosemirror-keymap "^1.1.2"
+ prosemirror-model "^1.8.1"
+ prosemirror-state "^1.3.1"
+ prosemirror-transform "^1.2.1"
+ prosemirror-view "^1.13.3"
+
+prosemirror-trailing-node@^2.0.7:
+ version "2.0.8"
+ resolved "https://registry.yarnpkg.com/prosemirror-trailing-node/-/prosemirror-trailing-node-2.0.8.tgz#233ddcbda72de06f9b5d758d2a65a8cac482ea10"
+ integrity sha512-ujRYhSuhQb1Jsarh1IHqb2KoSnRiD7wAMDGucP35DN7j5af6X7B18PfdPIrbwsPTqIAj0fyOvxbuPsWhNvylmA==
+ dependencies:
+ "@remirror/core-constants" "^2.0.2"
+ escape-string-regexp "^4.0.0"
+
+prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1, prosemirror-transform@^1.7.3, prosemirror-transform@^1.8.0:
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.8.0.tgz#a47c64a3c373c1bd0ff46e95be3210c8dda0cd11"
+ integrity sha512-BaSBsIMv52F1BVVMvOmp1yzD3u65uC3HTzCBQV1WDPqJRQ2LuHKcyfn0jwqodo8sR9vVzMzZyI+Dal5W9E6a9A==
+ dependencies:
+ prosemirror-model "^1.0.0"
+
+prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.27.0, prosemirror-view@^1.31.0, prosemirror-view@^1.32.7:
+ version "1.33.5"
+ resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.33.5.tgz#6b41ad9f3de64d8a836ea9cf9999376586af217c"
+ integrity sha512-AbYYLgg2h5CLARLcTtbNrMARlMwV51jTrezcJkV0NS9J4vi28+rhJ45iIWVSjCcRY209BoySDuJ58b8wIFqdmQ==
+ dependencies:
+ prosemirror-model "^1.20.0"
+ prosemirror-state "^1.0.0"
+ prosemirror-transform "^1.1.0"
+
+punycode.js@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/punycode.js/-/punycode.js-2.3.1.tgz#6b53e56ad75588234e79f4affa90972c7dd8cdb7"
+ integrity sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==
+
punycode@^2.1.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
@@ -3045,6 +3318,11 @@ rollup@^3.18.0:
optionalDependencies:
fsevents "~2.3.2"
+rope-sequence@^1.3.0:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/rope-sequence/-/rope-sequence-1.3.4.tgz#df85711aaecd32f1e756f76e43a415171235d425"
+ integrity sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==
+
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
@@ -3315,6 +3593,13 @@ tinyspy@^2.1.0:
resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-2.1.0.tgz#bd6875098f988728e6456cfd5ab8cc06498ecdeb"
integrity sha512-7eORpyqImoOvkQJCSkL0d0mB4NHHIFAy4b1u8PHdDa7SjGS2njzl6/lyGoZLm+eyYEtlUmFGE0rFj66SWxZgQQ==
+tippy.js@^6.3.7:
+ version "6.3.7"
+ resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c"
+ integrity sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==
+ dependencies:
+ "@popperjs/core" "^2.9.0"
+
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
@@ -3380,6 +3665,11 @@ typescript@^4.9.5:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
+uc.micro@^2.0.0, uc.micro@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee"
+ integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==
+
ufo@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.1.1.tgz#e70265e7152f3aba425bd013d150b2cdf4056d7c"
@@ -3496,6 +3786,11 @@ vitest@^0.30.0:
vite-node "0.30.0"
why-is-node-running "^2.2.2"
+w3c-keyname@^2.2.0:
+ version "2.2.8"
+ resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.8.tgz#7b17c8c6883d4e8b86ac8aba79d39e880f8869c5"
+ integrity sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==
+
well-known-symbols@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/well-known-symbols/-/well-known-symbols-2.0.0.tgz#e9c7c07dbd132b7b84212c8174391ec1f9871ba5"