From d12a2b0c38ab056a22c969954b6c757dcb09c0ff Mon Sep 17 00:00:00 2001 From: Steven Date: Thu, 4 Jan 2024 20:05:29 +0800 Subject: [PATCH] feat: implement math expression parser --- api/v2/markdown_service.go | 4 + plugin/gomark/ast/ast.go | 2 + plugin/gomark/ast/block.go | 14 + plugin/gomark/ast/inline.go | 14 + plugin/gomark/parser/math.go | 56 ++ plugin/gomark/parser/math_block.go | 56 ++ plugin/gomark/parser/math_block_test.go | 30 + plugin/gomark/parser/math_test.go | 30 + plugin/gomark/parser/parser.go | 2 + plugin/gomark/parser/tokenizer/tokenizer.go | 3 + proto/api/v2/markdown_service.proto | 56 +- proto/gen/api/v2/README.md | 58 +- proto/gen/api/v2/markdown_service.pb.go | 737 ++++++++++++-------- web/package.json | 2 + web/pnpm-lock.yaml | 29 + web/src/components/MemoContent/Math.tsx | 13 + web/src/components/MemoContent/Renderer.tsx | 6 + 17 files changed, 797 insertions(+), 315 deletions(-) create mode 100644 plugin/gomark/parser/math.go create mode 100644 plugin/gomark/parser/math_block.go create mode 100644 plugin/gomark/parser/math_block_test.go create mode 100644 plugin/gomark/parser/math_test.go create mode 100644 web/src/components/MemoContent/Math.tsx diff --git a/api/v2/markdown_service.go b/api/v2/markdown_service.go index 0b720cbf..7308228a 100644 --- a/api/v2/markdown_service.go +++ b/api/v2/markdown_service.go @@ -61,6 +61,8 @@ func convertFromASTNode(rawNode ast.Node) *apiv2pb.Node { case *ast.TaskList: children := convertFromASTNodes(n.Children) node.Node = &apiv2pb.Node_TaskListNode{TaskListNode: &apiv2pb.TaskListNode{Symbol: n.Symbol, Complete: n.Complete, Children: children}} + case *ast.MathBlock: + node.Node = &apiv2pb.Node_MathBlockNode{MathBlockNode: &apiv2pb.MathBlockNode{Content: n.Content}} case *ast.Text: node.Node = &apiv2pb.Node_TextNode{TextNode: &apiv2pb.TextNode{Content: n.Content}} case *ast.Bold: @@ -84,6 +86,8 @@ func convertFromASTNode(rawNode ast.Node) *apiv2pb.Node { node.Node = &apiv2pb.Node_StrikethroughNode{StrikethroughNode: &apiv2pb.StrikethroughNode{Content: n.Content}} case *ast.EscapingCharacter: node.Node = &apiv2pb.Node_EscapingCharacterNode{EscapingCharacterNode: &apiv2pb.EscapingCharacterNode{Symbol: n.Symbol}} + case *ast.Math: + node.Node = &apiv2pb.Node_MathNode{MathNode: &apiv2pb.MathNode{Content: n.Content}} default: node.Node = &apiv2pb.Node_TextNode{TextNode: &apiv2pb.TextNode{}} } diff --git a/plugin/gomark/ast/ast.go b/plugin/gomark/ast/ast.go index 5c7d5f2c..a1416d3d 100644 --- a/plugin/gomark/ast/ast.go +++ b/plugin/gomark/ast/ast.go @@ -14,6 +14,7 @@ const ( OrderedListNode UnorderedListNode TaskListNode + MathBlockNode // Inline nodes. TextNode BoldNode @@ -26,6 +27,7 @@ const ( TagNode StrikethroughNode EscapingCharacterNode + MathNode ) type Node interface { diff --git a/plugin/gomark/ast/block.go b/plugin/gomark/ast/block.go index d292cc2d..cd43a7f6 100644 --- a/plugin/gomark/ast/block.go +++ b/plugin/gomark/ast/block.go @@ -170,3 +170,17 @@ func (n *TaskList) Restore() string { } return fmt.Sprintf("%s [%s] %s", n.Symbol, complete, result) } + +type MathBlock struct { + BaseBlock + + Content string +} + +func (*MathBlock) Type() NodeType { + return MathBlockNode +} + +func (n *MathBlock) Restore() string { + return fmt.Sprintf("$$\n%s\n$$", n.Content) +} diff --git a/plugin/gomark/ast/inline.go b/plugin/gomark/ast/inline.go index af1d065b..a7f52cca 100644 --- a/plugin/gomark/ast/inline.go +++ b/plugin/gomark/ast/inline.go @@ -177,3 +177,17 @@ func (*EscapingCharacter) Type() NodeType { func (n *EscapingCharacter) Restore() string { return fmt.Sprintf("\\%s", n.Symbol) } + +type Math struct { + BaseInline + + Content string +} + +func (*Math) Type() NodeType { + return MathNode +} + +func (n *Math) Restore() string { + return fmt.Sprintf("$%s$", n.Content) +} diff --git a/plugin/gomark/parser/math.go b/plugin/gomark/parser/math.go new file mode 100644 index 00000000..888c60d3 --- /dev/null +++ b/plugin/gomark/parser/math.go @@ -0,0 +1,56 @@ +package parser + +import ( + "errors" + + "github.com/usememos/memos/plugin/gomark/ast" + "github.com/usememos/memos/plugin/gomark/parser/tokenizer" +) + +type MathParser struct{} + +func NewMathParser() *MathParser { + return &MathParser{} +} + +func (*MathParser) Match(tokens []*tokenizer.Token) (int, bool) { + if len(tokens) < 3 { + return 0, false + } + + if tokens[0].Type != tokenizer.DollarSign { + return 0, false + } + + contentTokens := []*tokenizer.Token{} + for _, token := range tokens[1:] { + if token.Type == tokenizer.Newline { + return 0, false + } + if token.Type == tokenizer.DollarSign { + break + } + contentTokens = append(contentTokens, token) + } + if len(contentTokens) == 0 { + return 0, false + } + if len(contentTokens)+2 > len(tokens) { + return 0, false + } + if tokens[len(contentTokens)+1].Type != tokenizer.DollarSign { + return 0, false + } + return len(contentTokens) + 2, true +} + +func (p *MathParser) Parse(tokens []*tokenizer.Token) (ast.Node, error) { + size, ok := p.Match(tokens) + if size == 0 || !ok { + return nil, errors.New("not matched") + } + + return &ast.Math{ + Content: tokenizer.Stringify(tokens[1 : size-1]), + }, nil +} diff --git a/plugin/gomark/parser/math_block.go b/plugin/gomark/parser/math_block.go new file mode 100644 index 00000000..ad3a7852 --- /dev/null +++ b/plugin/gomark/parser/math_block.go @@ -0,0 +1,56 @@ +package parser + +import ( + "errors" + + "github.com/usememos/memos/plugin/gomark/ast" + "github.com/usememos/memos/plugin/gomark/parser/tokenizer" +) + +type MathBlockParser struct{} + +func NewMathBlockParser() *MathBlockParser { + return &MathBlockParser{} +} + +func (*MathBlockParser) Match(tokens []*tokenizer.Token) (int, bool) { + if len(tokens) < 7 { + return 0, false + } + + if tokens[0].Type != tokenizer.DollarSign && tokens[1].Type != tokenizer.DollarSign && tokens[2].Type != tokenizer.Newline { + return 0, false + } + + cursor := 3 + matched := false + for ; cursor < len(tokens)-2; cursor++ { + if tokens[cursor].Type == tokenizer.Newline && tokens[cursor+1].Type == tokenizer.DollarSign && tokens[cursor+2].Type == tokenizer.DollarSign { + if cursor+2 == len(tokens)-1 { + cursor += 3 + matched = true + break + } else if tokens[cursor+3].Type == tokenizer.Newline { + cursor += 3 + matched = true + break + } + } + } + if !matched { + return 0, false + } + + return cursor, true +} + +func (p *MathBlockParser) Parse(tokens []*tokenizer.Token) (ast.Node, error) { + size, ok := p.Match(tokens) + if size == 0 || !ok { + return nil, errors.New("not matched") + } + + return &ast.MathBlock{ + Content: tokenizer.Stringify(tokens[3 : size-3]), + }, nil +} diff --git a/plugin/gomark/parser/math_block_test.go b/plugin/gomark/parser/math_block_test.go new file mode 100644 index 00000000..5f489980 --- /dev/null +++ b/plugin/gomark/parser/math_block_test.go @@ -0,0 +1,30 @@ +package parser + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/usememos/memos/plugin/gomark/ast" + "github.com/usememos/memos/plugin/gomark/parser/tokenizer" + "github.com/usememos/memos/plugin/gomark/restore" +) + +func TestMathBlockParser(t *testing.T) { + tests := []struct { + text string + link ast.Node + }{ + { + text: "$$\n(1+x)^2\n$$", + link: &ast.MathBlock{ + Content: "(1+x)^2", + }, + }, + } + for _, test := range tests { + tokens := tokenizer.Tokenize(test.text) + node, _ := NewMathBlockParser().Parse(tokens) + require.Equal(t, restore.Restore([]ast.Node{test.link}), restore.Restore([]ast.Node{node})) + } +} diff --git a/plugin/gomark/parser/math_test.go b/plugin/gomark/parser/math_test.go new file mode 100644 index 00000000..d3d41483 --- /dev/null +++ b/plugin/gomark/parser/math_test.go @@ -0,0 +1,30 @@ +package parser + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/usememos/memos/plugin/gomark/ast" + "github.com/usememos/memos/plugin/gomark/parser/tokenizer" + "github.com/usememos/memos/plugin/gomark/restore" +) + +func TestMathParser(t *testing.T) { + tests := []struct { + text string + link ast.Node + }{ + { + text: "$\\sqrt{3x-1}+(1+x)^2$", + link: &ast.Math{ + Content: "\\sqrt{3x-1}+(1+x)^2", + }, + }, + } + for _, test := range tests { + tokens := tokenizer.Tokenize(test.text) + node, _ := NewMathParser().Parse(tokens) + require.Equal(t, restore.Restore([]ast.Node{test.link}), restore.Restore([]ast.Node{node})) + } +} diff --git a/plugin/gomark/parser/parser.go b/plugin/gomark/parser/parser.go index 133bbad3..8d0f8a4a 100644 --- a/plugin/gomark/parser/parser.go +++ b/plugin/gomark/parser/parser.go @@ -37,6 +37,7 @@ var defaultBlockParsers = []BlockParser{ NewTaskListParser(), NewUnorderedListParser(), NewOrderedListParser(), + NewMathBlockParser(), NewParagraphParser(), NewLineBreakParser(), } @@ -90,6 +91,7 @@ var defaultInlineParsers = []InlineParser{ NewBoldParser(), NewItalicParser(), NewCodeParser(), + NewMathParser(), NewTagParser(), NewStrikethroughParser(), NewLineBreakParser(), diff --git a/plugin/gomark/parser/tokenizer/tokenizer.go b/plugin/gomark/parser/tokenizer/tokenizer.go index ea79158e..8322a23a 100644 --- a/plugin/gomark/parser/tokenizer/tokenizer.go +++ b/plugin/gomark/parser/tokenizer/tokenizer.go @@ -18,6 +18,7 @@ const ( Dot TokenType = "." LessThan TokenType = "<" GreaterThan TokenType = ">" + DollarSign TokenType = "$" Backslash TokenType = "\\" Newline TokenType = "\n" Space TokenType = " " @@ -74,6 +75,8 @@ func Tokenize(text string) []*Token { tokens = append(tokens, NewToken(PlusSign, "+")) case '.': tokens = append(tokens, NewToken(Dot, ".")) + case '$': + tokens = append(tokens, NewToken(DollarSign, "$")) case '\\': tokens = append(tokens, NewToken(Backslash, `\`)) case '\n': diff --git a/proto/api/v2/markdown_service.proto b/proto/api/v2/markdown_service.proto index 64357e23..5f4d1215 100644 --- a/proto/api/v2/markdown_service.proto +++ b/proto/api/v2/markdown_service.proto @@ -34,17 +34,19 @@ enum NodeType { ORDERED_LIST = 7; UNORDERED_LIST = 8; TASK_LIST = 9; - TEXT = 10; - BOLD = 11; - ITALIC = 12; - BOLD_ITALIC = 13; - CODE = 14; - IMAGE = 15; - LINK = 16; - AUTO_LINK = 17; - TAG = 18; - STRIKETHROUGH = 19; - ESCAPING_CHARACTER = 20; + MATH_BLOCK = 10; + TEXT = 11; + BOLD = 12; + ITALIC = 13; + BOLD_ITALIC = 14; + CODE = 15; + IMAGE = 16; + LINK = 17; + AUTO_LINK = 18; + TAG = 19; + STRIKETHROUGH = 20; + ESCAPING_CHARACTER = 21; + MATH = 22; } message Node { @@ -59,17 +61,19 @@ message Node { OrderedListNode ordered_list_node = 8; UnorderedListNode unordered_list_node = 9; TaskListNode task_list_node = 10; - TextNode text_node = 11; - BoldNode bold_node = 12; - ItalicNode italic_node = 13; - BoldItalicNode bold_italic_node = 14; - CodeNode code_node = 15; - ImageNode image_node = 16; - LinkNode link_node = 17; - AutoLinkNode auto_link_node = 18; - TagNode tag_node = 19; - StrikethroughNode strikethrough_node = 20; - EscapingCharacterNode escaping_character_node = 21; + MathBlockNode math_block_node = 11; + TextNode text_node = 12; + BoldNode bold_node = 13; + ItalicNode italic_node = 14; + BoldItalicNode bold_italic_node = 15; + CodeNode code_node = 16; + ImageNode image_node = 17; + LinkNode link_node = 18; + AutoLinkNode auto_link_node = 19; + TagNode tag_node = 20; + StrikethroughNode strikethrough_node = 21; + EscapingCharacterNode escaping_character_node = 22; + MathNode math_node = 23; } } @@ -113,6 +117,10 @@ message TaskListNode { repeated Node children = 3; } +message MathBlockNode { + string content = 1; +} + message TextNode { string content = 1; } @@ -161,3 +169,7 @@ message StrikethroughNode { message EscapingCharacterNode { string symbol = 1; } + +message MathNode { + string content = 1; +} diff --git a/proto/gen/api/v2/README.md b/proto/gen/api/v2/README.md index 4dc5e244..99a2c2b1 100644 --- a/proto/gen/api/v2/README.md +++ b/proto/gen/api/v2/README.md @@ -79,6 +79,8 @@ - [ItalicNode](#memos-api-v2-ItalicNode) - [LineBreakNode](#memos-api-v2-LineBreakNode) - [LinkNode](#memos-api-v2-LinkNode) + - [MathBlockNode](#memos-api-v2-MathBlockNode) + - [MathNode](#memos-api-v2-MathNode) - [Node](#memos-api-v2-Node) - [OrderedListNode](#memos-api-v2-OrderedListNode) - [ParagraphNode](#memos-api-v2-ParagraphNode) @@ -1154,6 +1156,36 @@ + + +### MathBlockNode + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| content | [string](#string) | | | + + + + + + + + +### MathNode + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| content | [string](#string) | | | + + + + + + ### Node @@ -1172,6 +1204,7 @@ | ordered_list_node | [OrderedListNode](#memos-api-v2-OrderedListNode) | | | | unordered_list_node | [UnorderedListNode](#memos-api-v2-UnorderedListNode) | | | | task_list_node | [TaskListNode](#memos-api-v2-TaskListNode) | | | +| math_block_node | [MathBlockNode](#memos-api-v2-MathBlockNode) | | | | text_node | [TextNode](#memos-api-v2-TextNode) | | | | bold_node | [BoldNode](#memos-api-v2-BoldNode) | | | | italic_node | [ItalicNode](#memos-api-v2-ItalicNode) | | | @@ -1183,6 +1216,7 @@ | tag_node | [TagNode](#memos-api-v2-TagNode) | | | | strikethrough_node | [StrikethroughNode](#memos-api-v2-StrikethroughNode) | | | | escaping_character_node | [EscapingCharacterNode](#memos-api-v2-EscapingCharacterNode) | | | +| math_node | [MathNode](#memos-api-v2-MathNode) | | | @@ -1347,17 +1381,19 @@ | ORDERED_LIST | 7 | | | UNORDERED_LIST | 8 | | | TASK_LIST | 9 | | -| TEXT | 10 | | -| BOLD | 11 | | -| ITALIC | 12 | | -| BOLD_ITALIC | 13 | | -| CODE | 14 | | -| IMAGE | 15 | | -| LINK | 16 | | -| AUTO_LINK | 17 | | -| TAG | 18 | | -| STRIKETHROUGH | 19 | | -| ESCAPING_CHARACTER | 20 | | +| MATH_BLOCK | 10 | | +| TEXT | 11 | | +| BOLD | 12 | | +| ITALIC | 13 | | +| BOLD_ITALIC | 14 | | +| CODE | 15 | | +| IMAGE | 16 | | +| LINK | 17 | | +| AUTO_LINK | 18 | | +| TAG | 19 | | +| STRIKETHROUGH | 20 | | +| ESCAPING_CHARACTER | 21 | | +| MATH | 22 | | diff --git a/proto/gen/api/v2/markdown_service.pb.go b/proto/gen/api/v2/markdown_service.pb.go index 5e6ef7a6..abd2cf0b 100644 --- a/proto/gen/api/v2/markdown_service.pb.go +++ b/proto/gen/api/v2/markdown_service.pb.go @@ -34,17 +34,19 @@ const ( NodeType_ORDERED_LIST NodeType = 7 NodeType_UNORDERED_LIST NodeType = 8 NodeType_TASK_LIST NodeType = 9 - NodeType_TEXT NodeType = 10 - NodeType_BOLD NodeType = 11 - NodeType_ITALIC NodeType = 12 - NodeType_BOLD_ITALIC NodeType = 13 - NodeType_CODE NodeType = 14 - NodeType_IMAGE NodeType = 15 - NodeType_LINK NodeType = 16 - NodeType_AUTO_LINK NodeType = 17 - NodeType_TAG NodeType = 18 - NodeType_STRIKETHROUGH NodeType = 19 - NodeType_ESCAPING_CHARACTER NodeType = 20 + NodeType_MATH_BLOCK NodeType = 10 + NodeType_TEXT NodeType = 11 + NodeType_BOLD NodeType = 12 + NodeType_ITALIC NodeType = 13 + NodeType_BOLD_ITALIC NodeType = 14 + NodeType_CODE NodeType = 15 + NodeType_IMAGE NodeType = 16 + NodeType_LINK NodeType = 17 + NodeType_AUTO_LINK NodeType = 18 + NodeType_TAG NodeType = 19 + NodeType_STRIKETHROUGH NodeType = 20 + NodeType_ESCAPING_CHARACTER NodeType = 21 + NodeType_MATH NodeType = 22 ) // Enum value maps for NodeType. @@ -60,17 +62,19 @@ var ( 7: "ORDERED_LIST", 8: "UNORDERED_LIST", 9: "TASK_LIST", - 10: "TEXT", - 11: "BOLD", - 12: "ITALIC", - 13: "BOLD_ITALIC", - 14: "CODE", - 15: "IMAGE", - 16: "LINK", - 17: "AUTO_LINK", - 18: "TAG", - 19: "STRIKETHROUGH", - 20: "ESCAPING_CHARACTER", + 10: "MATH_BLOCK", + 11: "TEXT", + 12: "BOLD", + 13: "ITALIC", + 14: "BOLD_ITALIC", + 15: "CODE", + 16: "IMAGE", + 17: "LINK", + 18: "AUTO_LINK", + 19: "TAG", + 20: "STRIKETHROUGH", + 21: "ESCAPING_CHARACTER", + 22: "MATH", } NodeType_value = map[string]int32{ "NODE_UNSPECIFIED": 0, @@ -83,17 +87,19 @@ var ( "ORDERED_LIST": 7, "UNORDERED_LIST": 8, "TASK_LIST": 9, - "TEXT": 10, - "BOLD": 11, - "ITALIC": 12, - "BOLD_ITALIC": 13, - "CODE": 14, - "IMAGE": 15, - "LINK": 16, - "AUTO_LINK": 17, - "TAG": 18, - "STRIKETHROUGH": 19, - "ESCAPING_CHARACTER": 20, + "MATH_BLOCK": 10, + "TEXT": 11, + "BOLD": 12, + "ITALIC": 13, + "BOLD_ITALIC": 14, + "CODE": 15, + "IMAGE": 16, + "LINK": 17, + "AUTO_LINK": 18, + "TAG": 19, + "STRIKETHROUGH": 20, + "ESCAPING_CHARACTER": 21, + "MATH": 22, } ) @@ -235,6 +241,7 @@ type Node struct { // *Node_OrderedListNode // *Node_UnorderedListNode // *Node_TaskListNode + // *Node_MathBlockNode // *Node_TextNode // *Node_BoldNode // *Node_ItalicNode @@ -246,6 +253,7 @@ type Node struct { // *Node_TagNode // *Node_StrikethroughNode // *Node_EscapingCharacterNode + // *Node_MathNode Node isNode_Node `protobuf_oneof:"node"` } @@ -358,6 +366,13 @@ func (x *Node) GetTaskListNode() *TaskListNode { return nil } +func (x *Node) GetMathBlockNode() *MathBlockNode { + if x, ok := x.GetNode().(*Node_MathBlockNode); ok { + return x.MathBlockNode + } + return nil +} + func (x *Node) GetTextNode() *TextNode { if x, ok := x.GetNode().(*Node_TextNode); ok { return x.TextNode @@ -435,6 +450,13 @@ func (x *Node) GetEscapingCharacterNode() *EscapingCharacterNode { return nil } +func (x *Node) GetMathNode() *MathNode { + if x, ok := x.GetNode().(*Node_MathNode); ok { + return x.MathNode + } + return nil +} + type isNode_Node interface { isNode_Node() } @@ -475,48 +497,56 @@ type Node_TaskListNode struct { TaskListNode *TaskListNode `protobuf:"bytes,10,opt,name=task_list_node,json=taskListNode,proto3,oneof"` } +type Node_MathBlockNode struct { + MathBlockNode *MathBlockNode `protobuf:"bytes,11,opt,name=math_block_node,json=mathBlockNode,proto3,oneof"` +} + type Node_TextNode struct { - TextNode *TextNode `protobuf:"bytes,11,opt,name=text_node,json=textNode,proto3,oneof"` + TextNode *TextNode `protobuf:"bytes,12,opt,name=text_node,json=textNode,proto3,oneof"` } type Node_BoldNode struct { - BoldNode *BoldNode `protobuf:"bytes,12,opt,name=bold_node,json=boldNode,proto3,oneof"` + BoldNode *BoldNode `protobuf:"bytes,13,opt,name=bold_node,json=boldNode,proto3,oneof"` } type Node_ItalicNode struct { - ItalicNode *ItalicNode `protobuf:"bytes,13,opt,name=italic_node,json=italicNode,proto3,oneof"` + ItalicNode *ItalicNode `protobuf:"bytes,14,opt,name=italic_node,json=italicNode,proto3,oneof"` } type Node_BoldItalicNode struct { - BoldItalicNode *BoldItalicNode `protobuf:"bytes,14,opt,name=bold_italic_node,json=boldItalicNode,proto3,oneof"` + BoldItalicNode *BoldItalicNode `protobuf:"bytes,15,opt,name=bold_italic_node,json=boldItalicNode,proto3,oneof"` } type Node_CodeNode struct { - CodeNode *CodeNode `protobuf:"bytes,15,opt,name=code_node,json=codeNode,proto3,oneof"` + CodeNode *CodeNode `protobuf:"bytes,16,opt,name=code_node,json=codeNode,proto3,oneof"` } type Node_ImageNode struct { - ImageNode *ImageNode `protobuf:"bytes,16,opt,name=image_node,json=imageNode,proto3,oneof"` + ImageNode *ImageNode `protobuf:"bytes,17,opt,name=image_node,json=imageNode,proto3,oneof"` } type Node_LinkNode struct { - LinkNode *LinkNode `protobuf:"bytes,17,opt,name=link_node,json=linkNode,proto3,oneof"` + LinkNode *LinkNode `protobuf:"bytes,18,opt,name=link_node,json=linkNode,proto3,oneof"` } type Node_AutoLinkNode struct { - AutoLinkNode *AutoLinkNode `protobuf:"bytes,18,opt,name=auto_link_node,json=autoLinkNode,proto3,oneof"` + AutoLinkNode *AutoLinkNode `protobuf:"bytes,19,opt,name=auto_link_node,json=autoLinkNode,proto3,oneof"` } type Node_TagNode struct { - TagNode *TagNode `protobuf:"bytes,19,opt,name=tag_node,json=tagNode,proto3,oneof"` + TagNode *TagNode `protobuf:"bytes,20,opt,name=tag_node,json=tagNode,proto3,oneof"` } type Node_StrikethroughNode struct { - StrikethroughNode *StrikethroughNode `protobuf:"bytes,20,opt,name=strikethrough_node,json=strikethroughNode,proto3,oneof"` + StrikethroughNode *StrikethroughNode `protobuf:"bytes,21,opt,name=strikethrough_node,json=strikethroughNode,proto3,oneof"` } type Node_EscapingCharacterNode struct { - EscapingCharacterNode *EscapingCharacterNode `protobuf:"bytes,21,opt,name=escaping_character_node,json=escapingCharacterNode,proto3,oneof"` + EscapingCharacterNode *EscapingCharacterNode `protobuf:"bytes,22,opt,name=escaping_character_node,json=escapingCharacterNode,proto3,oneof"` +} + +type Node_MathNode struct { + MathNode *MathNode `protobuf:"bytes,23,opt,name=math_node,json=mathNode,proto3,oneof"` } func (*Node_LineBreakNode) isNode_Node() {} @@ -537,6 +567,8 @@ func (*Node_UnorderedListNode) isNode_Node() {} func (*Node_TaskListNode) isNode_Node() {} +func (*Node_MathBlockNode) isNode_Node() {} + func (*Node_TextNode) isNode_Node() {} func (*Node_BoldNode) isNode_Node() {} @@ -559,6 +591,8 @@ func (*Node_StrikethroughNode) isNode_Node() {} func (*Node_EscapingCharacterNode) isNode_Node() {} +func (*Node_MathNode) isNode_Node() {} + type LineBreakNode struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1021,6 +1055,53 @@ func (x *TaskListNode) GetChildren() []*Node { return nil } +type MathBlockNode struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Content string `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` +} + +func (x *MathBlockNode) Reset() { + *x = MathBlockNode{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_markdown_service_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MathBlockNode) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MathBlockNode) ProtoMessage() {} + +func (x *MathBlockNode) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_markdown_service_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MathBlockNode.ProtoReflect.Descriptor instead. +func (*MathBlockNode) Descriptor() ([]byte, []int) { + return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{12} +} + +func (x *MathBlockNode) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + type TextNode struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1032,7 +1113,7 @@ type TextNode struct { func (x *TextNode) Reset() { *x = TextNode{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_markdown_service_proto_msgTypes[12] + mi := &file_api_v2_markdown_service_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1045,7 +1126,7 @@ func (x *TextNode) String() string { func (*TextNode) ProtoMessage() {} func (x *TextNode) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_markdown_service_proto_msgTypes[12] + mi := &file_api_v2_markdown_service_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1058,7 +1139,7 @@ func (x *TextNode) ProtoReflect() protoreflect.Message { // Deprecated: Use TextNode.ProtoReflect.Descriptor instead. func (*TextNode) Descriptor() ([]byte, []int) { - return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{12} + return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{13} } func (x *TextNode) GetContent() string { @@ -1080,7 +1161,7 @@ type BoldNode struct { func (x *BoldNode) Reset() { *x = BoldNode{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_markdown_service_proto_msgTypes[13] + mi := &file_api_v2_markdown_service_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1093,7 +1174,7 @@ func (x *BoldNode) String() string { func (*BoldNode) ProtoMessage() {} func (x *BoldNode) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_markdown_service_proto_msgTypes[13] + mi := &file_api_v2_markdown_service_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1106,7 +1187,7 @@ func (x *BoldNode) ProtoReflect() protoreflect.Message { // Deprecated: Use BoldNode.ProtoReflect.Descriptor instead. func (*BoldNode) Descriptor() ([]byte, []int) { - return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{13} + return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{14} } func (x *BoldNode) GetSymbol() string { @@ -1135,7 +1216,7 @@ type ItalicNode struct { func (x *ItalicNode) Reset() { *x = ItalicNode{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_markdown_service_proto_msgTypes[14] + mi := &file_api_v2_markdown_service_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1148,7 +1229,7 @@ func (x *ItalicNode) String() string { func (*ItalicNode) ProtoMessage() {} func (x *ItalicNode) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_markdown_service_proto_msgTypes[14] + mi := &file_api_v2_markdown_service_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1161,7 +1242,7 @@ func (x *ItalicNode) ProtoReflect() protoreflect.Message { // Deprecated: Use ItalicNode.ProtoReflect.Descriptor instead. func (*ItalicNode) Descriptor() ([]byte, []int) { - return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{14} + return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{15} } func (x *ItalicNode) GetSymbol() string { @@ -1190,7 +1271,7 @@ type BoldItalicNode struct { func (x *BoldItalicNode) Reset() { *x = BoldItalicNode{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_markdown_service_proto_msgTypes[15] + mi := &file_api_v2_markdown_service_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1203,7 +1284,7 @@ func (x *BoldItalicNode) String() string { func (*BoldItalicNode) ProtoMessage() {} func (x *BoldItalicNode) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_markdown_service_proto_msgTypes[15] + mi := &file_api_v2_markdown_service_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1216,7 +1297,7 @@ func (x *BoldItalicNode) ProtoReflect() protoreflect.Message { // Deprecated: Use BoldItalicNode.ProtoReflect.Descriptor instead. func (*BoldItalicNode) Descriptor() ([]byte, []int) { - return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{15} + return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{16} } func (x *BoldItalicNode) GetSymbol() string { @@ -1244,7 +1325,7 @@ type CodeNode struct { func (x *CodeNode) Reset() { *x = CodeNode{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_markdown_service_proto_msgTypes[16] + mi := &file_api_v2_markdown_service_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1257,7 +1338,7 @@ func (x *CodeNode) String() string { func (*CodeNode) ProtoMessage() {} func (x *CodeNode) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_markdown_service_proto_msgTypes[16] + mi := &file_api_v2_markdown_service_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1270,7 +1351,7 @@ func (x *CodeNode) ProtoReflect() protoreflect.Message { // Deprecated: Use CodeNode.ProtoReflect.Descriptor instead. func (*CodeNode) Descriptor() ([]byte, []int) { - return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{16} + return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{17} } func (x *CodeNode) GetContent() string { @@ -1292,7 +1373,7 @@ type ImageNode struct { func (x *ImageNode) Reset() { *x = ImageNode{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_markdown_service_proto_msgTypes[17] + mi := &file_api_v2_markdown_service_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1305,7 +1386,7 @@ func (x *ImageNode) String() string { func (*ImageNode) ProtoMessage() {} func (x *ImageNode) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_markdown_service_proto_msgTypes[17] + mi := &file_api_v2_markdown_service_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1318,7 +1399,7 @@ func (x *ImageNode) ProtoReflect() protoreflect.Message { // Deprecated: Use ImageNode.ProtoReflect.Descriptor instead. func (*ImageNode) Descriptor() ([]byte, []int) { - return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{17} + return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{18} } func (x *ImageNode) GetAltText() string { @@ -1347,7 +1428,7 @@ type LinkNode struct { func (x *LinkNode) Reset() { *x = LinkNode{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_markdown_service_proto_msgTypes[18] + mi := &file_api_v2_markdown_service_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1360,7 +1441,7 @@ func (x *LinkNode) String() string { func (*LinkNode) ProtoMessage() {} func (x *LinkNode) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_markdown_service_proto_msgTypes[18] + mi := &file_api_v2_markdown_service_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1373,7 +1454,7 @@ func (x *LinkNode) ProtoReflect() protoreflect.Message { // Deprecated: Use LinkNode.ProtoReflect.Descriptor instead. func (*LinkNode) Descriptor() ([]byte, []int) { - return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{18} + return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{19} } func (x *LinkNode) GetText() string { @@ -1401,7 +1482,7 @@ type AutoLinkNode struct { func (x *AutoLinkNode) Reset() { *x = AutoLinkNode{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_markdown_service_proto_msgTypes[19] + mi := &file_api_v2_markdown_service_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1414,7 +1495,7 @@ func (x *AutoLinkNode) String() string { func (*AutoLinkNode) ProtoMessage() {} func (x *AutoLinkNode) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_markdown_service_proto_msgTypes[19] + mi := &file_api_v2_markdown_service_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1427,7 +1508,7 @@ func (x *AutoLinkNode) ProtoReflect() protoreflect.Message { // Deprecated: Use AutoLinkNode.ProtoReflect.Descriptor instead. func (*AutoLinkNode) Descriptor() ([]byte, []int) { - return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{19} + return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{20} } func (x *AutoLinkNode) GetUrl() string { @@ -1448,7 +1529,7 @@ type TagNode struct { func (x *TagNode) Reset() { *x = TagNode{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_markdown_service_proto_msgTypes[20] + mi := &file_api_v2_markdown_service_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1461,7 +1542,7 @@ func (x *TagNode) String() string { func (*TagNode) ProtoMessage() {} func (x *TagNode) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_markdown_service_proto_msgTypes[20] + mi := &file_api_v2_markdown_service_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1474,7 +1555,7 @@ func (x *TagNode) ProtoReflect() protoreflect.Message { // Deprecated: Use TagNode.ProtoReflect.Descriptor instead. func (*TagNode) Descriptor() ([]byte, []int) { - return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{20} + return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{21} } func (x *TagNode) GetContent() string { @@ -1495,7 +1576,7 @@ type StrikethroughNode struct { func (x *StrikethroughNode) Reset() { *x = StrikethroughNode{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_markdown_service_proto_msgTypes[21] + mi := &file_api_v2_markdown_service_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1508,7 +1589,7 @@ func (x *StrikethroughNode) String() string { func (*StrikethroughNode) ProtoMessage() {} func (x *StrikethroughNode) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_markdown_service_proto_msgTypes[21] + mi := &file_api_v2_markdown_service_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1521,7 +1602,7 @@ func (x *StrikethroughNode) ProtoReflect() protoreflect.Message { // Deprecated: Use StrikethroughNode.ProtoReflect.Descriptor instead. func (*StrikethroughNode) Descriptor() ([]byte, []int) { - return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{21} + return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{22} } func (x *StrikethroughNode) GetContent() string { @@ -1542,7 +1623,7 @@ type EscapingCharacterNode struct { func (x *EscapingCharacterNode) Reset() { *x = EscapingCharacterNode{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_markdown_service_proto_msgTypes[22] + mi := &file_api_v2_markdown_service_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1555,7 +1636,7 @@ func (x *EscapingCharacterNode) String() string { func (*EscapingCharacterNode) ProtoMessage() {} func (x *EscapingCharacterNode) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_markdown_service_proto_msgTypes[22] + mi := &file_api_v2_markdown_service_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1568,7 +1649,7 @@ func (x *EscapingCharacterNode) ProtoReflect() protoreflect.Message { // Deprecated: Use EscapingCharacterNode.ProtoReflect.Descriptor instead. func (*EscapingCharacterNode) Descriptor() ([]byte, []int) { - return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{22} + return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{23} } func (x *EscapingCharacterNode) GetSymbol() string { @@ -1578,6 +1659,53 @@ func (x *EscapingCharacterNode) GetSymbol() string { return "" } +type MathNode struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Content string `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` +} + +func (x *MathNode) Reset() { + *x = MathNode{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_markdown_service_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MathNode) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MathNode) ProtoMessage() {} + +func (x *MathNode) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_markdown_service_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MathNode.ProtoReflect.Descriptor instead. +func (*MathNode) Descriptor() ([]byte, []int) { + return file_api_v2_markdown_service_proto_rawDescGZIP(), []int{24} +} + +func (x *MathNode) GetContent() string { + if x != nil { + return x.Content + } + return "" +} + var File_api_v2_markdown_service_proto protoreflect.FileDescriptor var file_api_v2_markdown_service_proto_rawDesc = []byte{ @@ -1593,7 +1721,7 @@ var file_api_v2_markdown_service_proto_rawDesc = []byte{ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, - 0x65, 0x73, 0x22, 0x97, 0x0b, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x74, + 0x65, 0x73, 0x22, 0x95, 0x0c, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x45, 0x0a, 0x0f, 0x6c, 0x69, 0x6e, 0x65, 0x5f, @@ -1637,169 +1765,184 @@ var file_api_v2_markdown_service_proto_rawDesc = []byte{ 0x73, 0x6b, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, - 0x52, 0x0c, 0x74, 0x61, 0x73, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x35, - 0x0a, 0x09, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, - 0x2e, 0x54, 0x65, 0x78, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x08, 0x74, 0x65, 0x78, - 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x62, 0x6f, 0x6c, 0x64, 0x5f, 0x6e, 0x6f, + 0x52, 0x0c, 0x74, 0x61, 0x73, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x45, + 0x0a, 0x0f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x6f, 0x64, + 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x74, 0x68, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x6d, 0x61, 0x74, 0x68, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6f, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, - 0x48, 0x00, 0x52, 0x08, 0x62, 0x6f, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x3b, 0x0a, 0x0b, - 0x69, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, - 0x2e, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x69, - 0x74, 0x61, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x48, 0x0a, 0x10, 0x62, 0x6f, 0x6c, - 0x64, 0x5f, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x0e, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x32, 0x2e, 0x42, 0x6f, 0x6c, 0x64, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x64, - 0x65, 0x48, 0x00, 0x52, 0x0e, 0x62, 0x6f, 0x6c, 0x64, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x4e, - 0x6f, 0x64, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x6f, 0x64, 0x65, - 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, - 0x52, 0x08, 0x63, 0x6f, 0x64, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x38, 0x0a, 0x0a, 0x69, 0x6d, - 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x6d, - 0x61, 0x67, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, - 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x6f, 0x64, - 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x48, - 0x00, 0x52, 0x08, 0x6c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x42, 0x0a, 0x0e, 0x61, - 0x75, 0x74, 0x6f, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x12, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x32, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x48, - 0x00, 0x52, 0x0c, 0x61, 0x75, 0x74, 0x6f, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x12, - 0x32, 0x0a, 0x08, 0x74, 0x61, 0x67, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, - 0x2e, 0x54, 0x61, 0x67, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x07, 0x74, 0x61, 0x67, 0x4e, - 0x6f, 0x64, 0x65, 0x12, 0x50, 0x0a, 0x12, 0x73, 0x74, 0x72, 0x69, 0x6b, 0x65, 0x74, 0x68, 0x72, - 0x6f, 0x75, 0x67, 0x68, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, - 0x74, 0x72, 0x69, 0x6b, 0x65, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x4e, 0x6f, 0x64, 0x65, - 0x48, 0x00, 0x52, 0x11, 0x73, 0x74, 0x72, 0x69, 0x6b, 0x65, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, - 0x68, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x5d, 0x0a, 0x17, 0x65, 0x73, 0x63, 0x61, 0x70, 0x69, 0x6e, - 0x67, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x6f, 0x64, 0x65, - 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x73, 0x63, 0x61, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x68, - 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x15, 0x65, - 0x73, 0x63, 0x61, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, - 0x4e, 0x6f, 0x64, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x0f, 0x0a, 0x0d, - 0x4c, 0x69, 0x6e, 0x65, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x22, 0x3f, 0x0a, - 0x0d, 0x50, 0x61, 0x72, 0x61, 0x67, 0x72, 0x61, 0x70, 0x68, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x2e, - 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, - 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x45, - 0x0a, 0x0d, 0x43, 0x6f, 0x64, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x12, - 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x53, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, - 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x68, - 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, - 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, - 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x2c, 0x0a, 0x12, 0x48, 0x6f, - 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x22, 0x40, 0x0a, 0x0e, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x68, - 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, - 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, - 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x59, 0x0a, 0x0f, 0x4f, 0x72, - 0x64, 0x65, 0x72, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, - 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x63, 0x68, 0x69, - 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x5b, 0x0a, 0x11, 0x55, 0x6e, 0x6f, 0x72, 0x64, 0x65, 0x72, - 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, - 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, - 0x6f, 0x6c, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, - 0x65, 0x6e, 0x22, 0x72, 0x0a, 0x0c, 0x54, 0x61, 0x73, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, - 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, - 0x65, 0x6e, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x63, 0x68, - 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x24, 0x0a, 0x08, 0x54, 0x65, 0x78, 0x74, 0x4e, 0x6f, - 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x52, 0x0a, 0x08, - 0x42, 0x6f, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x65, 0x78, 0x74, 0x4e, 0x6f, 0x64, 0x65, + 0x48, 0x00, 0x52, 0x08, 0x74, 0x65, 0x78, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x35, 0x0a, 0x09, + 0x62, 0x6f, 0x6c, 0x64, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x42, + 0x6f, 0x6c, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x08, 0x62, 0x6f, 0x6c, 0x64, 0x4e, + 0x6f, 0x64, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x5f, 0x6e, 0x6f, + 0x64, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x4e, 0x6f, + 0x64, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x64, 0x65, + 0x12, 0x48, 0x0a, 0x10, 0x62, 0x6f, 0x6c, 0x64, 0x5f, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x5f, + 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x6f, 0x6c, 0x64, 0x49, 0x74, + 0x61, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x62, 0x6f, 0x6c, 0x64, + 0x49, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x63, 0x6f, + 0x64, 0x65, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x64, + 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x64, 0x65, 0x4e, 0x6f, 0x64, + 0x65, 0x12, 0x38, 0x0a, 0x0a, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, + 0x52, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x6c, + 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, + 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x08, 0x6c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, + 0x64, 0x65, 0x12, 0x42, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, + 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x4c, 0x69, + 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x75, 0x74, 0x6f, 0x4c, 0x69, + 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x74, 0x61, 0x67, 0x5f, 0x6e, 0x6f, + 0x64, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x61, 0x67, 0x4e, 0x6f, 0x64, 0x65, 0x48, + 0x00, 0x52, 0x07, 0x74, 0x61, 0x67, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x50, 0x0a, 0x12, 0x73, 0x74, + 0x72, 0x69, 0x6b, 0x65, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x5f, 0x6e, 0x6f, 0x64, 0x65, + 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6b, 0x65, 0x74, 0x68, 0x72, 0x6f, + 0x75, 0x67, 0x68, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x11, 0x73, 0x74, 0x72, 0x69, 0x6b, + 0x65, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x5d, 0x0a, 0x17, + 0x65, 0x73, 0x63, 0x61, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, + 0x65, 0x72, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x73, 0x63, + 0x61, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x4e, 0x6f, + 0x64, 0x65, 0x48, 0x00, 0x52, 0x15, 0x65, 0x73, 0x63, 0x61, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x68, + 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x6d, + 0x61, 0x74, 0x68, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, + 0x74, 0x68, 0x4e, 0x6f, 0x64, 0x65, 0x48, 0x00, 0x52, 0x08, 0x6d, 0x61, 0x74, 0x68, 0x4e, 0x6f, + 0x64, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x4c, 0x69, + 0x6e, 0x65, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x22, 0x3f, 0x0a, 0x0d, 0x50, + 0x61, 0x72, 0x61, 0x67, 0x72, 0x61, 0x70, 0x68, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x2e, 0x0a, 0x08, + 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, + 0x64, 0x65, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x45, 0x0a, 0x0d, + 0x43, 0x6f, 0x64, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, + 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x22, 0x53, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x4e, 0x6f, + 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x72, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, + 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x2c, 0x0a, 0x12, 0x48, 0x6f, 0x72, 0x69, + 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x22, 0x40, 0x0a, 0x0e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x71, + 0x75, 0x6f, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x72, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, + 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x59, 0x0a, 0x0f, 0x4f, 0x72, 0x64, 0x65, + 0x72, 0x65, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x72, 0x65, 0x6e, 0x22, 0x5b, 0x0a, 0x11, 0x55, 0x6e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, + 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, - 0x22, 0x3e, 0x0a, 0x0a, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, + 0x22, 0x72, 0x0a, 0x0c, 0x54, 0x61, 0x73, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x72, 0x65, 0x6e, 0x22, 0x29, 0x0a, 0x0d, 0x4d, 0x61, 0x74, 0x68, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, + 0x24, 0x0a, 0x08, 0x54, 0x65, 0x78, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x52, 0x0a, 0x08, 0x42, 0x6f, 0x6c, 0x64, 0x4e, 0x6f, 0x64, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, + 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x3e, 0x0a, 0x0a, 0x49, 0x74, 0x61, + 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, + 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, + 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x42, 0x0a, 0x0e, 0x42, 0x6f, 0x6c, + 0x64, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, + 0x62, 0x6f, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x24, 0x0a, + 0x08, 0x43, 0x6f, 0x64, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x22, 0x38, 0x0a, 0x09, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x6f, 0x64, 0x65, + 0x12, 0x19, 0x0a, 0x08, 0x61, 0x6c, 0x74, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x61, 0x6c, 0x74, 0x54, 0x65, 0x78, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, + 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x30, 0x0a, + 0x08, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, + 0x20, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x6f, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x12, + 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, + 0x6c, 0x22, 0x23, 0x0a, 0x07, 0x54, 0x61, 0x67, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x2d, 0x0a, 0x11, 0x53, 0x74, 0x72, 0x69, 0x6b, 0x65, + 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x2f, 0x0a, 0x15, 0x45, 0x73, 0x63, 0x61, 0x70, 0x69, 0x6e, + 0x67, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x22, 0x42, 0x0a, 0x0e, 0x42, 0x6f, 0x6c, 0x64, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x4e, 0x6f, - 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x22, 0x24, 0x0a, 0x08, 0x43, 0x6f, 0x64, 0x65, 0x4e, 0x6f, 0x64, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x38, 0x0a, 0x09, 0x49, 0x6d, - 0x61, 0x67, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x6c, 0x74, 0x5f, 0x74, - 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x6c, 0x74, 0x54, 0x65, - 0x78, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x75, 0x72, 0x6c, 0x22, 0x30, 0x0a, 0x08, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x74, 0x65, 0x78, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x20, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x6f, 0x4c, 0x69, - 0x6e, 0x6b, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x23, 0x0a, 0x07, 0x54, 0x61, 0x67, 0x4e, - 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x2d, 0x0a, - 0x11, 0x53, 0x74, 0x72, 0x69, 0x6b, 0x65, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x4e, 0x6f, + 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x22, 0x24, 0x0a, 0x08, 0x4d, 0x61, 0x74, 0x68, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x2f, 0x0a, 0x15, - 0x45, 0x73, 0x63, 0x61, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, - 0x72, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x2a, 0xc9, 0x02, - 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x4e, 0x4f, - 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x42, 0x52, 0x45, 0x41, 0x4b, 0x10, 0x01, - 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x41, 0x52, 0x41, 0x47, 0x52, 0x41, 0x50, 0x48, 0x10, 0x02, 0x12, - 0x0e, 0x0a, 0x0a, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x03, 0x12, - 0x0b, 0x0a, 0x07, 0x48, 0x45, 0x41, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, - 0x48, 0x4f, 0x52, 0x49, 0x5a, 0x4f, 0x4e, 0x54, 0x41, 0x4c, 0x5f, 0x52, 0x55, 0x4c, 0x45, 0x10, - 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x51, 0x55, 0x4f, 0x54, 0x45, 0x10, - 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x45, 0x44, 0x5f, 0x4c, 0x49, 0x53, - 0x54, 0x10, 0x07, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x4e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x45, 0x44, - 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x08, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x53, 0x4b, 0x5f, - 0x4c, 0x49, 0x53, 0x54, 0x10, 0x09, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x45, 0x58, 0x54, 0x10, 0x0a, - 0x12, 0x08, 0x0a, 0x04, 0x42, 0x4f, 0x4c, 0x44, 0x10, 0x0b, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x54, - 0x41, 0x4c, 0x49, 0x43, 0x10, 0x0c, 0x12, 0x0f, 0x0a, 0x0b, 0x42, 0x4f, 0x4c, 0x44, 0x5f, 0x49, - 0x54, 0x41, 0x4c, 0x49, 0x43, 0x10, 0x0d, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x4f, 0x44, 0x45, 0x10, - 0x0e, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x10, 0x0f, 0x12, 0x08, 0x0a, 0x04, - 0x4c, 0x49, 0x4e, 0x4b, 0x10, 0x10, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x4c, - 0x49, 0x4e, 0x4b, 0x10, 0x11, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x41, 0x47, 0x10, 0x12, 0x12, 0x11, - 0x0a, 0x0d, 0x53, 0x54, 0x52, 0x49, 0x4b, 0x45, 0x54, 0x48, 0x52, 0x4f, 0x55, 0x47, 0x48, 0x10, - 0x13, 0x12, 0x16, 0x0a, 0x12, 0x45, 0x53, 0x43, 0x41, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x43, 0x48, - 0x41, 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x10, 0x14, 0x32, 0x88, 0x01, 0x0a, 0x0f, 0x4d, 0x61, - 0x72, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x75, 0x0a, - 0x0d, 0x50, 0x61, 0x72, 0x73, 0x65, 0x4d, 0x61, 0x72, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x22, - 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x61, - 0x72, 0x73, 0x65, 0x4d, 0x61, 0x72, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, - 0x32, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x4d, 0x61, 0x72, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, - 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x61, 0x72, 0x6b, - 0x64, 0x6f, 0x77, 0x6e, 0x42, 0xac, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, - 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x14, 0x4d, 0x61, 0x72, 0x6b, 0x64, - 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, - 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, - 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, - 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, - 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, - 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, - 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2a, 0xe3, 0x02, 0x0a, + 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x4e, 0x4f, 0x44, + 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x0e, 0x0a, 0x0a, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x42, 0x52, 0x45, 0x41, 0x4b, 0x10, 0x01, 0x12, + 0x0d, 0x0a, 0x09, 0x50, 0x41, 0x52, 0x41, 0x47, 0x52, 0x41, 0x50, 0x48, 0x10, 0x02, 0x12, 0x0e, + 0x0a, 0x0a, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x03, 0x12, 0x0b, + 0x0a, 0x07, 0x48, 0x45, 0x41, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x48, + 0x4f, 0x52, 0x49, 0x5a, 0x4f, 0x4e, 0x54, 0x41, 0x4c, 0x5f, 0x52, 0x55, 0x4c, 0x45, 0x10, 0x05, + 0x12, 0x0e, 0x0a, 0x0a, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x51, 0x55, 0x4f, 0x54, 0x45, 0x10, 0x06, + 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x45, 0x44, 0x5f, 0x4c, 0x49, 0x53, 0x54, + 0x10, 0x07, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x4e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x45, 0x44, 0x5f, + 0x4c, 0x49, 0x53, 0x54, 0x10, 0x08, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x53, 0x4b, 0x5f, 0x4c, + 0x49, 0x53, 0x54, 0x10, 0x09, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x41, 0x54, 0x48, 0x5f, 0x42, 0x4c, + 0x4f, 0x43, 0x4b, 0x10, 0x0a, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x45, 0x58, 0x54, 0x10, 0x0b, 0x12, + 0x08, 0x0a, 0x04, 0x42, 0x4f, 0x4c, 0x44, 0x10, 0x0c, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x54, 0x41, + 0x4c, 0x49, 0x43, 0x10, 0x0d, 0x12, 0x0f, 0x0a, 0x0b, 0x42, 0x4f, 0x4c, 0x44, 0x5f, 0x49, 0x54, + 0x41, 0x4c, 0x49, 0x43, 0x10, 0x0e, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x0f, + 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x10, 0x10, 0x12, 0x08, 0x0a, 0x04, 0x4c, + 0x49, 0x4e, 0x4b, 0x10, 0x11, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x4c, 0x49, + 0x4e, 0x4b, 0x10, 0x12, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x41, 0x47, 0x10, 0x13, 0x12, 0x11, 0x0a, + 0x0d, 0x53, 0x54, 0x52, 0x49, 0x4b, 0x45, 0x54, 0x48, 0x52, 0x4f, 0x55, 0x47, 0x48, 0x10, 0x14, + 0x12, 0x16, 0x0a, 0x12, 0x45, 0x53, 0x43, 0x41, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x43, 0x48, 0x41, + 0x52, 0x41, 0x43, 0x54, 0x45, 0x52, 0x10, 0x15, 0x12, 0x08, 0x0a, 0x04, 0x4d, 0x41, 0x54, 0x48, + 0x10, 0x16, 0x32, 0x88, 0x01, 0x0a, 0x0f, 0x4d, 0x61, 0x72, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x75, 0x0a, 0x0d, 0x50, 0x61, 0x72, 0x73, 0x65, 0x4d, + 0x61, 0x72, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x22, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x4d, 0x61, 0x72, 0x6b, + 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, + 0x4d, 0x61, 0x72, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x61, 0x72, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x42, 0xac, 0x01, + 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x42, 0x14, 0x4d, 0x61, 0x72, 0x6b, 0x64, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, + 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, + 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, + 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, + 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1815,7 +1958,7 @@ func file_api_v2_markdown_service_proto_rawDescGZIP() []byte { } var file_api_v2_markdown_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_api_v2_markdown_service_proto_msgTypes = make([]protoimpl.MessageInfo, 23) +var file_api_v2_markdown_service_proto_msgTypes = make([]protoimpl.MessageInfo, 25) var file_api_v2_markdown_service_proto_goTypes = []interface{}{ (NodeType)(0), // 0: memos.api.v2.NodeType (*ParseMarkdownRequest)(nil), // 1: memos.api.v2.ParseMarkdownRequest @@ -1830,17 +1973,19 @@ var file_api_v2_markdown_service_proto_goTypes = []interface{}{ (*OrderedListNode)(nil), // 10: memos.api.v2.OrderedListNode (*UnorderedListNode)(nil), // 11: memos.api.v2.UnorderedListNode (*TaskListNode)(nil), // 12: memos.api.v2.TaskListNode - (*TextNode)(nil), // 13: memos.api.v2.TextNode - (*BoldNode)(nil), // 14: memos.api.v2.BoldNode - (*ItalicNode)(nil), // 15: memos.api.v2.ItalicNode - (*BoldItalicNode)(nil), // 16: memos.api.v2.BoldItalicNode - (*CodeNode)(nil), // 17: memos.api.v2.CodeNode - (*ImageNode)(nil), // 18: memos.api.v2.ImageNode - (*LinkNode)(nil), // 19: memos.api.v2.LinkNode - (*AutoLinkNode)(nil), // 20: memos.api.v2.AutoLinkNode - (*TagNode)(nil), // 21: memos.api.v2.TagNode - (*StrikethroughNode)(nil), // 22: memos.api.v2.StrikethroughNode - (*EscapingCharacterNode)(nil), // 23: memos.api.v2.EscapingCharacterNode + (*MathBlockNode)(nil), // 13: memos.api.v2.MathBlockNode + (*TextNode)(nil), // 14: memos.api.v2.TextNode + (*BoldNode)(nil), // 15: memos.api.v2.BoldNode + (*ItalicNode)(nil), // 16: memos.api.v2.ItalicNode + (*BoldItalicNode)(nil), // 17: memos.api.v2.BoldItalicNode + (*CodeNode)(nil), // 18: memos.api.v2.CodeNode + (*ImageNode)(nil), // 19: memos.api.v2.ImageNode + (*LinkNode)(nil), // 20: memos.api.v2.LinkNode + (*AutoLinkNode)(nil), // 21: memos.api.v2.AutoLinkNode + (*TagNode)(nil), // 22: memos.api.v2.TagNode + (*StrikethroughNode)(nil), // 23: memos.api.v2.StrikethroughNode + (*EscapingCharacterNode)(nil), // 24: memos.api.v2.EscapingCharacterNode + (*MathNode)(nil), // 25: memos.api.v2.MathNode } var file_api_v2_markdown_service_proto_depIdxs = []int32{ 3, // 0: memos.api.v2.ParseMarkdownResponse.nodes:type_name -> memos.api.v2.Node @@ -1854,31 +1999,33 @@ var file_api_v2_markdown_service_proto_depIdxs = []int32{ 10, // 8: memos.api.v2.Node.ordered_list_node:type_name -> memos.api.v2.OrderedListNode 11, // 9: memos.api.v2.Node.unordered_list_node:type_name -> memos.api.v2.UnorderedListNode 12, // 10: memos.api.v2.Node.task_list_node:type_name -> memos.api.v2.TaskListNode - 13, // 11: memos.api.v2.Node.text_node:type_name -> memos.api.v2.TextNode - 14, // 12: memos.api.v2.Node.bold_node:type_name -> memos.api.v2.BoldNode - 15, // 13: memos.api.v2.Node.italic_node:type_name -> memos.api.v2.ItalicNode - 16, // 14: memos.api.v2.Node.bold_italic_node:type_name -> memos.api.v2.BoldItalicNode - 17, // 15: memos.api.v2.Node.code_node:type_name -> memos.api.v2.CodeNode - 18, // 16: memos.api.v2.Node.image_node:type_name -> memos.api.v2.ImageNode - 19, // 17: memos.api.v2.Node.link_node:type_name -> memos.api.v2.LinkNode - 20, // 18: memos.api.v2.Node.auto_link_node:type_name -> memos.api.v2.AutoLinkNode - 21, // 19: memos.api.v2.Node.tag_node:type_name -> memos.api.v2.TagNode - 22, // 20: memos.api.v2.Node.strikethrough_node:type_name -> memos.api.v2.StrikethroughNode - 23, // 21: memos.api.v2.Node.escaping_character_node:type_name -> memos.api.v2.EscapingCharacterNode - 3, // 22: memos.api.v2.ParagraphNode.children:type_name -> memos.api.v2.Node - 3, // 23: memos.api.v2.HeadingNode.children:type_name -> memos.api.v2.Node - 3, // 24: memos.api.v2.BlockquoteNode.children:type_name -> memos.api.v2.Node - 3, // 25: memos.api.v2.OrderedListNode.children:type_name -> memos.api.v2.Node - 3, // 26: memos.api.v2.UnorderedListNode.children:type_name -> memos.api.v2.Node - 3, // 27: memos.api.v2.TaskListNode.children:type_name -> memos.api.v2.Node - 3, // 28: memos.api.v2.BoldNode.children:type_name -> memos.api.v2.Node - 1, // 29: memos.api.v2.MarkdownService.ParseMarkdown:input_type -> memos.api.v2.ParseMarkdownRequest - 2, // 30: memos.api.v2.MarkdownService.ParseMarkdown:output_type -> memos.api.v2.ParseMarkdownResponse - 30, // [30:31] is the sub-list for method output_type - 29, // [29:30] is the sub-list for method input_type - 29, // [29:29] is the sub-list for extension type_name - 29, // [29:29] is the sub-list for extension extendee - 0, // [0:29] is the sub-list for field type_name + 13, // 11: memos.api.v2.Node.math_block_node:type_name -> memos.api.v2.MathBlockNode + 14, // 12: memos.api.v2.Node.text_node:type_name -> memos.api.v2.TextNode + 15, // 13: memos.api.v2.Node.bold_node:type_name -> memos.api.v2.BoldNode + 16, // 14: memos.api.v2.Node.italic_node:type_name -> memos.api.v2.ItalicNode + 17, // 15: memos.api.v2.Node.bold_italic_node:type_name -> memos.api.v2.BoldItalicNode + 18, // 16: memos.api.v2.Node.code_node:type_name -> memos.api.v2.CodeNode + 19, // 17: memos.api.v2.Node.image_node:type_name -> memos.api.v2.ImageNode + 20, // 18: memos.api.v2.Node.link_node:type_name -> memos.api.v2.LinkNode + 21, // 19: memos.api.v2.Node.auto_link_node:type_name -> memos.api.v2.AutoLinkNode + 22, // 20: memos.api.v2.Node.tag_node:type_name -> memos.api.v2.TagNode + 23, // 21: memos.api.v2.Node.strikethrough_node:type_name -> memos.api.v2.StrikethroughNode + 24, // 22: memos.api.v2.Node.escaping_character_node:type_name -> memos.api.v2.EscapingCharacterNode + 25, // 23: memos.api.v2.Node.math_node:type_name -> memos.api.v2.MathNode + 3, // 24: memos.api.v2.ParagraphNode.children:type_name -> memos.api.v2.Node + 3, // 25: memos.api.v2.HeadingNode.children:type_name -> memos.api.v2.Node + 3, // 26: memos.api.v2.BlockquoteNode.children:type_name -> memos.api.v2.Node + 3, // 27: memos.api.v2.OrderedListNode.children:type_name -> memos.api.v2.Node + 3, // 28: memos.api.v2.UnorderedListNode.children:type_name -> memos.api.v2.Node + 3, // 29: memos.api.v2.TaskListNode.children:type_name -> memos.api.v2.Node + 3, // 30: memos.api.v2.BoldNode.children:type_name -> memos.api.v2.Node + 1, // 31: memos.api.v2.MarkdownService.ParseMarkdown:input_type -> memos.api.v2.ParseMarkdownRequest + 2, // 32: memos.api.v2.MarkdownService.ParseMarkdown:output_type -> memos.api.v2.ParseMarkdownResponse + 32, // [32:33] is the sub-list for method output_type + 31, // [31:32] is the sub-list for method input_type + 31, // [31:31] is the sub-list for extension type_name + 31, // [31:31] is the sub-list for extension extendee + 0, // [0:31] is the sub-list for field type_name } func init() { file_api_v2_markdown_service_proto_init() } @@ -2032,7 +2179,7 @@ func file_api_v2_markdown_service_proto_init() { } } file_api_v2_markdown_service_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TextNode); i { + switch v := v.(*MathBlockNode); i { case 0: return &v.state case 1: @@ -2044,7 +2191,7 @@ func file_api_v2_markdown_service_proto_init() { } } file_api_v2_markdown_service_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BoldNode); i { + switch v := v.(*TextNode); i { case 0: return &v.state case 1: @@ -2056,7 +2203,7 @@ func file_api_v2_markdown_service_proto_init() { } } file_api_v2_markdown_service_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ItalicNode); i { + switch v := v.(*BoldNode); i { case 0: return &v.state case 1: @@ -2068,7 +2215,7 @@ func file_api_v2_markdown_service_proto_init() { } } file_api_v2_markdown_service_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BoldItalicNode); i { + switch v := v.(*ItalicNode); i { case 0: return &v.state case 1: @@ -2080,7 +2227,7 @@ func file_api_v2_markdown_service_proto_init() { } } file_api_v2_markdown_service_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CodeNode); i { + switch v := v.(*BoldItalicNode); i { case 0: return &v.state case 1: @@ -2092,7 +2239,7 @@ func file_api_v2_markdown_service_proto_init() { } } file_api_v2_markdown_service_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ImageNode); i { + switch v := v.(*CodeNode); i { case 0: return &v.state case 1: @@ -2104,7 +2251,7 @@ func file_api_v2_markdown_service_proto_init() { } } file_api_v2_markdown_service_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LinkNode); i { + switch v := v.(*ImageNode); i { case 0: return &v.state case 1: @@ -2116,7 +2263,7 @@ func file_api_v2_markdown_service_proto_init() { } } file_api_v2_markdown_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AutoLinkNode); i { + switch v := v.(*LinkNode); i { case 0: return &v.state case 1: @@ -2128,7 +2275,7 @@ func file_api_v2_markdown_service_proto_init() { } } file_api_v2_markdown_service_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TagNode); i { + switch v := v.(*AutoLinkNode); i { case 0: return &v.state case 1: @@ -2140,7 +2287,7 @@ func file_api_v2_markdown_service_proto_init() { } } file_api_v2_markdown_service_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StrikethroughNode); i { + switch v := v.(*TagNode); i { case 0: return &v.state case 1: @@ -2152,6 +2299,18 @@ func file_api_v2_markdown_service_proto_init() { } } file_api_v2_markdown_service_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StrikethroughNode); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_markdown_service_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*EscapingCharacterNode); i { case 0: return &v.state @@ -2163,6 +2322,18 @@ func file_api_v2_markdown_service_proto_init() { return nil } } + file_api_v2_markdown_service_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MathNode); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_api_v2_markdown_service_proto_msgTypes[2].OneofWrappers = []interface{}{ (*Node_LineBreakNode)(nil), @@ -2174,6 +2345,7 @@ func file_api_v2_markdown_service_proto_init() { (*Node_OrderedListNode)(nil), (*Node_UnorderedListNode)(nil), (*Node_TaskListNode)(nil), + (*Node_MathBlockNode)(nil), (*Node_TextNode)(nil), (*Node_BoldNode)(nil), (*Node_ItalicNode)(nil), @@ -2185,6 +2357,7 @@ func file_api_v2_markdown_service_proto_init() { (*Node_TagNode)(nil), (*Node_StrikethroughNode)(nil), (*Node_EscapingCharacterNode)(nil), + (*Node_MathNode)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -2192,7 +2365,7 @@ func file_api_v2_markdown_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_v2_markdown_service_proto_rawDesc, NumEnums: 1, - NumMessages: 23, + NumMessages: 25, NumExtensions: 0, NumServices: 1, }, diff --git a/web/package.json b/web/package.json index 68eded29..dded1808 100644 --- a/web/package.json +++ b/web/package.json @@ -12,6 +12,7 @@ "dependencies": { "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", + "@matejmazur/react-katex": "^3.1.3", "@mui/joy": "5.0.0-beta.20", "@reduxjs/toolkit": "^1.9.7", "axios": "^1.6.3", @@ -20,6 +21,7 @@ "highlight.js": "^11.9.0", "i18next": "^21.10.0", "i18next-browser-languagedetector": "^7.2.0", + "katex": "^0.16.9", "lodash-es": "^4.17.21", "long": "^5.2.3", "lucide-react": "^0.263.1", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index b4c5ffd3..a2442440 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -14,6 +14,9 @@ dependencies: '@emotion/styled': specifier: ^11.11.0 version: 11.11.0(@emotion/react@11.11.3)(@types/react@18.2.45)(react@18.2.0) + '@matejmazur/react-katex': + specifier: ^3.1.3 + version: 3.1.3(katex@0.16.9)(react@18.2.0) '@mui/joy': specifier: 5.0.0-beta.20 version: 5.0.0-beta.20(@emotion/react@11.11.3)(@emotion/styled@11.11.0)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) @@ -38,6 +41,9 @@ dependencies: i18next-browser-languagedetector: specifier: ^7.2.0 version: 7.2.0 + katex: + specifier: ^0.16.9 + version: 0.16.9 lodash-es: specifier: ^4.17.21 version: 4.17.21 @@ -923,6 +929,17 @@ packages: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 + /@matejmazur/react-katex@3.1.3(katex@0.16.9)(react@18.2.0): + resolution: {integrity: sha512-rBp7mJ9An7ktNoU653BWOYdO4FoR4YNwofHZi+vaytX/nWbIlmHVIF+X8VFOn6c3WYmrLT5FFBjKqCZ1sjR5uQ==} + engines: {node: '>=12', yarn: '>=1.1'} + peerDependencies: + katex: '>=0.9' + react: '>=16' + dependencies: + katex: 0.16.9 + react: 18.2.0 + dev: false + /@mui/base@5.0.0-beta.29(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-OXfUssYrB6ch/xpBVHMKAjThPlI9VyGGKdvQLMXef2j39wXfcxPlUVQlwia/lmE3rxWIGvbwkZsDtNYzLMsDUg==} engines: {node: '>=12.0.0'} @@ -2012,6 +2029,11 @@ packages: engines: {node: '>= 6'} dev: false + /commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + dev: false + /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true @@ -3124,6 +3146,13 @@ packages: object.values: 1.1.7 dev: true + /katex@0.16.9: + resolution: {integrity: sha512-fsSYjWS0EEOwvy81j3vRA8TEAhQhKiqO+FQaKWp0m39qwOzHVBgAUBIXWj1pB+O2W3fIpNa6Y9KSKCVbfPhyAQ==} + hasBin: true + dependencies: + commander: 8.3.0 + dev: false + /keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: diff --git a/web/src/components/MemoContent/Math.tsx b/web/src/components/MemoContent/Math.tsx new file mode 100644 index 00000000..2f60dd23 --- /dev/null +++ b/web/src/components/MemoContent/Math.tsx @@ -0,0 +1,13 @@ +import TeX from "@matejmazur/react-katex"; +import "katex/dist/katex.min.css"; + +interface Props { + content: string; + block?: boolean; +} + +const Math: React.FC = ({ content, block }: Props) => { + return ; +}; + +export default Math; diff --git a/web/src/components/MemoContent/Renderer.tsx b/web/src/components/MemoContent/Renderer.tsx index 49b171c0..eee2c944 100644 --- a/web/src/components/MemoContent/Renderer.tsx +++ b/web/src/components/MemoContent/Renderer.tsx @@ -11,6 +11,7 @@ import { ImageNode, ItalicNode, LinkNode, + MathNode, Node, NodeType, OrderedListNode, @@ -34,6 +35,7 @@ import Image from "./Image"; import Italic from "./Italic"; import LineBreak from "./LineBreak"; import Link from "./Link"; +import Math from "./Math"; import OrderedList from "./OrderedList"; import Paragraph from "./Paragraph"; import Strikethrough from "./Strikethrough"; @@ -66,6 +68,8 @@ const Renderer: React.FC = ({ node }: Props) => { return ; case NodeType.TASK_LIST: return ; + case NodeType.MATH_BLOCK: + return ; case NodeType.TEXT: return ; case NodeType.BOLD: @@ -86,6 +90,8 @@ const Renderer: React.FC = ({ node }: Props) => { return ; case NodeType.STRIKETHROUGH: return ; + case NodeType.MATH: + return ; case NodeType.ESCAPING_CHARACTER: return ; default: