Compare commits

...

3 Commits

Author SHA1 Message Date
e175d12ca7 fix: fix route conflicts 2022-04-16 02:35:35 +07:00
f2c6d852a9 feat: add auth to tag menus 2022-04-16 02:21:34 +07:00
19e7aea06d feat: revamp with tag editor 2022-04-16 02:20:14 +07:00
28 changed files with 947 additions and 129 deletions

View File

@ -152,6 +152,15 @@ func postCreate(c *gin.Context) {
}
func postUpdate(c *gin.Context) {
_, ok := c.Get("user")
if !ok {
c.JSON(http.StatusForbidden, models.ErrorResponse{
Code: http.StatusBadRequest,
Message: "User don't exist",
})
c.Abort()
}
id := c.Param("id")
var model models.PostUpdateModel
@ -194,6 +203,15 @@ func postUpdate(c *gin.Context) {
}
func postDelete(c *gin.Context) {
_, ok := c.Get("user")
if !ok {
c.JSON(http.StatusForbidden, models.ErrorResponse{
Code: http.StatusBadRequest,
Message: "User don't exist",
})
c.Abort()
}
id := c.Param("id")
err := services.DeletePost(id)

View File

@ -3,15 +3,26 @@ package app
import (
"net/http"
"github.com/Damillora/Shioriko/pkg/middleware"
"github.com/Damillora/Shioriko/pkg/models"
"github.com/Damillora/Shioriko/pkg/services"
"github.com/gin-gonic/gin"
)
func InitializeTagRoutes(g *gin.Engine) {
autocomplete := g.Group("/api/tag-autocomplete")
{
autocomplete.GET("/", tagAutocomplete)
}
unprotected := g.Group("/api/tag")
{
unprotected.GET("/", tagGet)
unprotected.GET("/autocomplete", tagAutocomplete)
unprotected.GET("/:tag", tagGetOne)
}
protected := g.Group("/api/tag").Use(middleware.AuthMiddleware())
{
protected.PUT("/:tag/note", tagUpdateNote)
protected.PUT("/:tag", tagUpdate)
}
}
@ -20,7 +31,95 @@ func tagGet(c *gin.Context) {
c.JSON(http.StatusOK, tags)
}
func tagGetOne(c *gin.Context) {
tag := c.Param("tag")
tagObj, err := services.GetTag(tag)
if err != nil {
c.JSON(http.StatusBadRequest, models.ErrorResponse{
Code: http.StatusBadRequest,
Message: err.Error(),
})
c.Abort()
}
c.JSON(http.StatusOK, models.TagReadModel{
TagID: tagObj.TagID,
TagName: tagObj.TagName,
TagType: tagObj.TagType,
TagNote: tagObj.TagNote,
PostCount: tagObj.PostCount,
})
}
func tagAutocomplete(c *gin.Context) {
tags := services.GetTagAutocomplete()
c.JSON(http.StatusOK, tags)
}
func tagUpdateNote(c *gin.Context) {
_, ok := c.Get("user")
if !ok {
c.JSON(http.StatusForbidden, models.ErrorResponse{
Code: http.StatusBadRequest,
Message: "User don't exist",
})
c.Abort()
}
var model models.TagNoteUpdateModel
err := c.ShouldBindJSON(&model)
if err != nil {
c.JSON(http.StatusBadRequest, models.ErrorResponse{
Code: http.StatusBadRequest,
Message: err.Error(),
})
c.Abort()
return
}
tag := c.Param("tag")
err = services.UpdateTagNotes(tag, model.Note)
if err != nil {
c.JSON(http.StatusBadRequest, models.ErrorResponse{
Code: http.StatusBadRequest,
Message: err.Error(),
})
c.Abort()
}
c.JSON(http.StatusOK, nil)
}
func tagUpdate(c *gin.Context) {
_, ok := c.Get("user")
if !ok {
c.JSON(http.StatusForbidden, models.ErrorResponse{
Code: http.StatusBadRequest,
Message: "User don't exist",
})
c.Abort()
}
var model models.TagUpdateModel
err := c.ShouldBindJSON(&model)
if err != nil {
c.JSON(http.StatusBadRequest, models.ErrorResponse{
Code: http.StatusBadRequest,
Message: err.Error(),
})
c.Abort()
return
}
tag := c.Param("tag")
err = services.UpdateTag(tag, model)
if err != nil {
c.JSON(http.StatusBadRequest, models.ErrorResponse{
Code: http.StatusBadRequest,
Message: err.Error(),
})
c.Abort()
}
c.JSON(http.StatusOK, nil)
}

View File

@ -12,10 +12,12 @@ import (
)
func InitializeTagTypeRoutes(g *gin.Engine) {
unprotected := g.Group(("/api/tagtype"))
{
unprotected.GET("/", tagTypeGet)
}
protected := g.Group("/api/tagtype").Use(middleware.AuthMiddleware())
{
protected.GET("/", tagTypeGet)
protected.POST("/create", tagTypeCreate)
protected.DELETE("/:id", tagTypeDelete)
}

View File

@ -11,5 +11,6 @@ type Tag struct {
UpdatedAt time.Time
TagTypeID uint
TagType TagType
Note string `gorm:"type:text"`
Posts []Post `gorm:"many2many:post_tags"`
}

View File

@ -7,9 +7,10 @@ type UserCreateModel struct {
}
type UserUpdateModel struct {
Email string `json:"email" validate:"required,email"`
Username string `json:"username" validate:"required"`
Password string `json:"password"`
Email string `json:"email" validate:"required,email"`
Username string `json:"username" validate:"required"`
OldPassword string `json:"oldPassword"`
NewPassword string `json:"newPassword"`
}
type TagTypeCreateModel struct {
@ -26,6 +27,9 @@ type TagUpdateModel struct {
TagTypeID uint `json:"tagTypeId" validate:"required"`
}
type TagNoteUpdateModel struct {
Note string `json:"note" validate:"required"`
}
type PostCreateModel struct {
BlobID string `json:"blob_id" validate:"required"`
SourceURL string `json:"source_url"`

View File

@ -10,3 +10,11 @@ type PostReadModel struct {
Height int `json:"height"`
Uploader string `json:"uploader"`
}
type TagReadModel struct {
TagID string `json:"tagId"`
TagName string `json:"tagName"`
TagType string `json:"tagType"`
TagNote string `json:"tagNote"`
PostCount int `json:"postCount"`
}

View File

@ -42,6 +42,24 @@ func GetTagFilter(tagObjs []database.Tag) []models.TagListItem {
Find(&tags, tagIds)
return tags
}
func GetTag(tagString string) (*models.TagReadModel, error) {
tagObj, err := FindTag(tagString)
if err != nil {
return nil, err
}
var tagModel models.TagReadModel
database.DB.Model(&tagObj).
Joins("join tag_types on tag_types.id = tags.tag_type_id").
Joins("left join post_tags on post_tags.tag_id = tags.id").
Select("tags.id as tag_id, tags.name as tag_name, tag_types.name as tag_type, tags.note as tag_note, count(post_tags.post_id) as post_count").
Group("tags.id, tags.name, tag_types.name, tags.note").
First(&tagModel, "tags.id = ? ", tagObj.ID)
return &tagModel, nil
}
func GetTagAutocomplete() []string {
var tags []string
result := database.DB.Model(&database.Tag{}).
@ -134,6 +152,7 @@ func CreateOrUpdateTag(tagSyntax string) (*database.Tag, error) {
return nil, errors.New("Malformed tag syntax")
}
}
func FindTag(tagSyntax string) (*database.Tag, error) {
tagFields := strings.Split(tagSyntax, ":")
var tagName string
@ -173,3 +192,36 @@ func ParseReadTags(tags []string) ([]database.Tag, error) {
}
return result, nil
}
func UpdateTagNotes(tagString string, notes string) error {
tagObj, err := FindTag(tagString)
if err != nil {
return err
}
tagObj.Note = notes
result := database.DB.Save(&tagObj)
if result.Error != nil {
return result.Error
}
return nil
}
func UpdateTag(tagString string, model models.TagUpdateModel) error {
tagObj, err := FindTag(tagString)
if err != nil {
return err
}
tagObj.TagTypeID = model.TagTypeID
tagObj.Name = model.Name
result := database.DB.Save(&tagObj)
if result.Error != nil {
return result.Error
}
return nil
}

View File

@ -50,7 +50,12 @@ func UpdateUser(id string, model models.UserUpdateModel) (*database.User, error)
user.Username = model.Username
if user.Password != "" {
passwd, err := bcrypt.GenerateFromPassword([]byte(model.Password), bcrypt.DefaultCost)
verifyErr := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(model.OldPassword))
if verifyErr != nil {
return nil, verifyErr
}
passwd, err := bcrypt.GenerateFromPassword([]byte(model.NewPassword), bcrypt.DefaultCost)
if err != nil {
return nil, err
}

View File

@ -18,6 +18,9 @@
"svelte": "^3.0.0"
},
"dependencies": {
"@svelte-parts/editor": "^0.0.26",
"@tiptap/core": "^2.0.0-beta.174",
"@tiptap/starter-kit": "^2.0.0-beta.183",
"axios": "^0.21.1",
"bulma": "^0.9.2",
"node-sass": "^6.0.0",

View File

@ -3,15 +3,21 @@
import Navbar from "./Navbar.svelte";
import Home from "./routes/Home.svelte";
import Posts from "./routes/Posts.svelte";
import Post from "./routes/Post.svelte";
import Login from "./routes/Login.svelte";
import Logout from "./routes/Logout.svelte";
import Upload from "./routes/Upload.svelte";
import Edit from "./routes/Edit.svelte";
import Tags from "./routes/Tags.svelte";
import Register from "./routes/Register.svelte";
import Login from "./routes/Auth/Login.svelte";
import Logout from "./routes/Auth/Logout.svelte";
import Register from "./routes/Auth/Register.svelte";
import Posts from "./routes/Post/Posts.svelte";
import Post from "./routes/Post/Post.svelte";
import Upload from "./routes/Post/Upload.svelte";
import Tags from "./routes/Tags/Tags.svelte";
import Tag from "./routes/Tags/Tag.svelte";
import Profile from "./routes/User/Profile.svelte";
export let url = "";
let baseURL = window.BASE_URL;
@ -23,12 +29,13 @@
<Route path="/" component={Home} />
<Route path="/posts" component={Posts} />
<Route path="/post/:id" component={Post} />
<Route path="/post/edit/:id" component={Edit} />
<Route path="/auth/login" component={Login} />
<Route path="/auth/logout" component={Logout} />
<Route path="/upload" component={Upload} />
<Route path="/tags" component={Tags} />
<Route path="/tags/:tag" component={Tag} />
<Route path="/auth/register" component={Register} />
<Route path="/user/profile" component={Profile} />
</div>
</Router>

View File

@ -46,6 +46,9 @@
{#if loggedIn}
<div class="navbar-item">
<div class="buttons">
<Link to="/user/profile" class="button is-primary">
Profile
</Link>
<Link to="/auth/logout" class="button is-light">
Log out
</Link>

View File

@ -41,8 +41,15 @@ export async function getTags() {
const response = await axios.get(endpoint);
return response.data;
}
export async function getTag({ tag }) {
const endpoint = url + "/api/tag/" + tag;
const response = await axios.get(endpoint);
return response.data;
}
export async function getTagAutocomplete() {
const endpoint = url + "/api/tag/autocomplete";
const endpoint = url + "/api/tag-autocomplete";
const response = await axios.get(endpoint);
return response.data;
}
@ -123,6 +130,7 @@ export async function postUpdate(id, { source_url, tags }) {
})
return response.data;
}
export async function postDelete({ id }) {
const endpoint = url + "/api/post/" + id;
const response = await axios({
@ -134,4 +142,57 @@ export async function postDelete({ id }) {
withCredentials: true,
})
return response.status == 200;
}
export async function getUserProfile() {
const endpoint = url + "/api/user/profile";
const response = await axios({
url: endpoint,
method: "GET",
headers: {
'Authorization': 'Bearer ' + current_token,
},
withCredentials: true,
});
console.log(response.data);
return response.data;
}
export async function updateTagNotes(id, { note }) {
const endpoint = url + "/api/tag/" + id + "/note";
const response = await axios({
url: endpoint,
method: "PUT",
headers: {
'Authorization': 'Bearer ' + current_token,
},
withCredentials: true,
data: {
note
}
})
return response.data;
}
export async function updateTag(id, { name, tagTypeId }) {
const endpoint = url + "/api/tag/" + id;
const response = await axios({
url: endpoint,
method: "PUT",
headers: {
'Authorization': 'Bearer ' + current_token,
},
withCredentials: true,
data: {
name, tagTypeId
}
})
return response.data;
}
export async function getTagTypes() {
const endpoint = url + "/api/tagtype";
const response = await axios.get(endpoint);
return response.data;
}

View File

@ -0,0 +1,94 @@
<script>
import { onMount } from "svelte";
import { Link, navigate } from "svelte-routing";
import { getTagTypes, updateTag } from "../../api";
export let tag;
export let data;
export let toggleRenameMenu;
export let onSubmit;
let tagTypes = [];
let form = {
name: "",
tagTypeId: 1,
};
const getData = async () => {
tagTypes = await getTagTypes();
form.name = data.tagName;
let tagType = tagTypes.filter((x) => x.name == data.tagType);
form.tagTypeId = tagType[0].id;
};
const onFormSubmit = async () => {
await updateTag(tag, form);
navigate("/tags/"+form.name);
toggleRenameMenu();
onSubmit(form.name);
};
onMount(() => {
getData();
});
</script>
<form on:submit|preventDefault={onFormSubmit}>
<div class="panel is-warning">
<p class="panel-heading">Edit Tag</p>
<div class="panel-block column">
<div class="row">
<strong>Name:</strong>
</div>
<div class="row">
<div class="field">
<div class="control">
<input
class="input"
type="text"
bind:value={form.name}
/>
</div>
</div>
</div>
</div>
<div class="panel-block column">
<div class="row">
<strong>Category:</strong>
</div>
<div class="row">
<div class="field">
<div class="select">
<select bind:value={form.tagTypeId}>
{#each tagTypes as tagType}
<option
value={tagType.id}
selected={form.tagTypeId === tagType.id}
>
{tagType.name}
</option>
{/each}
</select>
</div>
</div>
</div>
</div>
<div class="panel-block column">
<div class="row">
<strong>Posts:</strong>
</div>
<div class="row">
{data.postCount} (<Link to="/posts?tags={tag}">Browse</Link>)
</div>
</div>
<div class="panel-block column">
<button class="button is-primary" type="submit">Submit</button>
<button on:click|preventDefault={toggleRenameMenu} class="button"
>Cancel</button
>
</div>
</div>
</form>

View File

@ -0,0 +1,40 @@
<script>
import { Link } from "svelte-routing";
import AuthCheck from "../../AuthCheck.svelte";
export let tag;
export let data;
export let toggleRenameMenu;
</script>
<div class="panel is-primary">
<p class="panel-heading">Tag</p>
<div class="panel-block column">
<div class="row">
<strong>Name:</strong>
</div>
<div class="row">{data.tagName}</div>
</div>
<div class="panel-block column">
<div class="row">
<strong>Category:</strong>
</div>
<div class="row">{data.tagType}</div>
</div>
<div class="panel-block column">
<div class="row">
<strong>Posts:</strong>
</div>
<div class="row">
{data.postCount} (<Link to="/posts?tags={tag}">Browse</Link>)
</div>
</div>
<AuthCheck>
<div class="panel-block column">
<button
on:click|preventDefault={toggleRenameMenu}
class="button is-primary">Rename</button
>
</div>
</AuthCheck>
</div>

View File

@ -0,0 +1,47 @@
<script>
import { onMount } from "svelte";
import { updateTagNotes } from "../../api";
export let tag;
export let data;
export let toggleEditMenu;
export let onSubmit;
let form = {
note: "",
};
const getData = async () => {
form.note = data.tagNote;
};
const onFormSubmit = async () => {
await updateTagNotes(tag, form);
toggleEditMenu();
onSubmit();
};
onMount(() => {
getData();
});
</script>
<form on:submit|preventDefault={onFormSubmit}>
<div class="panel is-warning">
<p class="panel-heading">Edit Notes</p>
<div class="panel-block column">
<textarea
bind:value={form.note}
class="textarea has-fixed-size"
/>
<div class="content" />
</div>
<div class="panel-block column">
<button type="submit" class="button is-primary">Save</button>
<button on:click|preventDefault={toggleEditMenu} class="button"
>Cancel</button
>
</div>
</div>
</form>

View File

@ -0,0 +1,29 @@
<script>
import AuthCheck from "../../AuthCheck.svelte";
export let data;
export let toggleEditMenu;
</script>
<div class="panel is-info">
<p class="panel-heading">Notes</p>
<div class="panel-block column">
<div class="content pre-line">
{data.tagNote}
</div>
</div>
<AuthCheck>
<div class="panel-block column">
<button
on:click|preventDefault={toggleEditMenu}
class="button is-primary">Edit</button
>
</div>
</AuthCheck>
</div>
<style>
.pre-line {
white-space: pre-line;
}
</style>

View File

@ -6,6 +6,7 @@
@import '../node_modules/bulma/sass/grid/_all';
@import '../node_modules/bulma/sass/helpers/_all';
@import '../node_modules/bulma/sass/layout/_all';
@import '../node_modules/bytemd/dist/index.css';
.tile.is-multiline {
flex-wrap: wrap;

View File

@ -1,5 +1,5 @@
<script>
import { login } from "../api.js";
import { login } from "../../api.js";
import { navigate } from "svelte-routing";
let username = "";

View File

@ -1,5 +1,5 @@
<script>
import { token } from "../stores.js";
import { token } from "../../stores.js";
import { navigate } from "svelte-routing";
import { onMount } from "svelte";

View File

@ -1,5 +1,5 @@
<script>
import { register } from "../api.js";
import { register } from "../../api.js";
import { navigate } from "svelte-routing";
let username = "";

View File

@ -1,97 +0,0 @@
<script>
import { getPost, postUpdate, getTagAutocomplete } from "../api.js";
import { navigate } from "svelte-routing";
import Tags from "svelte-tags-input";
import { onMount } from "svelte";
import { Link } from "svelte-routing";
import AuthRequired from "../AuthRequired.svelte";
export let id;
let image_path = "";
let form = {
source_url: "",
tags: [],
};
const getData = async () => {
const data = await getPost({ id });
form.source_url = data.source_url;
form.tags = data.tags;
image_path = data.image_path;
};
const onTagChange = (value) => {
form.tags = value.detail.tags;
};
const onAutocomplete = async () => {
const list = await getTagAutocomplete();
return list;
};
const onSubmit = async () => {
const response = await postUpdate(id, form);
navigate(`/post/${response.id}`);
};
onMount(() => {
getData();
});
</script>
<AuthRequired />
<section class="hero is-primary">
<div class="hero-body">
<p class="title">Edit Post: {id}</p>
</div>
</section>
<div class="container">
<section class="section">
<div class="columns">
<div class="column is-one-third box">
<p>
<Link class="button is-primary" to="/post/{id}">Back</Link>
</p>
<form on:submit|preventDefault={onSubmit}>
<div class="field">
<label for="source" class="label">Source URL</label>
<div class="control">
<input
id="source"
class="input"
type="url"
placeholder="Source URL"
bind:value={form.source_url}
/>
</div>
</div>
<div class="field">
<label for="tags" class="label">Tags</label>
<div class="control" id="tags">
<Tags
tags={form.tags}
addKeys={[9, 32]}
on:tags={onTagChange}
autoComplete={onAutocomplete}
/>
</div>
</div>
<div class="control">
<button type="submit" class="button is-primary"
>Submit</button
>
</div>
</form>
</div>
<div class="column">
<figure class="image">
<img alt={id} src={image_path} />
</figure>
</div>
</div>
</section>
</div>

View File

@ -1,9 +1,9 @@
<script>
import { onMount } from "svelte";
import { getPost, postDelete } from "../api.js";
import { getPost, postDelete } from "../../api.js";
import { navigate } from "svelte-routing";
import EditPostPanel from "../EditPostPanel.svelte";
import ViewPostPanel from "../ViewPostPanel.svelte";
import EditPostPanel from "../../EditPostPanel.svelte";
import ViewPostPanel from "../../ViewPostPanel.svelte";
export let id;
let post;
const getData = async () => {

View File

@ -1,12 +1,10 @@
<script>
import { onMount } from "svelte";
import { getPostSearchTag, getTagAutocomplete } from "../api.js";
import { getPostSearchTag, getTagAutocomplete } from "../../api.js";
import { Link, navigate } from "svelte-routing";
import TagLinkNumbered from "../TagLinkNumbered.svelte";
import TagLinkNumbered from "../../TagLinkNumbered.svelte";
import queryString from "query-string";
import Tags from "svelte-tags-input";
import { add_attribute } from "svelte/internal";
import { paginate } from "../simple-pagination.js";
import { paginate } from "../../simple-pagination.js";
export let location;

View File

@ -1,8 +1,8 @@
<script>
import { uploadBlob, postCreate, getTagAutocomplete } from "../api.js";
import { uploadBlob, postCreate, getTagAutocomplete } from "../../api.js";
import { navigate, Link } from "svelte-routing";
import Tags from "svelte-tags-input";
import AuthRequired from "../AuthRequired.svelte";
import AuthRequired from "../../AuthRequired.svelte";
let currentProgress = 0;

View File

@ -0,0 +1,70 @@
<script>
import { onMount } from "svelte";
import { getTag } from "../../api";
import EditTagNotesPanel from "../../components/TagNotes/EditTagNotesPanel.svelte";
import ViewTagNotesPanel from "../../components/TagNotes/ViewTagNotesPanel.svelte";
import ViewTagPanel from "../../components/Tag/ViewTagPanel.svelte";
import EditTagPanel from "../../components/Tag/EditTagPanel.svelte";
export let tag;
let data;
const getData = async () => {
if (tag) {
data = await getTag({ tag });
}
};
let renameMenuShown = false;
const toggleRenameMenu = () => {
renameMenuShown = !renameMenuShown;
};
let editMenuShown = false;
const toggleEditMenu = () => {
editMenuShown = !editMenuShown;
};
const onTagSubmit = (newName) => {
tag = newName;
getData();
};
onMount(() => {
getData();
});
</script>
<section class="section">
<div class="container">
{#if data}
<div class="columns">
<div class="column is-one-third">
{#if renameMenuShown}
<EditTagPanel
{tag}
{data}
{toggleRenameMenu}
onSubmit={onTagSubmit}
/>
{:else}
<ViewTagPanel {tag} {data} {toggleRenameMenu} />
{/if}
</div>
<div class="column is-two-thirds">
{#if editMenuShown}
<EditTagNotesPanel
{tag}
{data}
{toggleEditMenu}
onSubmit={getData}
/>
{:else}
<ViewTagNotesPanel {data} {toggleEditMenu} />
{/if}
</div>
</div>
{/if}
</div>
</section>

View File

@ -1,5 +1,5 @@
<script>
import { getTags } from "../api";
import { getTags } from "../../api";
import { Link } from "svelte-routing";
let tags = [];
@ -29,7 +29,7 @@
{#each tags as tag}
<tr>
<td>
<Link to="/posts?tags={tag.tagType}:{tag.tagName}">{tag.tagName}</Link>
<Link to="/tags/{tag.tagName}">{tag.tagName}</Link>
</td>
<td>{tag.tagType}</td>
<td>{tag.postCount}</td>

View File

@ -0,0 +1,26 @@
<script>
import { onMount } from "svelte";
import { getUserProfile } from "../../api.js";
import AuthRequired from "../../AuthRequired.svelte";
let user;
const getData = async () => {
user = await getUserProfile();
};
onMount(() => {
getData();
});
</script>
<AuthRequired />
<section class="section">
<div class="container">
{#if user}
<h1 class="title">Welcome, {user.username}</h1>
<p>Email: {user.email}</p>
<p>Username: {user.username}</p>
{/if}
</div>
</section>

View File

@ -70,6 +70,161 @@
estree-walker "^1.0.1"
picomatch "^2.2.2"
"@svelte-parts/editor@^0.0.26":
version "0.0.26"
resolved "https://registry.yarnpkg.com/@svelte-parts/editor/-/editor-0.0.26.tgz#321923306dc0c2734839e08e4d54f9e4e89d6ff5"
integrity sha512-5VyzZG9RrkawjVAG5QHCqRcFY1Tn5am1W+whRH+EYVjPJTqJho5rYaTE0+f3cIpcNAkfHMd3lFyIWccoW2gBAQ==
dependencies:
codemirror "^5.58.2"
"@tiptap/core@^2.0.0-beta.174":
version "2.0.0-beta.174"
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.174.tgz#cfdf16b7d7401e4b255dc69147d784f5f537b942"
integrity sha512-APQDto40PdvagG1HTwkKlieQS4Vp6GXNe7qgV1Qo2QCgJCLyxc/fXCTghtrOx0CQb+9JT7fjSLZxbSyUFXjx7Q==
dependencies:
"@types/prosemirror-commands" "^1.0.4"
"@types/prosemirror-keymap" "^1.0.4"
"@types/prosemirror-model" "^1.16.0"
"@types/prosemirror-schema-list" "^1.0.3"
"@types/prosemirror-state" "^1.2.8"
"@types/prosemirror-transform" "^1.1.5"
"@types/prosemirror-view" "^1.23.1"
prosemirror-commands "^1.2.1"
prosemirror-keymap "^1.1.5"
prosemirror-model "^1.16.1"
prosemirror-schema-list "^1.1.6"
prosemirror-state "^1.3.4"
prosemirror-transform "^1.3.3"
prosemirror-view "^1.23.6"
"@tiptap/extension-blockquote@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.0.0-beta.26.tgz#e5ae4b7bd9376db37407a23e22080c7b11287f3b"
integrity sha512-A6yjcYovONJfOjQFk6vDYXswaCdCtCwjL7w9VTB0R2DLTuJvvRt9DWN0IDcMrj5G+aMgDq4GUUTitv+2Y8krDg==
"@tiptap/extension-bold@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.26.tgz#aa1c7850df28cec8e0614fde437183bd4ae3e66b"
integrity sha512-pnO0I5sEQM3pmowjMGQ74adLzvc6HqGyLyqMizaGMicPu9uTYlSdId+qckYEEgPwPMaEShtv2Vg+ZHs7KVqfcg==
"@tiptap/extension-bullet-list@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.0-beta.26.tgz#b42126d2d984c04041b14037e8d3ec1bcf16e7ec"
integrity sha512-1n5HV8gY1tLjPk4x48nva6SZlFHoPlRfF6pqSu9JcJxPO7FUSPxUokuz4swYNe0LRrtykfyNz44dUcxKVhoFow==
"@tiptap/extension-code-block@^2.0.0-beta.37":
version "2.0.0-beta.37"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.0.0-beta.37.tgz#c07c007248a21d9e0434458fd05c363b7078227f"
integrity sha512-mJAM+PHaNoKRYwM3D36lZ51/aoPxxvZNQn3UBnZ6G7l0ZJSgB3JvBEzqK6S8nNFeYIIxGwv4QF6vXe4MG9ie2g==
dependencies:
prosemirror-state "^1.3.4"
"@tiptap/extension-code@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.0.0-beta.26.tgz#bbfa600a252ee2cded6947b56b6c4c33d998e53a"
integrity sha512-QcFWdEFfbJ1n5UFFBD17QPPAJ3J5p/b7XV484u0shCzywO7aNPV32QeHy1z0eMoyZtCbOWf6hg/a7Ugv8IwpHw==
"@tiptap/extension-document@^2.0.0-beta.15":
version "2.0.0-beta.15"
resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.0.0-beta.15.tgz#5d17a0289244a913ab2ef08e8495a1e46950711e"
integrity sha512-ypENC+xUYD5m2t+KOKNYqyXnanXd5fxyIyhR1qeEEwwQwMXGNrO3kCH6O4mIDCpy+/WqHvVay2tV5dVsXnvY8w==
"@tiptap/extension-dropcursor@^2.0.0-beta.25":
version "2.0.0-beta.25"
resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.0.0-beta.25.tgz#962f290a200259533a26194daca5a4b4a53e72d3"
integrity sha512-GYf5s6dkZtsDy+TEkrQK6kLbfbitG4qnk02D+FlhlJMI/Nnx8rYCRJbwEHDdqrfX7XwZzULMqqqHvzxZYrEeNg==
dependencies:
"@types/prosemirror-dropcursor" "^1.0.3"
prosemirror-dropcursor "^1.4.0"
"@tiptap/extension-gapcursor@^2.0.0-beta.34":
version "2.0.0-beta.34"
resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.0-beta.34.tgz#0e4971affb1621934422dd5fc4bf2dd7a84f70f7"
integrity sha512-Vm8vMWWQ2kJcUOLfB5CEo5pYgyudI7JeeiZvX9ScPmUmgKVYhEpt3EAICY9pUYJ41aAVH35gZLXkUtsz2f9GHw==
dependencies:
"@types/prosemirror-gapcursor" "^1.0.4"
prosemirror-gapcursor "^1.2.1"
"@tiptap/extension-hard-break@^2.0.0-beta.30":
version "2.0.0-beta.30"
resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.0.0-beta.30.tgz#165494f1194a7bad08907e6d64d349dd15851b72"
integrity sha512-X9xj/S+CikrbIE7ccUFVwit5QHEbflnKVxod+4zPwr1cxogFbE9AyLZE2MpYdx3z9LcnTYYi9leBqFrP4T/Olw==
"@tiptap/extension-heading@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.0.0-beta.26.tgz#112b14b4d488772bda36abbf7cb2bc8aba7c42f5"
integrity sha512-nR6W/3rjnZH1Swo7tGBoYsmO6xMvu9MGq6jlm3WVHCB7B3CsrRvCkTwGjVIbKTaZC4bQfx5gvAUpQFvwuU+M5w==
"@tiptap/extension-history@^2.0.0-beta.21":
version "2.0.0-beta.21"
resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.0.0-beta.21.tgz#5d96a17a83a7130744f0757a3275dd5b11eb1bf7"
integrity sha512-0v8Cl30V4dsabdpspLdk+f+lMoIvLFlJN5WRxtc7RRZ5gfJVxPHwooIKdvC51brfh/oJtWFCNMRjhoz0fRaF9A==
dependencies:
"@types/prosemirror-history" "^1.0.3"
prosemirror-history "^1.2.0"
"@tiptap/extension-horizontal-rule@^2.0.0-beta.31":
version "2.0.0-beta.31"
resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.0.0-beta.31.tgz#efb383a6cedbbf4f2175d7d207eaeeba626faab0"
integrity sha512-MNc4retfjRgkv3qxqGya0+/BEd1Kmn+oMsCRvE+8x3sXyKIse+vdqMuG5qUcA6np0ZD/9hh1riiQ1GQdgc23Ng==
dependencies:
prosemirror-state "^1.3.4"
"@tiptap/extension-italic@^2.0.0-beta.26":
version "2.0.0-beta.26"
resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.26.tgz#b00c9e32b81b1bd94eaed24bb2a22e44d5dc54a3"
integrity sha512-vejGe2ra4K5ipFOn1U9viqF9X9nPTX8WSJpSOux+9UbKjHpANy7bz69tp66OIi/Wh5L/MMDc+luH/04qfVnpZw==
"@tiptap/extension-list-item@^2.0.0-beta.20":
version "2.0.0-beta.20"
resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.0.0-beta.20.tgz#7169528b226dee4590e013bdf6e5fc6d83729b0f"
integrity sha512-5IPEspJt38t9ROj4xLUesOVEYlTT/R9Skd9meHRxJQZX1qrzBICs5PC/WRIsnexrvTBhdxpYgCYjpvpsJBlKuQ==
"@tiptap/extension-ordered-list@^2.0.0-beta.27":
version "2.0.0-beta.27"
resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.0-beta.27.tgz#ed48a53a9b012d578613b68375db31e8664bfdc9"
integrity sha512-apFDeignxdZb3cA3p1HJu0zw1JgJdBYUBz1r7f99qdNybYuk3I/1MPUvlOuOgvIrBB/wydoyVDP+v9F7QN3tfQ==
"@tiptap/extension-paragraph@^2.0.0-beta.23":
version "2.0.0-beta.23"
resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.0.0-beta.23.tgz#2ab77308519494994d7a9e5a4acd14042f45f28c"
integrity sha512-VWAxyzecErYWk97Kv/Gkghh97zAQTcaVOisEnYYArZAlyYDaYM48qVssAC/vnRRynP2eQxb1EkppbAxE+bMHAA==
"@tiptap/extension-strike@^2.0.0-beta.27":
version "2.0.0-beta.27"
resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.0.0-beta.27.tgz#c5187bf3c28837f95a5c0c0617d0dd31c318353d"
integrity sha512-2dmCgtesuDdivM/54Q+Y6Tc3JbGz1SkHP6c62piuqBiYLWg3xa16zChZOhfN8szbbQlBgLT6XRTDt3c2Ux+Dug==
"@tiptap/extension-text@^2.0.0-beta.15":
version "2.0.0-beta.15"
resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.0.0-beta.15.tgz#f08cff1b78f1c6996464dfba1fef8ec1e107617f"
integrity sha512-S3j2+HyV2gsXZP8Wg/HA+YVXQsZ3nrXgBM9HmGAxB0ESOO50l7LWfip0f3qcw1oRlh5H3iLPkA6/f7clD2/TFA==
"@tiptap/starter-kit@^2.0.0-beta.183":
version "2.0.0-beta.183"
resolved "https://registry.yarnpkg.com/@tiptap/starter-kit/-/starter-kit-2.0.0-beta.183.tgz#35ff9f4b236bd321ffdd44c5061514959c1b4b9d"
integrity sha512-Lcms6lEfFfdL1oHoATcNKfu1C8+yhuZnI5Pq+U6o2zSslfnUSDf3jgmy6nSoZrrkqvFoXjQk4dxMDFg3giw2Kg==
dependencies:
"@tiptap/core" "^2.0.0-beta.174"
"@tiptap/extension-blockquote" "^2.0.0-beta.26"
"@tiptap/extension-bold" "^2.0.0-beta.26"
"@tiptap/extension-bullet-list" "^2.0.0-beta.26"
"@tiptap/extension-code" "^2.0.0-beta.26"
"@tiptap/extension-code-block" "^2.0.0-beta.37"
"@tiptap/extension-document" "^2.0.0-beta.15"
"@tiptap/extension-dropcursor" "^2.0.0-beta.25"
"@tiptap/extension-gapcursor" "^2.0.0-beta.34"
"@tiptap/extension-hard-break" "^2.0.0-beta.30"
"@tiptap/extension-heading" "^2.0.0-beta.26"
"@tiptap/extension-history" "^2.0.0-beta.21"
"@tiptap/extension-horizontal-rule" "^2.0.0-beta.31"
"@tiptap/extension-italic" "^2.0.0-beta.26"
"@tiptap/extension-list-item" "^2.0.0-beta.20"
"@tiptap/extension-ordered-list" "^2.0.0-beta.27"
"@tiptap/extension-paragraph" "^2.0.0-beta.23"
"@tiptap/extension-strike" "^2.0.0-beta.27"
"@tiptap/extension-text" "^2.0.0-beta.15"
"@types/estree@*":
version "0.0.47"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.47.tgz#d7a51db20f0650efec24cd04994f523d93172ed4"
@ -85,6 +240,94 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.0.2.tgz#51e9c0920d1b45936ea04341aa3e2e58d339fb67"
integrity sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA==
"@types/orderedmap@*":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/orderedmap/-/orderedmap-1.0.0.tgz#807455a192bba52cbbb4517044bc82bdbfa8c596"
integrity sha512-dxKo80TqYx3YtBipHwA/SdFmMMyLCnP+5mkEqN0eMjcTBzHkiiX0ES118DsjDBjvD+zeSsSU9jULTZ+frog+Gw==
"@types/prosemirror-commands@*", "@types/prosemirror-commands@^1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/prosemirror-commands/-/prosemirror-commands-1.0.4.tgz#d08551415127d93ae62e7239d30db0b5e7208e22"
integrity sha512-utDNYB3EXLjAfYIcRWJe6pn3kcQ5kG4RijbT/0Y/TFOm6yhvYS/D9eJVnijdg9LDjykapcezchxGRqFD5LcyaQ==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-view" "*"
"@types/prosemirror-dropcursor@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@types/prosemirror-dropcursor/-/prosemirror-dropcursor-1.0.3.tgz#49250849b8a0b86e8c29eb1ba70a463e53e46947"
integrity sha512-b0/8njnJ4lwyHKcGuCMf3x7r1KjxyugB1R/c2iMCjplsJHSC7UY9+OysqgJR5uUXRekUSGniiLgBtac/lvH6wg==
dependencies:
"@types/prosemirror-state" "*"
"@types/prosemirror-gapcursor@^1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/prosemirror-gapcursor/-/prosemirror-gapcursor-1.0.4.tgz#7df7d373edb33ea8da12084bfd462cf84cd69761"
integrity sha512-9xKjFIG5947dzerFvkLWp6F53JwrUYoYwh3SgcTFEp8SbSfNNrez/PFYVZKPnoqPoaK5WtTdQTaMwpCV9rXQIg==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-history@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@types/prosemirror-history/-/prosemirror-history-1.0.3.tgz#f1110efbe758129b5475e466ff077f0a8d9b964f"
integrity sha512-5TloMDRavgLjOAKXp1Li8u0xcsspzbT1Cm9F2pwHOkgvQOz1jWQb2VIXO7RVNsFjLBZdIXlyfSLivro3DuMWXg==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-keymap@^1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/prosemirror-keymap/-/prosemirror-keymap-1.0.4.tgz#f73c79810e8d0e0a20d153d84f998f02e5afbc0c"
integrity sha512-ycevwkqUh+jEQtPwqO7sWGcm+Sybmhu8MpBsM8DlO3+YTKnXbKA6SDz/+q14q1wK3UA8lHJyfR+v+GPxfUSemg==
dependencies:
"@types/prosemirror-commands" "*"
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-view" "*"
"@types/prosemirror-model@*", "@types/prosemirror-model@^1.16.0":
version "1.16.1"
resolved "https://registry.yarnpkg.com/@types/prosemirror-model/-/prosemirror-model-1.16.1.tgz#0ce6c80cd81b398b8a11b1bf7cf695bff3160c9a"
integrity sha512-SrrCe2cHlYrQ9o55e2i/c3wt1yRajTTpRLvzfmB+2DWjWEbBLTByVWyjrdpKtQTxAaTeU2aeDGo1iuwl/jF27w==
dependencies:
"@types/orderedmap" "*"
"@types/prosemirror-schema-list@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@types/prosemirror-schema-list/-/prosemirror-schema-list-1.0.3.tgz#bdf1893a7915fbdc5c49b3cac9368e96213d70de"
integrity sha512-uWybOf+M2Ea7rlbs0yLsS4YJYNGXYtn4N+w8HCw3Vvfl6wBAROzlMt0gV/D/VW/7J/LlAjwMezuGe8xi24HzXA==
dependencies:
"@types/orderedmap" "*"
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-state@*", "@types/prosemirror-state@^1.2.8":
version "1.2.8"
resolved "https://registry.yarnpkg.com/@types/prosemirror-state/-/prosemirror-state-1.2.8.tgz#65080eeec52f63c50bf7034377f07773b4f6b2ac"
integrity sha512-mq9uyQWcpu8jeamO6Callrdvf/e1H/aRLR2kZWSpZrPHctEsxWHBbluD/wqVjXBRIOoMHLf6ZvOkrkmGLoCHVA==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-transform" "*"
"@types/prosemirror-view" "*"
"@types/prosemirror-transform@*", "@types/prosemirror-transform@^1.1.5":
version "1.1.6"
resolved "https://registry.yarnpkg.com/@types/prosemirror-transform/-/prosemirror-transform-1.1.6.tgz#4a06979f656331c46c2725039a57360cc35853af"
integrity sha512-7HwXOWc5vZQqIfEUUVAz13lPgBqAWJTv89qEpzAtBFB6hOszFmhsvQ02Jqe2LvKauAoJDa3Qpv/dbJAmgyiTuQ==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-view@*", "@types/prosemirror-view@^1.23.1":
version "1.23.1"
resolved "https://registry.yarnpkg.com/@types/prosemirror-view/-/prosemirror-view-1.23.1.tgz#a9a926bb6b6e6873e3a9d8caa61c32f3402629eb"
integrity sha512-6e1B2oKUnhmZPUrsVvYjDqeVjE6jGezygjtoHsAK4ZENAxHzHqy5NT4jUvdPTWjCYeH0t2Y7pSfRPNrPIyQX4A==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-transform" "*"
"@types/pug@^2.0.4":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@types/pug/-/pug-2.0.4.tgz#8772fcd0418e3cd2cc171555d73007415051f4b2"
@ -345,6 +588,11 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codemirror@^5.58.2:
version "5.65.2"
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.65.2.tgz#5799a70cb3d706e10f60e267245e3a75205d3dd9"
integrity sha512-SZM4Zq7XEC8Fhroqe3LxbEEX1zUPWH1wMr5zxiBuiUF64iYOUH/JI88v4tBag8MiBS8B8gRv8O1pPXGYXQ4ErA==
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@ -1171,6 +1419,11 @@ once@^1.3.0:
resolved "https://registry.yarnpkg.com/opts/-/opts-2.0.2.tgz#a17e189fbbfee171da559edd8a42423bc5993ce1"
integrity sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg==
orderedmap@^1.1.0:
version "1.1.5"
resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-1.1.5.tgz#4174c90b61bd7c25294932edf789f3b5677744d0"
integrity sha512-/fzlCGKRmfayGoI9UUXvJfc2nMZlJHW30QqEvwPvlg8tsX7jyiUSomYie6mYqx7Z9bOMGoag0H/q1PS/0PjYkg==
p-limit@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
@ -1282,6 +1535,90 @@ process-nextick-args@~2.0.0:
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
prosemirror-commands@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.2.2.tgz#1bd167372ee20abf488aca9cece63c43fab182c9"
integrity sha512-TX+KpWudMon06frryfpO/u7hsQv2hu8L4VSVbCpi3/7wXHBgl+35mV85qfa3RpT8xD2f3MdeoTqH0vy5JdbXPg==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-state "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-dropcursor@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.4.0.tgz#91a859d4ee79c99b1c0ba6ee61c093b195c0d9f0"
integrity sha512-6+YwTjmqDwlA/Dm+5wK67ezgqgjA/MhSDgaNxKUzH97SmeuWFXyLeDRxxOPZeSo7yTxcDGUCWTEjmQZsVBuMrQ==
dependencies:
prosemirror-state "^1.0.0"
prosemirror-transform "^1.1.0"
prosemirror-view "^1.1.0"
prosemirror-gapcursor@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.2.2.tgz#7394613ba4a1601fad1f36f1cff8961968c22ffa"
integrity sha512-7YzuRBbu9W7HGQde84kCHfIjaRLNcAdeijbgqrm/R9dsdTWkV+rrdcmic/sCc+bptiNpvjCEE+R6hrbT8zFQeQ==
dependencies:
prosemirror-keymap "^1.0.0"
prosemirror-model "^1.0.0"
prosemirror-state "^1.0.0"
prosemirror-view "^1.0.0"
prosemirror-history@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.2.0.tgz#04cc4df8d2f7b2a46651a2780de191ada6d465ea"
integrity sha512-B9v9xtf4fYbKxQwIr+3wtTDNLDZcmMMmGiI3TAPShnUzvo+Rmv1GiUrsQChY1meetHl7rhML2cppF3FTs7f7UQ==
dependencies:
prosemirror-state "^1.2.2"
prosemirror-transform "^1.0.0"
rope-sequence "^1.3.0"
prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.1.5.tgz#b5984c7d30f5c75956c853126c54e9e624c0327b"
integrity sha512-8SZgPH3K+GLsHL2wKuwBD9rxhsbnVBTwpHCO4VUO5GmqUQlxd/2GtBVWTsyLq4Dp3N9nGgPd3+lZFKUDuVp+Vw==
dependencies:
prosemirror-state "^1.0.0"
w3c-keyname "^2.2.0"
prosemirror-model@^1.0.0, prosemirror-model@^1.16.0, prosemirror-model@^1.16.1:
version "1.16.1"
resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.16.1.tgz#fb388270bc9609b66298d6a7e15d0cc1d6c61253"
integrity sha512-r1/w0HDU40TtkXp0DyKBnFPYwd8FSlUSJmGCGFv4DeynfeSlyQF2FD0RQbVEMOe6P3PpUSXM6LZBV7W/YNZ4mA==
dependencies:
orderedmap "^1.1.0"
prosemirror-schema-list@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.1.6.tgz#c3e13fe2f74750e4a53ff88d798dc0c4ccca6707"
integrity sha512-aFGEdaCWmJzouZ8DwedmvSsL50JpRkqhQ6tcpThwJONVVmCgI36LJHtoQ4VGZbusMavaBhXXr33zyD2IVsTlkw==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.3.4.tgz#4c6b52628216e753fc901c6d2bfd84ce109e8952"
integrity sha512-Xkkrpd1y/TQ6HKzN3agsQIGRcLckUMA9u3j207L04mt8ToRgpGeyhbVv0HI7omDORIBHjR29b7AwlATFFf2GLA==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-transform "^1.0.0"
prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.3.3:
version "1.4.2"
resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.4.2.tgz#35f56091bcab3359f1eb90e82ce9f20cc52105c1"
integrity sha512-bcIsf3uRZhfab0xRfyyxOEh6eqSszq/hJbDbmUumFnbHBoWhB/uXbpz6vvUxfk0XiEvrZDJ+5pXRrNDc1Hu3vQ==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.23.6:
version "1.23.12"
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.23.12.tgz#196436a964abbd25a7d8efad879575e80d286ba6"
integrity sha512-uvw9ZVz5dNDD9w1bzHkU2r4NWFlpFz85v9rCD8NAhQBau6LYhwM/crjry+C4JgeR8gy6pMXS5eJ1zhNLcK4ctQ==
dependencies:
prosemirror-model "^1.16.0"
prosemirror-state "^1.0.0"
prosemirror-transform "^1.1.0"
psl@^1.1.28:
version "1.8.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
@ -1468,6 +1805,11 @@ rollup@^2.3.4:
optionalDependencies:
fsevents "~2.3.1"
rope-sequence@^1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/rope-sequence/-/rope-sequence-1.3.2.tgz#a19e02d72991ca71feb6b5f8a91154e48e3c098b"
integrity sha512-ku6MFrwEVSVmXLvy3dYph3LAMNS0890K7fabn+0YIRQ2T96T9F4gkFf0vf0WW0JUraNWwGRtInEpH7yO4tbQZg==
sade@^1.6.0:
version "1.7.4"
resolved "https://registry.yarnpkg.com/sade/-/sade-1.7.4.tgz#ea681e0c65d248d2095c90578c03ca0bb1b54691"
@ -1910,6 +2252,11 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
w3c-keyname@^2.2.0:
version "2.2.4"
resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.4.tgz#4ade6916f6290224cdbd1db8ac49eab03d0eef6b"
integrity sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==
which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"