Transaction
C5BF10579F8E7B…586DEA4008E8
Block 25,931 · index 0 · indexed
Summary
- Hash
- C5BF10579F8E7B88324E8DAE57A1916E2D1CD942CDAF16182FC3586DEA4008E8
- Block
- 25,931
- Size
- 5072 bytes
- Gas used
- 9,933,862 / 11,920,694
- Fee
- 1000000ugnot
- Memo
- gnopublish
- Status
- success
Messages
Arguments · 9
- #1cowsay
- #2README.md
- #3# `gno.land/p/moul/x/daily/cowsay/v0` **cowsay** — `Say(msg string) string` returns the classic ASCII cow with a speech bubble containing `msg`. Pure deterministic string art: the message is word-wrapped into a speech balloon (single line uses `< >`, multi-line uses `/ \ | |` borders) with the happy cow stacked underneath. Port of cowsay by Tony Monroe (1999); no `os`/`exec`, no chain coupling. ```go import "gno.land/p/moul/x/daily/cowsay/v0" art := cowsay.Say("Hello, gno.land!") // bubble + cow, ready for a code block cowsay.Say("") // default message ("Moo!") ``` **Live demo:** [`r/moul/x/daily/cowsaydemo`](https://github.com/moul/gno-contracts/tree/main/r/moul/x/daily/cowsaydemo/v0) · render it at [`/r/moul/x/daily/cowsaydemo/v0`](https://gno.land/r/moul/x/daily/cowsaydemo/v0). <!-- BEGIN GNOCONTRACTS FOOTER (generated by `make readmes`; do not edit below) --> --- Part of **[moul/gno-contracts](https://github.com/moul/gno-contracts)** — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage. > 🧪 **Highly experimental — potentially vibe-coded.** Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: [DISCLAIMER](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md). <!-- END GNOCONTRACTS FOOTER -->
- #4cowsay.gno
- #5// Package cowsay is an on-chain Gno port of the classic `cowsay` program: // it builds an ASCII cow with a speech bubble containing a message — as a // reusable pure package. // // Original: cowsay by Tony Monroe (1999), a Perl program later ported to Go // many times. This package reimplements the core rendering — bubble framing, // word-wrapping and the cow art — as pure, deterministic string logic. // // A live demo of this package (an interactive cow that says whatever you put in // the path) is at [r/moul/x/daily/cowsaydemo](/r/moul/x/daily/cowsaydemo/v0). package cowsay import ( "strings" ) // defaultMessage is shown when no message is supplied. const defaultMessage = "Moo!" // wrapWidth is the maximum bubble text width (classic cowsay uses 40). const wrapWidth = 40 // Say returns the full cowsay art (speech bubble + cow) for msg. // An empty msg falls back to the default message. func Say(msg string) string { msg = strings.TrimSpace(msg) if msg == "" { msg = defaultMessage } lines := wrap(msg, wrapWidth) return balloon(lines) + cow } // balloon builds the speech bubble around the given (already wrapped) lines. func balloon(lines []string) string { width := maxLen(lines) var b strings.Builder // top border: " " + "_"*(width+2) b.WriteString(" ") b.WriteString(strings.Repeat("_", width+2)) b.WriteString("\n") n := len(lines) for i, ln := range lines { left, right := borderChars(i, n) b.WriteString(left) b.WriteString(" ") b.WriteString(ln) b.WriteString(strings.Repeat(" ", width-len(ln))) b.WriteString(" ") b.WriteString(right) b.WriteString("\n") } // bottom border: " " + "-"*(width+2) b.WriteString(" ") b.WriteString(strings.Repeat("-", width+2)) b.WriteString("\n") return b.String() } // borderChars picks the left/right bubble characters for line i of n. // Single line uses < >. Multi-line uses / \ for the first row, // \ / for the last row, and | | for the middle rows. func borderChars(i, n int) (string, string) { if n == 1 { return "<", ">" } switch i { case 0: return "/", "\\" case n - 1: return "\\", "/" default: return "|", "|" } } // wrap splits text into lines no longer than width, breaking on spaces. // Words longer than width are hard-split. func wrap(text string, width int) []string { words := strings.Fields(text) if len(words) == 0 { return []string{""} } var lines []string cur := "" for _, w := range words { // hard-split a single word that is too long for len(w) > width { if cur != "" { lines = append(lines, cur) cur = "" } lines = append(lines, w[:width]) w = w[width:] } if cur == "" { cur = w } else if len(cur)+1+len(w) <= width { cur = cur + " " + w } else { lines = append(lines, cur) cur = w } } if cur != "" { lines = append(lines, cur) } return lines } // maxLen returns the length of the longest line. func maxLen(lines []string) int { m := 0 for _, ln := range lines { if len(ln) > m { m = len(ln) } } return m } // cow is the classic happy cow, aligned under the bubble. const cow = ` \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || `
- #6gnomod.toml
- #7module = "gno.land/p/moul/x/daily/cowsay/v0" gno = "0.9"
- #8/gno.MemPackageType
- #9 MPUserProd
Result log
msg:0,success:true,log:,events:[]