1package boards23import (4 "errors"5 "strings"6 "time"78 "gno.land/p/nt/ufmt/v0"9)1011// NewReply creates a new reply to a thread or another reply.12func NewReply(parent *Post, creator address, body string) (*Post, error) {13 if parent == nil {14 return nil, errors.New("reply requires a parent thread or reply")15 }1617 if parent.ThreadID == 0 {18 return nil, errors.New("parent has no thread ID assigned")19 }2021 if parent.Board == nil {22 return nil, errors.New("parent has no board assigned")23 }2425 if !creator.IsValid() {26 return nil, ufmt.Errorf("invalid reply creator address: %s", creator)27 }2829 body = strings.TrimSpace(body)30 if body == "" {31 return nil, errors.New("reply body is required")32 }3334 id := parent.Board.ThreadsSequence.Next()35 return &Post{36 ID: id,37 ParentID: parent.ID,38 ThreadID: parent.ThreadID,39 Board: parent.Board,40 Body: body,41 Replies: NewPostStorage(),42 Flags: NewFlagStorage(),43 Creator: creator,44 CreatedAt: time.Now(),45 }, nil46}4748// MustNewReply creates a new reply or panics on error.49func MustNewReply(parent *Post, creator address, body string) *Post {50 p, err := NewReply(parent, creator, body)51 if err != nil {52 panic(err)53 }54 return p55}56Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.