[
  {
    "path": ".github/CODEOWNERS",
    "content": "* @Code-Hex"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: Code-Hex\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"daily\"\n  - package-ecosystem: \"gomod\"\n    directory: \"/\"\n    schedule:\n      interval: \"daily\"\n"
  },
  {
    "path": ".github/workflows/lgtm.yml",
    "content": "on:\n  pull_request_review:\n    types:\n      - submitted\n\njobs:\n  lgtm:\n    name: LGTM\n    runs-on: ubuntu-latest\n    if: github.event.review.state == 'approved'\n    steps:\n    - name: Cowsay LGTM\n      uses: Code-Hex/neo-cowsay-action@v1.0.2\n      with:\n        message: 'LGTM'\n        cow: 'random'\n        cowsay_on_comment: true\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "on:\n  push:\n    branches:\n      - \"master\"\n  pull_request:\n\njobs:\n  test:\n    strategy:\n      matrix:\n        os: [ubuntu-latest, windows-latest]\n    name: test\n    runs-on: ${{ matrix.os }}\n    steps:\n    - name: Setup Go 1.17.2\n      uses: actions/setup-go@v2\n      with:\n        go-version: 1.17.2\n    - name: Check out code into the Go module directory\n      uses: actions/checkout@v3\n    - name: Vet\n      run: make vet\n    - name: Test\n      run: make test\n    - name: Lint\n      if: matrix.os == 'ubuntu-latest'\n      run: |\n        go get golang.org/x/lint/golint\n        export PATH=\"$PATH:$(go env GOPATH)/bin\"\n        make lint\n      env:\n        GO111MODULE: off\n    - name: Declare some variables\n      if: matrix.os == 'ubuntu-latest'\n      id: vars\n      run: |\n        echo \"::set-output name=coverage_txt::${RUNNER_TEMP}/coverage.txt\"\n    - name: Test Coverage (pkg)\n      if: matrix.os == 'ubuntu-latest'\n      run: go test ./... -coverprofile=${{ steps.vars.outputs.coverage_txt }}\n    - name: Upload coverage\n      if: matrix.os == 'ubuntu-latest'\n      uses: codecov/codecov-action@v3\n      with:\n        files: ${{ steps.vars.outputs.coverage_txt }}"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "on:\n  push:\n    tags:\n      - \"v*.*.*\"\n\njobs:\n  release:\n    name: Release\n    runs-on: ubuntu-latest\n    steps:\n    - name: Setup Go 1.17.2\n      uses: actions/setup-go@v2\n      with:\n        go-version: 1.17.2\n    - name: Check out code into the Go module directory\n      uses: actions/checkout@v3\n    - name: Run GoReleaser\n      if: contains(github.ref, 'tags/v')\n      uses: goreleaser/goreleaser-action@v2\n      with:\n        version: latest\n        args: release --rm-dist\n      env:\n        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}\n\n  winget:\n    runs-on: ubuntu-latest\n    needs: release\n    steps:\n      - uses: vedantmgoyal2009/winget-releaser@v2\n        with:\n          identifier: codehex.Neo-cowsay\n          installers-regex: '_Windows_\\w+\\.zip$'\n          token: ${{ secrets.WINGET_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*.prof\n\ngithub-token\nbuild\nreleases\nbin/*\n!bin/.gitkeep\n"
  },
  {
    "path": ".goreleaser.yml",
    "content": "builds:\n  - id: cowsay\n    dir: cmd\n    main: ./cowsay/main.go\n    binary: cowsay\n    env:\n      - CGO_ENABLED=0\n    ldflags: -s -w -X main.version={{.Version}}\n    goos:\n      - linux\n      - darwin\n      - windows\n    goarch:\n      - 386\n      - amd64\n      - arm\n      - arm64\n    goarm:\n      - 6\n      - 7\n    ignore:\n      - goos: darwin\n        goarch: 386\n      - goos: linux\n        goarch: arm\n        goarm: 7\n      - goos: windows\n        goarch: arm\n        goarm: 7\n  - id: cowthink\n    dir: cmd\n    main: ./cowthink/main.go\n    binary: cowthink\n    env:\n      - CGO_ENABLED=0\n    ldflags: -s -w -X main.version={{.Version}}\n    goos:\n      - linux\n      - darwin\n      - windows\n    goarch:\n      - 386\n      - amd64\n      - arm\n      - arm64\n    goarm:\n      - 6\n      - 7\n    ignore:\n      - goos: darwin\n        goarch: 386\n      - goos: linux\n        goarch: arm\n        goarm: 7\n      - goos: windows\n        goarch: arm\n        goarm: 7\n\narchives:\n- builds:\n  - cowsay\n  - cowthink\n  name_template: 'cowsay_{{ .Version }}_{{ .Os }}_{{ .Arch }}'\n  replacements:\n    darwin: macOS\n    linux: Linux\n    windows: Windows\n    386: i386\n    amd64: x86_64\n  format_overrides:\n  - goos: windows\n    format: zip\n  files:\n  - LICENSE\n  - doc/cowsay.1\n\nbrews:\n- name: neo-cowsay\n  tap:\n    owner: Code-Hex\n    name: homebrew-tap\n    token: \"{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}\"\n  homepage: https://github.com/Code-Hex/Neo-cowsay\n  description: \"Fast, funny, everyone wanted? new cowsay!!\"\n  folder: Formula\n  install: |\n    bin.install \"cowsay\"\n    bin.install \"cowthink\"\n    man1.install Dir[\"doc/cowsay.1\"]\n\nnfpms:\n  - license: Artistic License 2.0\n    maintainer: Kei Kamikawa <x00.x7f.x86@gmail.com>\n    homepage: https://github.com/Code-Hex/Neo-cowsay\n    bindir: /usr/local/bin\n    description: \"Fast, funny, everyone wanted? new cowsay!!\"\n    formats:\n      - apk\n      - deb\n      - rpm\n    contents:\n      - src: \"doc/cowsay.1\"\n        dst: \"/usr/share/man/man1/cowsay.1\"\n\nchecksum:\n  name_template: 'cowsay_checksums.txt'\n\nchangelog:\n  sort: asc\n  filters:\n    exclude:\n    - '^docs:'\n    - '^test:'\n    - Merge pull request\n    - Merge branch\n"
  },
  {
    "path": "LICENSE",
    "content": "\t\t       The Artistic License 2.0\n\n\t    Copyright (c) 2000-2006, The Perl Foundation.\n\n     Everyone is permitted to copy and distribute verbatim copies\n      of this license document, but changing it is not allowed.\n\nPreamble\n\nThis license establishes the terms under which a given free software\nPackage may be copied, modified, distributed, and/or redistributed.\nThe intent is that the Copyright Holder maintains some artistic\ncontrol over the development of that Package while still keeping the\nPackage available as open source and free software.\n\nYou are always permitted to make arrangements wholly outside of this\nlicense directly with the Copyright Holder of a given Package.  If the\nterms of this license do not permit the full use that you propose to\nmake of the Package, you should contact the Copyright Holder and seek\na different licensing arrangement.\n\nDefinitions\n\n    \"Copyright Holder\" means the individual(s) or organization(s)\n    named in the copyright notice for the entire Package.\n\n    \"Contributor\" means any party that has contributed code or other\n    material to the Package, in accordance with the Copyright Holder's\n    procedures.\n\n    \"You\" and \"your\" means any person who would like to copy,\n    distribute, or modify the Package.\n\n    \"Package\" means the collection of files distributed by the\n    Copyright Holder, and derivatives of that collection and/or of\n    those files. A given Package may consist of either the Standard\n    Version, or a Modified Version.\n\n    \"Distribute\" means providing a copy of the Package or making it\n    accessible to anyone else, or in the case of a company or\n    organization, to others outside of your company or organization.\n\n    \"Distributor Fee\" means any fee that you charge for Distributing\n    this Package or providing support for this Package to another\n    party.  It does not mean licensing fees.\n\n    \"Standard Version\" refers to the Package if it has not been\n    modified, or has been modified only in ways explicitly requested\n    by the Copyright Holder.\n\n    \"Modified Version\" means the Package, if it has been changed, and\n    such changes were not explicitly requested by the Copyright\n    Holder.\n\n    \"Original License\" means this Artistic License as Distributed with\n    the Standard Version of the Package, in its current version or as\n    it may be modified by The Perl Foundation in the future.\n\n    \"Source\" form means the source code, documentation source, and\n    configuration files for the Package.\n\n    \"Compiled\" form means the compiled bytecode, object code, binary,\n    or any other form resulting from mechanical transformation or\n    translation of the Source form.\n\n\nPermission for Use and Modification Without Distribution\n\n(1)  You are permitted to use the Standard Version and create and use\nModified Versions for any purpose without restriction, provided that\nyou do not Distribute the Modified Version.\n\n\nPermissions for Redistribution of the Standard Version\n\n(2)  You may Distribute verbatim copies of the Source form of the\nStandard Version of this Package in any medium without restriction,\neither gratis or for a Distributor Fee, provided that you duplicate\nall of the original copyright notices and associated disclaimers.  At\nyour discretion, such verbatim copies may or may not include a\nCompiled form of the Package.\n\n(3)  You may apply any bug fixes, portability changes, and other\nmodifications made available from the Copyright Holder.  The resulting\nPackage will still be considered the Standard Version, and as such\nwill be subject to the Original License.\n\n\nDistribution of Modified Versions of the Package as Source\n\n(4)  You may Distribute your Modified Version as Source (either gratis\nor for a Distributor Fee, and with or without a Compiled form of the\nModified Version) provided that you clearly document how it differs\nfrom the Standard Version, including, but not limited to, documenting\nany non-standard features, executables, or modules, and provided that\nyou do at least ONE of the following:\n\n    (a)  make the Modified Version available to the Copyright Holder\n    of the Standard Version, under the Original License, so that the\n    Copyright Holder may include your modifications in the Standard\n    Version.\n\n    (b)  ensure that installation of your Modified Version does not\n    prevent the user installing or running the Standard Version. In\n    addition, the Modified Version must bear a name that is different\n    from the name of the Standard Version.\n\n    (c)  allow anyone who receives a copy of the Modified Version to\n    make the Source form of the Modified Version available to others\n    under\n\n\t(i)  the Original License or\n\n\t(ii)  a license that permits the licensee to freely copy,\n\tmodify and redistribute the Modified Version using the same\n\tlicensing terms that apply to the copy that the licensee\n\treceived, and requires that the Source form of the Modified\n\tVersion, and of any works derived from it, be made freely\n\tavailable in that license fees are prohibited but Distributor\n\tFees are allowed.\n\n\nDistribution of Compiled Forms of the Standard Version\nor Modified Versions without the Source\n\n(5)  You may Distribute Compiled forms of the Standard Version without\nthe Source, provided that you include complete instructions on how to\nget the Source of the Standard Version.  Such instructions must be\nvalid at the time of your distribution.  If these instructions, at any\ntime while you are carrying out such distribution, become invalid, you\nmust provide new instructions on demand or cease further distribution.\nIf you provide valid instructions or cease distribution within thirty\ndays after you become aware that the instructions are invalid, then\nyou do not forfeit any of your rights under this license.\n\n(6)  You may Distribute a Modified Version in Compiled form without\nthe Source, provided that you comply with Section 4 with respect to\nthe Source of the Modified Version.\n\n\nAggregating or Linking the Package\n\n(7)  You may aggregate the Package (either the Standard Version or\nModified Version) with other packages and Distribute the resulting\naggregation provided that you do not charge a licensing fee for the\nPackage.  Distributor Fees are permitted, and licensing fees for other\ncomponents in the aggregation are permitted. The terms of this license\napply to the use and Distribution of the Standard or Modified Versions\nas included in the aggregation.\n\n(8) You are permitted to link Modified and Standard Versions with\nother works, to embed the Package in a larger work of your own, or to\nbuild stand-alone binary or bytecode versions of applications that\ninclude the Package, and Distribute the result without restriction,\nprovided the result does not expose a direct interface to the Package.\n\n\nItems That are Not Considered Part of a Modified Version\n\n(9) Works (including, but not limited to, modules and scripts) that\nmerely extend or make use of the Package, do not, by themselves, cause\nthe Package to be a Modified Version.  In addition, such works are not\nconsidered parts of the Package itself, and are not subject to the\nterms of this license.\n\n\nGeneral Provisions\n\n(10)  Any use, modification, and distribution of the Standard or\nModified Versions is governed by this Artistic License. By using,\nmodifying or distributing the Package, you accept this license. Do not\nuse, modify, or distribute the Package, if you do not accept this\nlicense.\n\n(11)  If your Modified Version has been derived from a Modified\nVersion made by someone other than you, you are nevertheless required\nto ensure that your Modified Version complies with the requirements of\nthis license.\n\n(12)  This license does not grant you the right to use any trademark,\nservice mark, tradename, or logo of the Copyright Holder.\n\n(13)  This license includes the non-exclusive, worldwide,\nfree-of-charge patent license to make, have made, use, offer to sell,\nsell, import and otherwise transfer the Package with respect to any\npatent claims licensable by the Copyright Holder that are necessarily\ninfringed by the Package. If you institute patent litigation\n(including a cross-claim or counterclaim) against any party alleging\nthat the Package constitutes direct or contributory patent\ninfringement, then this Artistic License to you shall terminate on the\ndate that such litigation is filed.\n\n(14)  Disclaimer of Warranty:\nTHE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS \"AS\nIS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED\nWARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR\nNON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL\nLAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL\nBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF\nADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
  },
  {
    "path": "Makefile",
    "content": ".PHONY: build\nbuild: build/cowsay build/cowthink\n\n.PHONY: build/cowsay\nbuild/cowsay:\n\tCGO_ENABLED=0 cd cmd && go build -o ../bin/cowsay -ldflags \"-w -s\" ./cowsay\n\n.PHONY: build/cowthink\nbuild/cowthink:\n\tCGO_ENABLED=0 cd cmd && go build -o ../bin/cowthink -ldflags \"-w -s\" ./cowthink\n\n.PHONY: lint\nlint:\n\tgolint ./...\n\tcd cmd && golint ./...\n\n.PHONY: vet\nvet:\n\tgo vet ./...\n\tcd cmd && go vet ./...\n\n.PHONY: test\ntest: test/pkg test/cli\n\n.PHONY: test/pkg\ntest/pkg:\n\tgo test ./...\n\n.PHONY: test/cli\ntest/cli:\n\tcd cmd && go test ./...\n\n.PHONY: man\nman:\n\tasciidoctor --doctype manpage --backend manpage doc/cowsay.1.txt.tpl -o doc/cowsay.1\n\n.PHONY: man/preview\nman/preview:\n\tcat doc/cowsay.1 | groff -man -Tascii | less\n"
  },
  {
    "path": "README.md",
    "content": "# Neo Cowsay\n\nNeo Cowsay is written in Go. This cowsay is extended the original cowsay. added fun more options, and you can be used as a library.\n\nfor GitHub Actions users: [Code-Hex/neo-cowsay-action](https://github.com/marketplace/actions/neo-cowsay)\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/Code-Hex/Neo-cowsay/v2.svg)](https://pkg.go.dev/github.com/Code-Hex/Neo-cowsay/v2) [![.github/workflows/main.yml](https://github.com/Code-Hex/Neo-cowsay/actions/workflows/main.yml/badge.svg)](https://github.com/Code-Hex/Neo-cowsay/actions/workflows/main.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/Code-Hex/Neo-cowsay)](https://goreportcard.com/report/github.com/Code-Hex/Neo-cowsay) [![codecov](https://codecov.io/gh/Code-Hex/Neo-cowsay/branch/master/graph/badge.svg?token=WwjmyHrOPv)](https://codecov.io/gh/Code-Hex/Neo-cowsay)\n\n```\n ______________\n< I'm Neo cows >\n --------------\n       \\   ^__^\n        \\  (oo)\\_______\n           (__)\\       )\\/\\\n               ||----w |\n               ||     ||\n```\n\n## About cowsay\n\nAccording to the [original](https://web.archive.org/web/20071026043648/http://www.nog.net/~tony/warez/cowsay.shtml) original manual.\n\n```\ncowsay is a configurable talking cow, written in Perl. It operates\nmuch as the figlet program does, and it written in the same spirit\nof silliness.\n```\n\nThis is also supported `COWPATH` env. Please read more details in [#33](https://github.com/Code-Hex/Neo-cowsay/pull/33) if you want to use this.\n\n## What makes it different from the original?\n\n- fast\n- utf8 is supported\n- new some cowfiles is added\n- cowfiles in binary\n- random pickup cowfile option\n- provides command-line fuzzy finder to search any cows with `-f -` [#39](https://github.com/Code-Hex/Neo-cowsay/pull/39)\n- coloring filter options\n- super mode\n\n<details>\n<summary>Movies for new options 🐮</summary>\n\n### Random\n\n[![asciicast](https://asciinema.org/a/228210.svg)](https://asciinema.org/a/228210)\n\n### Rainbow and Aurora, Bold\n\n[![asciicast](https://asciinema.org/a/228213.svg)](https://asciinema.org/a/228213)\n\n## And, Super Cows mode\n\nhttps://user-images.githubusercontent.com/6500104/140379043-53e44994-b1b0-442e-bda7-4f7ab3aedf01.mov\n\n</details>\n\n## Usage\n\n### As command\n\n```\ncow{say,think} version 2.0.0, (c) 2021 codehex\nUsage: cowsay [-bdgpstwy] [-h] [-e eyes] [-f cowfile] [--random]\n      [-l] [-n] [-T tongue] [-W wrapcolumn]\n      [--bold] [--rainbow] [--aurora] [--super] [message]\n\nOriginal Author: (c) 1999 Tony Monroe\nRepository: https://github.com/Code-Hex/Neo-cowsay\n```\nNormal\n```\n$ cowsay Hello\n _______\n< Hello >\n -------\n       \\   ^__^\n        \\  (oo)\\_______\n           (__)\\       )\\/\\\n               ||----w |\n               ||     ||\n```\nBorg mode\n```\n$ cowsay -b Hello\n _______\n< Hello >\n -------\n       \\   ^__^\n        \\  (==)\\_______\n           (__)\\       )\\/\\\n               ||----w |\n               ||     ||\n```\n\n### As library\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\tcowsay \"github.com/Code-Hex/Neo-cowsay/v2\"\n)\n\nfunc main() {\n\tsay, err := cowsay.Say(\n\t\t\"Hello\",\n\t\tcowsay.Type(\"default\"),\n\t\tcowsay.BallonWidth(40),\n\t)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(say)\n}\n```\n\n[Examples](https://github.com/Code-Hex/Neo-cowsay/blob/master/examples) or [GoDoc](https://pkg.go.dev/github.com/Code-Hex/Neo-cowsay/v2)\n\n## Install\n\n### Windows users via Scoop\n\n    $ scoop install neo-cowsay\n\n### Windows users via Winget\n\n    $ winget install neo-cowsay\n\n### Mac and Linux users via Homebrew\n\n    $ brew update\n    $ brew install Code-Hex/tap/neo-cowsay\n\n### Binary\n\nYou can download from [here](https://github.com/Code-Hex/Neo-cowsay/releases)\n\n### library\n\n    $ go get github.com/Code-Hex/Neo-cowsay/v2\n\n### Go\n\n#### cowsay\n\n    $ go install github.com/Code-Hex/Neo-cowsay/cmd/v2/cowsay@latest\n\n#### cowthink\n\n    $ go install github.com/Code-Hex/Neo-cowsay/cmd/v2/cowthink@latest\n\n## License\n\n<details>\n<summary>cowsay license</summary>\n\n```\n==============\ncowsay License\n==============\n\ncowsay is distributed under the same licensing terms as Perl: the\nArtistic License or the GNU General Public License.  If you don't\nwant to track down these licenses and read them for yourself, use\nthe parts that I'd prefer:\n\n(0) I wrote it and you didn't.\n\n(1) Give credit where credit is due if you borrow the code for some\nother purpose.\n\n(2) If you have any bugfixes or suggestions, please notify me so\nthat I may incorporate them.\n\n(3) If you try to make money off of cowsay, you suck.\n\n===============\ncowsay Legalese\n===============\n\n(0) Copyright (c) 1999 Tony Monroe.  All rights reserved.  All\nlefts may or may not be reversed at my discretion.\n\n(1) This software package can be freely redistributed or modified\nunder the terms described above in the \"cowsay License\" section\nof this file.\n\n(2) cowsay is provided \"as is,\" with no warranties whatsoever,\nexpressed or implied.  If you want some implied warranty about\nmerchantability and/or fitness for a particular purpose, you will\nnot find it here, because there is no such thing here.\n\n(3) I hate legalese.\n```\n\n</details>\n\n(The Artistic License or The GNU General Public License)\n\n## Author\nNeo Cowsay: [codehex](https://twitter.com/CodeHex)  \nOriginal: (c) 1999 Tony Monroe\n"
  },
  {
    "path": "balloon.go",
    "content": "package cowsay\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\twordwrap \"github.com/Code-Hex/go-wordwrap\"\n\trunewidth \"github.com/mattn/go-runewidth\"\n)\n\ntype border struct {\n\tfirst  [2]rune\n\tmiddle [2]rune\n\tlast   [2]rune\n\tonly   [2]rune\n}\n\nfunc (cow *Cow) borderType() border {\n\tif cow.thinking {\n\t\treturn border{\n\t\t\tfirst:  [2]rune{'(', ')'},\n\t\t\tmiddle: [2]rune{'(', ')'},\n\t\t\tlast:   [2]rune{'(', ')'},\n\t\t\tonly:   [2]rune{'(', ')'},\n\t\t}\n\t}\n\n\treturn border{\n\t\tfirst:  [2]rune{'/', '\\\\'},\n\t\tmiddle: [2]rune{'|', '|'},\n\t\tlast:   [2]rune{'\\\\', '/'},\n\t\tonly:   [2]rune{'<', '>'},\n\t}\n}\n\ntype line struct {\n\ttext      string\n\truneWidth int\n}\n\ntype lines []*line\n\nfunc (cow *Cow) maxLineWidth(lines []*line) int {\n\tmaxWidth := 0\n\tfor _, line := range lines {\n\t\tif line.runeWidth > maxWidth {\n\t\t\tmaxWidth = line.runeWidth\n\t\t}\n\t\tif !cow.disableWordWrap && maxWidth > cow.ballonWidth {\n\t\t\treturn cow.ballonWidth\n\t\t}\n\t}\n\treturn maxWidth\n}\n\nfunc (cow *Cow) getLines(phrase string) []*line {\n\ttext := cow.canonicalizePhrase(phrase)\n\tlineTexts := strings.Split(text, \"\\n\")\n\tlines := make([]*line, 0, len(lineTexts))\n\tfor _, lineText := range lineTexts {\n\t\tlines = append(lines, &line{\n\t\t\ttext:      lineText,\n\t\t\truneWidth: runewidth.StringWidth(lineText),\n\t\t})\n\t}\n\treturn lines\n}\n\nfunc (cow *Cow) canonicalizePhrase(phrase string) string {\n\t// Replace tab to 8 spaces\n\tphrase = strings.Replace(phrase, \"\\t\", \"       \", -1)\n\n\tif cow.disableWordWrap {\n\t\treturn phrase\n\t}\n\twidth := cow.ballonWidth\n\treturn wordwrap.WrapString(phrase, uint(width))\n}\n\n// Balloon to get the balloon and the string entered in the balloon.\nfunc (cow *Cow) Balloon(phrase string) string {\n\tdefer cow.buf.Reset()\n\n\tlines := cow.getLines(phrase)\n\tmaxWidth := cow.maxLineWidth(lines)\n\n\tcow.writeBallon(lines, maxWidth)\n\n\treturn cow.buf.String()\n}\n\nfunc (cow *Cow) writeBallon(lines []*line, maxWidth int) {\n\ttop := make([]byte, 0, maxWidth+2)\n\tbottom := make([]byte, 0, maxWidth+2)\n\n\ttop = append(top, ' ')\n\tbottom = append(bottom, ' ')\n\n\tfor i := 0; i < maxWidth+2; i++ {\n\t\ttop = append(top, '_')\n\t\tbottom = append(bottom, '-')\n\t}\n\n\tborderType := cow.borderType()\n\n\tcow.buf.Write(top)\n\tcow.buf.Write([]byte{' ', '\\n'})\n\tdefer func() {\n\t\tcow.buf.Write(bottom)\n\t\tcow.buf.Write([]byte{' ', '\\n'})\n\t}()\n\n\tl := len(lines)\n\tif l == 1 {\n\t\tborder := borderType.only\n\t\tcow.buf.WriteRune(border[0])\n\t\tcow.buf.WriteRune(' ')\n\t\tcow.buf.WriteString(lines[0].text)\n\t\tcow.buf.WriteRune(' ')\n\t\tcow.buf.WriteRune(border[1])\n\t\tcow.buf.WriteRune('\\n')\n\t\treturn\n\t}\n\n\tvar border [2]rune\n\tfor i := 0; i < l; i++ {\n\t\tswitch i {\n\t\tcase 0:\n\t\t\tborder = borderType.first\n\t\tcase l - 1:\n\t\t\tborder = borderType.last\n\t\tdefault:\n\t\t\tborder = borderType.middle\n\t\t}\n\t\tcow.buf.WriteRune(border[0])\n\t\tcow.buf.WriteRune(' ')\n\t\tcow.padding(lines[i], maxWidth)\n\t\tcow.buf.WriteRune(' ')\n\t\tcow.buf.WriteRune(border[1])\n\t\tcow.buf.WriteRune('\\n')\n\t}\n}\n\nfunc (cow *Cow) flush(text, top, bottom fmt.Stringer) string {\n\treturn fmt.Sprintf(\n\t\t\"%s\\n%s%s\\n\",\n\t\ttop.String(),\n\t\ttext.String(),\n\t\tbottom.String(),\n\t)\n}\n\nfunc (cow *Cow) padding(line *line, maxWidth int) {\n\tif maxWidth <= line.runeWidth {\n\t\tcow.buf.WriteString(line.text)\n\t\treturn\n\t}\n\n\tcow.buf.WriteString(line.text)\n\tl := maxWidth - line.runeWidth\n\tfor i := 0; i < l; i++ {\n\t\tcow.buf.WriteRune(' ')\n\t}\n}\n"
  },
  {
    "path": "bin/.gitkeep",
    "content": ""
  },
  {
    "path": "cmd/cmd.go",
    "content": "package cmd\n"
  },
  {
    "path": "cmd/cowsay/main.go",
    "content": "package main\n\nimport (\n\t\"os\"\n\n\t\"github.com/Code-Hex/Neo-cowsay/cmd/v2/internal/cli\"\n)\n\nvar version string\n\nfunc main() {\n\tos.Exit((&cli.CLI{\n\t\tVersion:  version,\n\t\tThinking: false,\n\t}).Run(os.Args[1:]))\n}\n"
  },
  {
    "path": "cmd/cowthink/main.go",
    "content": "package main\n\nimport (\n\t\"os\"\n\n\t\"github.com/Code-Hex/Neo-cowsay/cmd/v2/internal/cli\"\n)\n\nvar version string\n\nfunc main() {\n\tos.Exit((&cli.CLI{\n\t\tVersion:  version,\n\t\tThinking: true,\n\t}).Run(os.Args[1:]))\n}\n"
  },
  {
    "path": "cmd/go.mod",
    "content": "module github.com/Code-Hex/Neo-cowsay/cmd/v2\n\ngo 1.16\n\nrequire (\n\tgithub.com/Code-Hex/Neo-cowsay/v2 v2.0.3\n\tgithub.com/Code-Hex/go-wordwrap v1.0.0\n\tgithub.com/google/go-cmp v0.5.6\n\tgithub.com/jessevdk/go-flags v1.5.0\n\tgithub.com/ktr0731/go-fuzzyfinder v0.5.1\n\tgithub.com/mattn/go-colorable v0.1.11\n\tgithub.com/mattn/go-runewidth v0.0.13\n\tgithub.com/rivo/uniseg v0.2.0\n\tgolang.org/x/crypto v0.1.0\n)\n\nreplace github.com/Code-Hex/Neo-cowsay/v2 => ../\n"
  },
  {
    "path": "cmd/go.sum",
    "content": "github.com/Code-Hex/go-wordwrap v1.0.0 h1:yl5fLyZEz3+hPGbpTRlTQ8mQJ1HXWcTq1FCNR1ch6zM=\ngithub.com/Code-Hex/go-wordwrap v1.0.0/go.mod h1:/SsbgkY2Q0aPQRyvXcyQwWYTQOIwSORKe6MPjRVGIWU=\ngithub.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=\ngithub.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=\ngithub.com/gdamore/tcell/v2 v2.4.0 h1:W6dxJEmaxYvhICFoTY3WrLLEXsQ11SaFnKGVEXW57KM=\ngithub.com/gdamore/tcell/v2 v2.4.0/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6oBpwHp4fU=\ngithub.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=\ngithub.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=\ngithub.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=\ngithub.com/ktr0731/go-fuzzyfinder v0.5.1 h1:rDcWxmGi6ux4NURekn9iAXpbYBp8Kj4cznrz162S9og=\ngithub.com/ktr0731/go-fuzzyfinder v0.5.1/go.mod h1:gud27uRG2vF+oD58eGhYZj7Pc9enRX0qecwp09w/jno=\ngithub.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=\ngithub.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=\ngithub.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=\ngithub.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=\ngithub.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=\ngithub.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=\ngithub.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=\ngithub.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=\ngithub.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=\ngithub.com/nsf/termbox-go v0.0.0-20201124104050-ed494de23a00 h1:Rl8NelBe+n7SuLbJyw13ho7CGWUt2BjGGKIoreCWQ/c=\ngithub.com/nsf/termbox-go v0.0.0-20201124104050-ed494de23a00/go.mod h1:T0cTdVuOwf7pHQNtfhnEbzHbcNyCEcVU4YPpouCbVxo=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=\ngithub.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=\ngithub.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=\ngolang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=\ngolang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=\ngolang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=\ngolang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\n"
  },
  {
    "path": "cmd/internal/cli/cli.go",
    "content": "package cli\n\nimport (\n\t\"bufio\"\n\tcryptorand \"crypto/rand\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"math/big\"\n\t\"math/rand\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/Code-Hex/Neo-cowsay/cmd/v2/internal/super\"\n\tcowsay \"github.com/Code-Hex/Neo-cowsay/v2\"\n\t\"github.com/Code-Hex/Neo-cowsay/v2/decoration\"\n\t\"github.com/Code-Hex/go-wordwrap\"\n\t\"github.com/jessevdk/go-flags\"\n\t\"github.com/ktr0731/go-fuzzyfinder\"\n\t\"github.com/mattn/go-colorable\"\n)\n\nfunc init() {\n\t// safely set the seed globally so we generate random ids. Tries to use a\n\t// crypto seed before falling back to time.\n\tvar seed int64\n\tcryptoseed, err := cryptorand.Int(cryptorand.Reader, big.NewInt(math.MaxInt64))\n\tif err != nil {\n\t\t// This should not happen, but worst-case fallback to time-based seed.\n\t\tseed = time.Now().UnixNano()\n\t} else {\n\t\tseed = cryptoseed.Int64()\n\t}\n\trand.Seed(seed)\n}\n\n// options struct for parse command line arguments\ntype options struct {\n\tHelp     bool   `short:\"h\"`\n\tEyes     string `short:\"e\"`\n\tTongue   string `short:\"T\"`\n\tWidth    int    `short:\"W\"`\n\tBorg     bool   `short:\"b\"`\n\tDead     bool   `short:\"d\"`\n\tGreedy   bool   `short:\"g\"`\n\tParanoia bool   `short:\"p\"`\n\tStoned   bool   `short:\"s\"`\n\tTired    bool   `short:\"t\"`\n\tWired    bool   `short:\"w\"`\n\tYouthful bool   `short:\"y\"`\n\tList     bool   `short:\"l\"`\n\tNewLine  bool   `short:\"n\"`\n\tFile     string `short:\"f\"`\n\tBold     bool   `long:\"bold\"`\n\tSuper    bool   `long:\"super\"`\n\tRandom   bool   `long:\"random\"`\n\tRainbow  bool   `long:\"rainbow\"`\n\tAurora   bool   `long:\"aurora\"`\n}\n\n// CLI prepare for running command-line.\ntype CLI struct {\n\tVersion  string\n\tThinking bool\n\tstderr   io.Writer\n\tstdout   io.Writer\n\tstdin    io.Reader\n}\n\nfunc (c *CLI) program() string {\n\tif c.Thinking {\n\t\treturn \"cowthink\"\n\t}\n\treturn \"cowsay\"\n}\n\n// Run runs command-line.\nfunc (c *CLI) Run(argv []string) int {\n\tif c.stderr == nil {\n\t\tc.stderr = os.Stderr\n\t}\n\tif c.stdout == nil {\n\t\tc.stdout = colorable.NewColorableStdout()\n\t}\n\tif c.stdin == nil {\n\t\tc.stdin = os.Stdin\n\t}\n\tif err := c.mow(argv); err != nil {\n\t\tfmt.Fprintf(c.stderr, \"%s: %s\\n\", c.program(), err.Error())\n\t\treturn 1\n\t}\n\treturn 0\n}\n\n// mow will parsing for cowsay command line arguments and invoke cowsay.\nfunc (c *CLI) mow(argv []string) error {\n\tvar opts options\n\targs, err := c.parseOptions(&opts, argv)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif opts.List {\n\t\tcowPaths, err := cowsay.Cows()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfor _, cowPath := range cowPaths {\n\t\t\tif cowPath.LocationType == cowsay.InBinary {\n\t\t\t\tfmt.Fprintf(c.stdout, \"Cow files in binary:\\n\")\n\t\t\t} else {\n\t\t\t\tfmt.Fprintf(c.stdout, \"Cow files in %s:\\n\", cowPath.Name)\n\t\t\t}\n\t\t\tfmt.Fprintln(c.stdout, wordwrap.WrapString(strings.Join(cowPath.CowFiles, \" \"), 80))\n\t\t\tfmt.Fprintln(c.stdout)\n\t\t}\n\t\treturn nil\n\t}\n\n\tif err := c.mowmow(&opts, args); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (c *CLI) parseOptions(opts *options, argv []string) ([]string, error) {\n\tp := flags.NewParser(opts, flags.None)\n\targs, err := p.ParseArgs(argv)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif opts.Help {\n\t\tc.stdout.Write(c.usage())\n\t\tos.Exit(0)\n\t}\n\n\treturn args, nil\n}\n\nfunc (c *CLI) usage() []byte {\n\tyear := strconv.Itoa(time.Now().Year())\n\treturn []byte(c.program() + ` version ` + c.Version + `, (c) ` + year + ` codehex\nUsage: ` + c.program() + ` [-bdgpstwy] [-h] [-e eyes] [-f cowfile] [--random]\n          [-l] [-n] [-T tongue] [-W wrapcolumn]\n          [--bold] [--rainbow] [--aurora] [--super] [message]\n\nOriginal Author: (c) 1999 Tony Monroe\n`)\n}\n\nfunc (c *CLI) generateOptions(opts *options) []cowsay.Option {\n\to := make([]cowsay.Option, 0, 8)\n\tif opts.File == \"-\" {\n\t\tcows := cowList()\n\t\tidx, _ := fuzzyfinder.Find(cows, func(i int) string {\n\t\t\treturn cows[i]\n\t\t})\n\t\topts.File = cows[idx]\n\t}\n\to = append(o, cowsay.Type(opts.File))\n\tif c.Thinking {\n\t\to = append(o,\n\t\t\tcowsay.Thinking(),\n\t\t\tcowsay.Thoughts('o'),\n\t\t)\n\t}\n\tif opts.Random {\n\t\to = append(o, cowsay.Random())\n\t}\n\tif opts.Eyes != \"\" {\n\t\to = append(o, cowsay.Eyes(opts.Eyes))\n\t}\n\tif opts.Tongue != \"\" {\n\t\to = append(o, cowsay.Tongue(opts.Tongue))\n\t}\n\tif opts.Width > 0 {\n\t\to = append(o, cowsay.BallonWidth(uint(opts.Width)))\n\t}\n\tif opts.NewLine {\n\t\to = append(o, cowsay.DisableWordWrap())\n\t}\n\treturn selectFace(opts, o)\n}\n\nfunc cowList() []string {\n\tcows, err := cowsay.Cows()\n\tif err != nil {\n\t\treturn cowsay.CowsInBinary()\n\t}\n\tlist := make([]string, 0)\n\tfor _, cow := range cows {\n\t\tlist = append(list, cow.CowFiles...)\n\t}\n\treturn list\n}\n\nfunc (c *CLI) phrase(opts *options, args []string) string {\n\tif len(args) > 0 {\n\t\treturn strings.Join(args, \" \")\n\t}\n\tlines := make([]string, 0, 40)\n\tscanner := bufio.NewScanner(c.stdin)\n\tfor scanner.Scan() {\n\t\tlines = append(lines, scanner.Text())\n\t}\n\treturn strings.Join(lines, \"\\n\")\n}\n\nfunc (c *CLI) mowmow(opts *options, args []string) error {\n\tphrase := c.phrase(opts, args)\n\to := c.generateOptions(opts)\n\tif opts.Super {\n\t\treturn super.RunSuperCow(phrase, opts.Bold, o...)\n\t}\n\n\tsay, err := cowsay.Say(phrase, o...)\n\tif err != nil {\n\t\tvar notfound *cowsay.NotFound\n\t\tif errors.As(err, &notfound) {\n\t\t\treturn fmt.Errorf(\"could not find %s cowfile\", notfound.Cowfile)\n\t\t}\n\t\treturn err\n\t}\n\n\toptions := make([]decoration.Option, 0)\n\n\tif opts.Bold {\n\t\toptions = append(options, decoration.WithBold())\n\t}\n\tif opts.Rainbow {\n\t\toptions = append(options, decoration.WithRainbow())\n\t}\n\tif opts.Aurora {\n\t\toptions = append(options, decoration.WithAurora(rand.Intn(256)))\n\t}\n\n\tw := decoration.NewWriter(c.stdout, options...)\n\tfmt.Fprintln(w, say)\n\n\treturn nil\n}\n\nfunc selectFace(opts *options, o []cowsay.Option) []cowsay.Option {\n\tswitch {\n\tcase opts.Borg:\n\t\to = append(o,\n\t\t\tcowsay.Eyes(\"==\"),\n\t\t\tcowsay.Tongue(\"  \"),\n\t\t)\n\tcase opts.Dead:\n\t\to = append(o,\n\t\t\tcowsay.Eyes(\"xx\"),\n\t\t\tcowsay.Tongue(\"U \"),\n\t\t)\n\tcase opts.Greedy:\n\t\to = append(o,\n\t\t\tcowsay.Eyes(\"$$\"),\n\t\t\tcowsay.Tongue(\"  \"),\n\t\t)\n\tcase opts.Paranoia:\n\t\to = append(o,\n\t\t\tcowsay.Eyes(\"@@\"),\n\t\t\tcowsay.Tongue(\"  \"),\n\t\t)\n\tcase opts.Stoned:\n\t\to = append(o,\n\t\t\tcowsay.Eyes(\"**\"),\n\t\t\tcowsay.Tongue(\"U \"),\n\t\t)\n\tcase opts.Tired:\n\t\to = append(o,\n\t\t\tcowsay.Eyes(\"--\"),\n\t\t\tcowsay.Tongue(\"  \"),\n\t\t)\n\tcase opts.Wired:\n\t\to = append(o,\n\t\t\tcowsay.Eyes(\"OO\"),\n\t\t\tcowsay.Tongue(\"  \"),\n\t\t)\n\tcase opts.Youthful:\n\t\to = append(o,\n\t\t\tcowsay.Eyes(\"..\"),\n\t\t\tcowsay.Tongue(\"  \"),\n\t\t)\n\t}\n\treturn o\n}\n"
  },
  {
    "path": "cmd/internal/cli/cli_test.go",
    "content": "package cli\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n)\n\nfunc TestCLI_Run(t *testing.T) {\n\tclis := []struct {\n\t\tname     string\n\t\tthinking bool\n\t}{\n\t\t{\n\t\t\tname:     \"cowsay\",\n\t\t\tthinking: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"cowthink\",\n\t\t\tthinking: true,\n\t\t},\n\t}\n\tfor _, cli := range clis {\n\t\tcli := cli\n\t\tt.Run(cli.name, func(t *testing.T) {\n\t\t\tt.Parallel()\n\t\t\ttests := []struct {\n\t\t\t\tname     string\n\t\t\t\tphrase   string\n\t\t\t\targv     []string\n\t\t\t\ttestfile string\n\t\t\t}{\n\t\t\t\t{\n\t\t\t\t\tname:     \"ignore wordwrap option\",\n\t\t\t\t\tphrase:   \"foo\\nbar\\nbaz\",\n\t\t\t\t\targv:     []string{\"-n\"},\n\t\t\t\t\ttestfile: \"n_option.txt\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname:     \"tired option\",\n\t\t\t\t\tphrase:   \"tired\",\n\t\t\t\t\targv:     []string{\"-t\"},\n\t\t\t\t\ttestfile: \"t_option.txt\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname:     \"specifies width of the ballon is 3\",\n\t\t\t\t\tphrase:   \"foobarbaz\",\n\t\t\t\t\targv:     []string{\"-W\", \"3\"},\n\t\t\t\t\ttestfile: \"W_option.txt\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname:     \"borg mode\",\n\t\t\t\t\tphrase:   \"foobarbaz\",\n\t\t\t\t\targv:     []string{\"-b\"},\n\t\t\t\t\ttestfile: \"b_option.txt\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname:     \"dead mode\",\n\t\t\t\t\tphrase:   \"0xdeadbeef\",\n\t\t\t\t\targv:     []string{\"-d\"},\n\t\t\t\t\ttestfile: \"d_option.txt\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname:     \"greedy mode\",\n\t\t\t\t\tphrase:   \"give me money\",\n\t\t\t\t\targv:     []string{\"-g\"},\n\t\t\t\t\ttestfile: \"g_option.txt\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname:     \"paranoid mode\",\n\t\t\t\t\tphrase:   \"everyone hates me\",\n\t\t\t\t\targv:     []string{\"-p\"},\n\t\t\t\t\ttestfile: \"p_option.txt\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname:     \"stoned mode\",\n\t\t\t\t\tphrase:   \"I don't know\",\n\t\t\t\t\targv:     []string{\"-s\"},\n\t\t\t\t\ttestfile: \"s_option.txt\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname:     \"wired mode\",\n\t\t\t\t\tphrase:   \"Wanna Netflix and chill?\",\n\t\t\t\t\targv:     []string{\"-w\"},\n\t\t\t\t\ttestfile: \"wired_option.txt\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname:     \"youthful mode\",\n\t\t\t\t\tphrase:   \"I forgot my ID at home\",\n\t\t\t\t\targv:     []string{\"-y\"},\n\t\t\t\t\ttestfile: \"y_option.txt\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname:     \"eyes option\",\n\t\t\t\t\tphrase:   \"I'm not angry\",\n\t\t\t\t\targv:     []string{\"-e\", \"^^\"},\n\t\t\t\t\ttestfile: \"eyes_option.txt\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname:     \"tongue option\",\n\t\t\t\t\tphrase:   \"hungry\",\n\t\t\t\t\targv:     []string{\"-T\", \":\"},\n\t\t\t\t\ttestfile: \"tongue_option.txt\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname:     \"-f tux\",\n\t\t\t\t\tphrase:   \"what is macOS?\",\n\t\t\t\t\targv:     []string{\"-f\", \"tux\"},\n\t\t\t\t\ttestfile: \"f_tux_option.txt\",\n\t\t\t\t},\n\t\t\t}\n\t\t\tfor _, tt := range tests {\n\t\t\t\ttt := tt\n\t\t\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t\t\tvar stdout bytes.Buffer\n\t\t\t\t\tc := &CLI{\n\t\t\t\t\t\tThinking: cli.thinking,\n\t\t\t\t\t\tstdout:   &stdout,\n\t\t\t\t\t\tstdin:    strings.NewReader(tt.phrase),\n\t\t\t\t\t}\n\t\t\t\t\texit := c.Run(tt.argv)\n\t\t\t\t\tif exit != 0 {\n\t\t\t\t\t\tt.Fatalf(\"unexpected exit code: %d\", exit)\n\t\t\t\t\t}\n\t\t\t\t\ttestpath := filepath.Join(\"..\", \"..\", \"testdata\", cli.name, tt.testfile)\n\t\t\t\t\tcontent, err := ioutil.ReadFile(testpath)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tt.Fatal(err)\n\t\t\t\t\t}\n\t\t\t\t\tgot := strings.Replace(stdout.String(), \"\\r\", \"\", -1)  // for windows\n\t\t\t\t\twant := strings.Replace(string(content), \"\\r\", \"\", -1) // for windows\n\t\t\t\t\tif want != got {\n\t\t\t\t\t\tt.Log(cmp.Diff(want, got))\n\t\t\t\t\t\tt.Errorf(\"want\\n%s\\n-----got\\n%s\\n\", want, got)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tt.Run(\"program name\", func(t *testing.T) {\n\t\t\t\tc := &CLI{Thinking: cli.thinking}\n\t\t\t\tif cli.name != c.program() {\n\t\t\t\t\tt.Fatalf(\"want %q, but got %q\", cli.name, c.program())\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tt.Run(\"not found cowfile\", func(t *testing.T) {\n\t\t\t\tvar stderr bytes.Buffer\n\t\t\t\tc := &CLI{\n\t\t\t\t\tThinking: cli.thinking,\n\t\t\t\t\tstderr:   &stderr,\n\t\t\t\t}\n\n\t\t\t\texit := c.Run([]string{\"-f\", \"unknown\"})\n\t\t\t\tif exit == 0 {\n\t\t\t\t\tt.Errorf(\"unexpected exit code: %d\", exit)\n\t\t\t\t}\n\t\t\t\twant := fmt.Sprintf(\"%s: could not find unknown cowfile\\n\", cli.name)\n\t\t\t\tif want != stderr.String() {\n\t\t\t\t\tt.Errorf(\"want %q, but got %q\", want, stderr.String())\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "cmd/internal/screen/buffer.go",
    "content": "package screen\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n)\n\n// buffer is the global screen buffer\n// Its not recommended write to buffer dirrectly, use package Print,Printf,Println functions instead.\nvar buffer strings.Builder\n\n// Flush buffer and ensure that it will not overflow screen\nfunc Flush() string {\n\tdefer buffer.Reset()\n\treturn buffer.String()\n}\n\n// MoveWriter is implemented io.Writer and io.StringWriter.\ntype MoveWriter struct {\n\tidx  int\n\tx, y int\n\tw    io.Writer\n\tbuf  bytes.Buffer\n}\n\nvar _ interface {\n\tio.Writer\n\tio.StringWriter\n} = (*MoveWriter)(nil)\n\n// NewMoveWriter creates a new MoveWriter.\nfunc NewMoveWriter(w io.Writer, x, y int) *MoveWriter {\n\tx, y = getXY(x, y)\n\treturn &MoveWriter{\n\t\tw: w,\n\t\tx: x,\n\t\ty: y,\n\t}\n}\n\n// SetPosx sets pos x\nfunc (m *MoveWriter) SetPosx(x int) {\n\tx, _ = getXY(x, 0)\n\tm.x = x\n}\n\n// Reset resets\nfunc (m *MoveWriter) Reset() {\n\tm.idx = 0\n\tm.buf.Reset()\n}\n\n// Write writes bytes. which is implemented io.Writer.\nfunc (m *MoveWriter) Write(bs []byte) (nn int, _ error) {\n\tbr := bytes.NewReader(bs)\n\tfor {\n\t\tb, err := br.ReadByte()\n\t\tif err != nil && err != io.EOF {\n\t\t\treturn 0, err\n\t\t}\n\t\tif err == io.EOF {\n\t\t\tn, _ := fmt.Fprintf(m.w, \"\\x1b[%d;%dH%s\\x1b[0K\",\n\t\t\t\tm.y+m.idx,\n\t\t\t\tm.x,\n\t\t\t\tm.buf.String(),\n\t\t\t)\n\t\t\tnn += n\n\t\t\treturn\n\t\t}\n\t\tif b == '\\n' {\n\t\t\tn, _ := fmt.Fprintf(m.w, \"\\x1b[%d;%dH%s\\x1b[0K\",\n\t\t\t\tm.y+m.idx,\n\t\t\t\tm.x,\n\t\t\t\tm.buf.String(),\n\t\t\t)\n\t\t\tm.buf.Reset()\n\t\t\tm.idx++\n\t\t\tnn += n\n\t\t} else {\n\t\t\tm.buf.WriteByte(b)\n\t\t}\n\t}\n}\n\n// WriteString writes string. which is implemented io.StringWriter.\nfunc (m *MoveWriter) WriteString(s string) (nn int, _ error) {\n\tfor _, char := range s {\n\t\tif char == '\\n' {\n\t\t\tn, _ := fmt.Fprintf(m.w, \"\\x1b[%d;%dH%s\\x1b[0K\",\n\t\t\t\tm.y+m.idx,\n\t\t\t\tm.x,\n\t\t\t\tm.buf.String(),\n\t\t\t)\n\t\t\tm.buf.Reset()\n\t\t\tm.idx++\n\t\t\tnn += n\n\t\t} else {\n\t\t\tm.buf.WriteRune(char)\n\t\t}\n\t}\n\tif m.buf.Len() > 0 {\n\t\tn, _ := fmt.Fprintf(m.w, \"\\x1b[%d;%dH%s\\x1b[0K\",\n\t\t\tm.y+m.idx,\n\t\t\tm.x,\n\t\t\tm.buf.String(),\n\t\t)\n\t\tnn += n\n\t}\n\treturn\n}\n\n// getXY gets relative or absolute coorditantes\n// To get relative, set PCT flag to number:\n//\n//      // Get 10% of total width to `x` and 20 to y\n//      x, y = tm.GetXY(10|tm.PCT, 20)\n//\nfunc getXY(x int, y int) (int, int) {\n\t// Set percent flag: num | PCT\n\t//\n\t// Check percent flag: num & PCT\n\t//\n\t// Reset percent flag: num & 0xFF\n\tconst shift = uint(^uint(0)>>63) << 4\n\tconst PCT = 0x8000 << shift\n\tif y == -1 {\n\t\ty = currentHeight() + 1\n\t}\n\n\tif x&PCT != 0 {\n\t\tx = int((x & 0xFF) * Width() / 100)\n\t}\n\n\tif y&PCT != 0 {\n\t\ty = int((y & 0xFF) * Height() / 100)\n\t}\n\n\treturn x, y\n}\n\n// currentHeight returns current height. Line count in Screen buffer.\nfunc currentHeight() int {\n\treturn strings.Count(buffer.String(), \"\\n\")\n}\n"
  },
  {
    "path": "cmd/internal/screen/screen.go",
    "content": "package screen\n\nimport (\n\t\"os\"\n\t\"sync\"\n\n\tcolorable \"github.com/mattn/go-colorable\"\n\t\"golang.org/x/crypto/ssh/terminal\"\n)\n\n// Stdout color supported stdout\nvar Stdout = colorable.NewColorableStdout()\n\n// SaveState saves cursor state.\nfunc SaveState() { Stdout.Write([]byte(\"\\0337\")) }\n\n// RestoreState restores cursor state.\nfunc RestoreState() { Stdout.Write([]byte(\"\\0338\")) }\n\n// Clear clears terminal screen.\nfunc Clear() { Stdout.Write([]byte(\"\\033[2J\")) }\n\n// HideCursor hide the cursor\nfunc HideCursor() { Stdout.Write([]byte(\"\\033[?25l\")) }\n\n// UnHideCursor unhide the cursor\nfunc UnHideCursor() { Stdout.Write([]byte(\"\\033[?25h\")) }\n\nvar size struct {\n\tonce   sync.Once\n\twidth  int\n\theight int\n}\n\nfunc getSize() (int, int) {\n\tsize.once.Do(func() {\n\t\tvar err error\n\t\tsize.width, size.height, err = terminal.GetSize(int(os.Stdout.Fd()))\n\t\tif err != nil {\n\t\t\tsize.width, size.height = -1, -1\n\t\t}\n\t})\n\treturn size.width, size.height\n}\n\n// Width returns console width\nfunc Width() int {\n\twidth, _ := getSize()\n\treturn width\n}\n\n// Height returns console height\nfunc Height() int {\n\t_, height := getSize()\n\treturn height\n}\n"
  },
  {
    "path": "cmd/internal/super/supercow.go",
    "content": "package super\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"os\"\n\t\"os/signal\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/Code-Hex/Neo-cowsay/cmd/v2/internal/screen\"\n\tcowsay \"github.com/Code-Hex/Neo-cowsay/v2\"\n\t\"github.com/Code-Hex/Neo-cowsay/v2/decoration\"\n\trunewidth \"github.com/mattn/go-runewidth\"\n\t\"github.com/rivo/uniseg\"\n)\n\nfunc getNoSaidCow(cow *cowsay.Cow, opts ...cowsay.Option) (string, error) {\n\topts = append(opts, cowsay.Thoughts(' '))\n\tcow, err := cow.Clone(opts...)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn cow.GetCow()\n}\n\n// RunSuperCow runs super cow mode animation on the your terminal\nfunc RunSuperCow(phrase string, withBold bool, opts ...cowsay.Option) error {\n\tcow, err := cowsay.New(opts...)\n\tif err != nil {\n\t\treturn err\n\t}\n\tballoon := cow.Balloon(phrase)\n\tblank := createBlankSpace(balloon)\n\n\tsaid, err := cow.GetCow()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tnotSaid, err := getNoSaidCow(cow, opts...)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tsaidCow := balloon + said\n\tsaidCowLines := strings.Count(saidCow, \"\\n\") + 1\n\n\t// When it is higher than the height of the terminal\n\th := screen.Height()\n\tif saidCowLines > h {\n\t\treturn errors.New(\"too height messages\")\n\t}\n\n\tnotSaidCow := blank + notSaid\n\n\trenderer := newRenderer(saidCow, notSaidCow)\n\n\tscreen.SaveState()\n\tscreen.HideCursor()\n\tscreen.Clear()\n\n\tgo renderer.createFrames(cow, withBold)\n\n\trenderer.render()\n\n\tscreen.UnHideCursor()\n\tscreen.RestoreState()\n\n\treturn nil\n}\n\nfunc createBlankSpace(balloon string) string {\n\tvar buf strings.Builder\n\tl := strings.Count(balloon, \"\\n\")\n\tfor i := 0; i < l; i++ {\n\t\tbuf.WriteRune('\\n')\n\t}\n\treturn buf.String()\n}\n\nfunc maxLen(cow []string) int {\n\tmax := 0\n\tfor _, line := range cow {\n\t\tl := runewidth.StringWidth(line)\n\t\tif max < l {\n\t\t\tmax = l\n\t\t}\n\t}\n\treturn max\n}\n\ntype cowLine struct {\n\traw      string\n\tclusters []rune\n}\n\nfunc (c *cowLine) Len() int {\n\treturn len(c.clusters)\n}\n\nfunc (c *cowLine) Slice(i, j int) string {\n\tif c.Len() == 0 {\n\t\treturn \"\"\n\t}\n\treturn string(c.clusters[i:j])\n}\n\nfunc makeCowLines(cow string) []*cowLine {\n\tsep := strings.Split(cow, \"\\n\")\n\tcowLines := make([]*cowLine, len(sep))\n\tfor i, line := range sep {\n\t\tg := uniseg.NewGraphemes(line)\n\t\tclusters := make([]rune, 0)\n\t\tfor g.Next() {\n\t\t\tclusters = append(clusters, g.Runes()...)\n\t\t}\n\t\tcowLines[i] = &cowLine{\n\t\t\traw:      line,\n\t\t\tclusters: clusters,\n\t\t}\n\t}\n\treturn cowLines\n}\n\ntype renderer struct {\n\tmax         int\n\tmiddle      int\n\tscreenWidth int\n\theightDiff  int\n\tframes      chan string\n\n\tsaidCow         string\n\tnotSaidCowLines []*cowLine\n\n\tquit chan os.Signal\n}\n\nfunc newRenderer(saidCow, notSaidCow string) *renderer {\n\tnotSaidCowSep := strings.Split(notSaidCow, \"\\n\")\n\tw, cowsWidth := screen.Width(), maxLen(notSaidCowSep)\n\tmax := w + cowsWidth\n\n\tquit := make(chan os.Signal, 1)\n\tsignal.Notify(quit, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP)\n\n\treturn &renderer{\n\t\tmax:             max,\n\t\tmiddle:          max / 2,\n\t\tscreenWidth:     w,\n\t\theightDiff:      screen.Height() - strings.Count(saidCow, \"\\n\") - 1,\n\t\tframes:          make(chan string, max),\n\t\tsaidCow:         saidCow,\n\t\tnotSaidCowLines: makeCowLines(notSaidCow),\n\t\tquit:            quit,\n\t}\n}\n\nconst (\n\t// Frequency the color changes\n\tmagic = 2\n\n\tspan    = 30 * time.Millisecond\n\tstandup = 3 * time.Second\n)\n\nfunc (r *renderer) createFrames(cow *cowsay.Cow, withBold bool) {\n\tconst times = standup / span\n\tw := r.newWriter(withBold)\n\n\tfor x, i := 0, 1; i <= r.max; i++ {\n\t\tif i == r.middle {\n\t\t\tw.SetPosx(r.posX(i))\n\t\t\tfor k := 0; k < int(times); k++ {\n\t\t\t\tbase := x * 70\n\t\t\t\t// draw colored cow\n\t\t\t\tw.SetColorSeq(base)\n\t\t\t\tw.WriteString(r.saidCow)\n\t\t\t\tr.frames <- w.String()\n\t\t\t\tif k%magic == 0 {\n\t\t\t\t\tx++\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tbase := x * 70\n\t\t\tw.SetPosx(r.posX(i))\n\t\t\tw.SetColorSeq(base)\n\n\t\t\tfor _, line := range r.notSaidCowLines {\n\t\t\t\tif i > r.screenWidth {\n\t\t\t\t\t// Left side animations\n\t\t\t\t\tn := i - r.screenWidth\n\t\t\t\t\tif n < line.Len() {\n\t\t\t\t\t\tw.WriteString(line.Slice(n, line.Len()))\n\t\t\t\t\t}\n\t\t\t\t} else if i <= line.Len() {\n\t\t\t\t\t// Right side animations\n\t\t\t\t\tw.WriteString(line.Slice(0, i-1))\n\t\t\t\t} else {\n\t\t\t\t\tw.WriteString(line.raw)\n\t\t\t\t}\n\t\t\t\tw.Write([]byte{'\\n'})\n\t\t\t}\n\t\t\tr.frames <- w.String()\n\t\t}\n\t\tif i%magic == 0 {\n\t\t\tx++\n\t\t}\n\t}\n\tclose(r.frames)\n}\n\nfunc (r *renderer) render() {\n\tinitCh := make(chan struct{}, 1)\n\tinitCh <- struct{}{}\n\n\tfor view := range r.frames {\n\t\tselect {\n\t\tcase <-r.quit:\n\t\t\tscreen.Clear()\n\t\t\treturn\n\t\tcase <-initCh:\n\t\tcase <-time.After(span):\n\t\t}\n\t\tio.Copy(screen.Stdout, strings.NewReader(view))\n\t}\n}\n\nfunc (r *renderer) posX(i int) int {\n\tposx := r.screenWidth - i\n\tif posx < 1 {\n\t\tposx = 1\n\t}\n\treturn posx\n}\n\n// Writer is wrapper which is both screen.MoveWriter and decoration.Writer.\ntype Writer struct {\n\tbuf *strings.Builder\n\tmw  *screen.MoveWriter\n\tdw  *decoration.Writer\n}\n\nfunc (r *renderer) newWriter(withBold bool) *Writer {\n\tvar buf strings.Builder\n\tmw := screen.NewMoveWriter(&buf, r.posX(0), r.heightDiff)\n\toptions := []decoration.Option{\n\t\tdecoration.WithAurora(0),\n\t}\n\tif withBold {\n\t\toptions = append(options, decoration.WithBold())\n\t}\n\tdw := decoration.NewWriter(mw, options...)\n\treturn &Writer{\n\t\tbuf: &buf,\n\t\tmw:  mw,\n\t\tdw:  dw,\n\t}\n}\n\n// WriteString writes string. which is implemented io.StringWriter.\nfunc (w *Writer) WriteString(s string) (int, error) { return w.dw.WriteString(s) }\n\n// Write writes bytes. which is implemented io.Writer.\nfunc (w *Writer) Write(p []byte) (int, error) { return w.dw.Write(p) }\n\n// SetPosx sets posx\nfunc (w *Writer) SetPosx(x int) { w.mw.SetPosx(x) }\n\n// SetColorSeq sets color sequence.\nfunc (w *Writer) SetColorSeq(colorSeq int) { w.dw.SetColorSeq(colorSeq) }\n\n// Reset resets calls some Reset methods.\nfunc (w *Writer) Reset() {\n\tw.buf.Reset()\n\tw.mw.Reset()\n}\n\nfunc (w *Writer) String() string {\n\tdefer w.Reset()\n\treturn w.buf.String()\n}\n"
  },
  {
    "path": "cmd/testdata/cowsay/W_option.txt",
    "content": " _____ \n/ foo \\\n| bar |\n\\ baz /\n ----- \n        \\   ^__^\n         \\  (oo)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowsay/b_option.txt",
    "content": " ___________ \n< foobarbaz >\n ----------- \n        \\   ^__^\n         \\  (==)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowsay/d_option.txt",
    "content": " ____________ \n< 0xdeadbeef >\n ------------ \n        \\   ^__^\n         \\  (xx)\\_______\n            (__)\\       )\\/\\\n             U  ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowsay/eyes_option.txt",
    "content": " _______________ \n< I'm not angry >\n --------------- \n        \\   ^__^\n         \\  (^^)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowsay/f_tux_option.txt",
    "content": " ________________ \n< what is macOS? >\n ---------------- \n   \\\n    \\\n        .--.\n       |o_o |\n       |:_/ |\n      //   \\ \\\n     (|     | )\n    /'\\_   _/`\\\n    \\___)=(___/\n\n"
  },
  {
    "path": "cmd/testdata/cowsay/g_option.txt",
    "content": " _______________ \n< give me money >\n --------------- \n        \\   ^__^\n         \\  ($$)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowsay/n_option.txt",
    "content": " _____ \n/ foo \\\n| bar |\n\\ baz /\n ----- \n        \\   ^__^\n         \\  (oo)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowsay/p_option.txt",
    "content": " ___________________ \n< everyone hates me >\n ------------------- \n        \\   ^__^\n         \\  (@@)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowsay/s_option.txt",
    "content": " ______________ \n< I don't know >\n -------------- \n        \\   ^__^\n         \\  (**)\\_______\n            (__)\\       )\\/\\\n             U  ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowsay/t_option.txt",
    "content": " _______ \n< tired >\n ------- \n        \\   ^__^\n         \\  (--)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowsay/tongue_option.txt",
    "content": " ________ \n< hungry >\n -------- \n        \\   ^__^\n         \\  (oo)\\_______\n            (__)\\       )\\/\\\n             :  ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowsay/wired_option.txt",
    "content": " __________________________ \n< Wanna Netflix and chill? >\n -------------------------- \n        \\   ^__^\n         \\  (OO)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowsay/y_option.txt",
    "content": " ________________________ \n< I forgot my ID at home >\n ------------------------ \n        \\   ^__^\n         \\  (..)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowthink/W_option.txt",
    "content": " _____ \n( foo )\n( bar )\n( baz )\n ----- \n        o   ^__^\n         o  (oo)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowthink/b_option.txt",
    "content": " ___________ \n( foobarbaz )\n ----------- \n        o   ^__^\n         o  (==)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowthink/d_option.txt",
    "content": " ____________ \n( 0xdeadbeef )\n ------------ \n        o   ^__^\n         o  (xx)\\_______\n            (__)\\       )\\/\\\n             U  ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowthink/eyes_option.txt",
    "content": " _______________ \n( I'm not angry )\n --------------- \n        o   ^__^\n         o  (^^)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowthink/f_tux_option.txt",
    "content": " ________________ \n( what is macOS? )\n ---------------- \n   o\n    o\n        .--.\n       |o_o |\n       |:_/ |\n      //   \\ \\\n     (|     | )\n    /'\\_   _/`\\\n    \\___)=(___/\n\n"
  },
  {
    "path": "cmd/testdata/cowthink/g_option.txt",
    "content": " _______________ \n( give me money )\n --------------- \n        o   ^__^\n         o  ($$)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowthink/n_option.txt",
    "content": " _____ \n( foo )\n( bar )\n( baz )\n ----- \n        o   ^__^\n         o  (oo)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowthink/p_option.txt",
    "content": " ___________________ \n( everyone hates me )\n ------------------- \n        o   ^__^\n         o  (@@)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowthink/s_option.txt",
    "content": " ______________ \n( I don't know )\n -------------- \n        o   ^__^\n         o  (**)\\_______\n            (__)\\       )\\/\\\n             U  ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowthink/t_option.txt",
    "content": " _______ \n( tired )\n ------- \n        o   ^__^\n         o  (--)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowthink/tongue_option.txt",
    "content": " ________ \n( hungry )\n -------- \n        o   ^__^\n         o  (oo)\\_______\n            (__)\\       )\\/\\\n             :  ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowthink/wired_option.txt",
    "content": " __________________________ \n( Wanna Netflix and chill? )\n -------------------------- \n        o   ^__^\n         o  (OO)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cmd/testdata/cowthink/y_option.txt",
    "content": " ________________________ \n( I forgot my ID at home )\n ------------------------ \n        o   ^__^\n         o  (..)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n"
  },
  {
    "path": "cow.go",
    "content": "package cowsay\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"strings\"\n)\n\n// Cow struct!!\ntype Cow struct {\n\teyes            string\n\ttongue          string\n\ttyp             *CowFile\n\tthoughts        rune\n\tthinking        bool\n\tballonWidth     int\n\tdisableWordWrap bool\n\n\tbuf strings.Builder\n}\n\n// New returns pointer of Cow struct that made by options\nfunc New(options ...Option) (*Cow, error) {\n\tcow := &Cow{\n\t\teyes:     \"oo\",\n\t\ttongue:   \"  \",\n\t\tthoughts: '\\\\',\n\t\ttyp: &CowFile{\n\t\t\tName:         \"default\",\n\t\t\tBasePath:     \"cows\",\n\t\t\tLocationType: InBinary,\n\t\t},\n\t\tballonWidth: 40,\n\t}\n\tfor _, o := range options {\n\t\tif err := o(cow); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn cow, nil\n}\n\n// Say returns string that said by cow\nfunc (cow *Cow) Say(phrase string) (string, error) {\n\tmow, err := cow.GetCow()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn cow.Balloon(phrase) + mow, nil\n}\n\n// Clone returns a copy of cow.\n//\n// If any options are specified, they will be reflected.\nfunc (cow *Cow) Clone(options ...Option) (*Cow, error) {\n\tret := new(Cow)\n\t*ret = *cow\n\tret.buf.Reset()\n\tfor _, o := range options {\n\t\tif err := o(ret); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn ret, nil\n}\n\n// Option defined for Options\ntype Option func(*Cow) error\n\n// Eyes specifies eyes\n// The specified string will always be adjusted to be equal to two characters.\nfunc Eyes(s string) Option {\n\treturn func(c *Cow) error {\n\t\tc.eyes = adjustTo2Chars(s)\n\t\treturn nil\n\t}\n}\n\n// Tongue specifies tongue\n// The specified string will always be adjusted to be less than or equal to two characters.\nfunc Tongue(s string) Option {\n\treturn func(c *Cow) error {\n\t\tc.tongue = adjustTo2Chars(s)\n\t\treturn nil\n\t}\n}\n\nfunc adjustTo2Chars(s string) string {\n\tif len(s) >= 2 {\n\t\treturn s[:2]\n\t}\n\tif len(s) == 1 {\n\t\treturn s + \" \"\n\t}\n\treturn \"  \"\n}\n\nfunc containCows(target string) (*CowFile, error) {\n\tcowPaths, err := Cows()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor _, cowPath := range cowPaths {\n\t\tcowfile, ok := cowPath.Lookup(target)\n\t\tif ok {\n\t\t\treturn cowfile, nil\n\t\t}\n\t}\n\treturn nil, nil\n}\n\n// NotFound is indicated not found the cowfile.\ntype NotFound struct {\n\tCowfile string\n}\n\nvar _ error = (*NotFound)(nil)\n\nfunc (n *NotFound) Error() string {\n\treturn fmt.Sprintf(\"not found %q cowfile\", n.Cowfile)\n}\n\n// Type specify name of the cowfile\nfunc Type(s string) Option {\n\tif s == \"\" {\n\t\ts = \"default\"\n\t}\n\treturn func(c *Cow) error {\n\t\tcowfile, err := containCows(s)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif cowfile != nil {\n\t\t\tc.typ = cowfile\n\t\t\treturn nil\n\t\t}\n\t\treturn &NotFound{Cowfile: s}\n\t}\n}\n\n// Thinking enables thinking mode\nfunc Thinking() Option {\n\treturn func(c *Cow) error {\n\t\tc.thinking = true\n\t\treturn nil\n\t}\n}\n\n// Thoughts Thoughts allows you to specify\n// the rune that will be drawn between\n// the speech bubbles and the cow\nfunc Thoughts(thoughts rune) Option {\n\treturn func(c *Cow) error {\n\t\tc.thoughts = thoughts\n\t\treturn nil\n\t}\n}\n\n// Random specifies something .cow from cows directory\nfunc Random() Option {\n\tpick, err := pickCow()\n\treturn func(c *Cow) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tc.typ = pick\n\t\treturn nil\n\t}\n}\n\nfunc pickCow() (*CowFile, error) {\n\tcowPaths, err := Cows()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcowPath := cowPaths[rand.Intn(len(cowPaths))]\n\n\tn := len(cowPath.CowFiles)\n\tcowfile := cowPath.CowFiles[rand.Intn(n)]\n\treturn &CowFile{\n\t\tName:         cowfile,\n\t\tBasePath:     cowPath.Name,\n\t\tLocationType: cowPath.LocationType,\n\t}, nil\n}\n\n// BallonWidth specifies ballon size\nfunc BallonWidth(size uint) Option {\n\treturn func(c *Cow) error {\n\t\tc.ballonWidth = int(size)\n\t\treturn nil\n\t}\n}\n\n// DisableWordWrap disables word wrap.\n// Ignoring width of the ballon.\nfunc DisableWordWrap() Option {\n\treturn func(c *Cow) error {\n\t\tc.disableWordWrap = true\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "cow_test.go",
    "content": "package cowsay\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n)\n\nfunc TestCow_Clone(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\topts []Option\n\t\tfrom *Cow\n\t\twant *Cow\n\t}{\n\t\t{\n\t\t\tname: \"without options\",\n\t\t\topts: []Option{},\n\t\t\tfrom: func() *Cow {\n\t\t\t\tcow, _ := New()\n\t\t\t\treturn cow\n\t\t\t}(),\n\t\t\twant: func() *Cow {\n\t\t\t\tcow, _ := New()\n\t\t\t\treturn cow\n\t\t\t}(),\n\t\t},\n\t\t{\n\t\t\tname: \"with some options\",\n\t\t\topts: []Option{},\n\t\t\tfrom: func() *Cow {\n\t\t\t\tcow, _ := New(\n\t\t\t\t\tType(\"docker\"),\n\t\t\t\t\tBallonWidth(60),\n\t\t\t\t)\n\t\t\t\treturn cow\n\t\t\t}(),\n\t\t\twant: func() *Cow {\n\t\t\t\tcow, _ := New(\n\t\t\t\t\tType(\"docker\"),\n\t\t\t\t\tBallonWidth(60),\n\t\t\t\t)\n\t\t\t\treturn cow\n\t\t\t}(),\n\t\t},\n\t\t{\n\t\t\tname: \"clone and some options\",\n\t\t\topts: []Option{\n\t\t\t\tThinking(),\n\t\t\t\tThoughts('o'),\n\t\t\t},\n\t\t\tfrom: func() *Cow {\n\t\t\t\tcow, _ := New(\n\t\t\t\t\tType(\"docker\"),\n\t\t\t\t\tBallonWidth(60),\n\t\t\t\t)\n\t\t\t\treturn cow\n\t\t\t}(),\n\t\t\twant: func() *Cow {\n\t\t\t\tcow, _ := New(\n\t\t\t\t\tType(\"docker\"),\n\t\t\t\t\tBallonWidth(60),\n\t\t\t\t\tThinking(),\n\t\t\t\t\tThoughts('o'),\n\t\t\t\t)\n\t\t\t\treturn cow\n\t\t\t}(),\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot, err := tt.want.Clone(tt.opts...)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif diff := cmp.Diff(tt.want, got,\n\t\t\t\tcmp.AllowUnexported(Cow{}),\n\t\t\t\tcmpopts.IgnoreFields(Cow{}, \"buf\")); diff != \"\" {\n\t\t\t\tt.Errorf(\"(-want, +got)\\n%s\", diff)\n\t\t\t}\n\t\t})\n\t}\n\n\tt.Run(\"random\", func(t *testing.T) {\n\t\tcow, _ := New(\n\t\t\tType(\"\"),\n\t\t\tThinking(),\n\t\t\tThoughts('o'),\n\t\t\tEyes(\"xx\"),\n\t\t\tTongue(\"u\"),\n\t\t\tRandom(),\n\t\t)\n\n\t\tcloned, _ := cow.Clone()\n\n\t\tif diff := cmp.Diff(cow, cloned,\n\t\t\tcmp.AllowUnexported(Cow{}),\n\t\t\tcmpopts.IgnoreFields(Cow{}, \"buf\")); diff != \"\" {\n\t\t\tt.Errorf(\"(-want, +got)\\n%s\", diff)\n\t\t}\n\t})\n\n\tt.Run(\"error\", func(t *testing.T) {\n\t\tcow, err := New()\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\twantErr := errors.New(\"error\")\n\t\t_, err = cow.Clone(func(*Cow) error {\n\t\t\treturn wantErr\n\t\t})\n\t\tif wantErr != err {\n\t\t\tt.Fatalf(\"want %v, but got %v\", wantErr, err)\n\t\t}\n\t})\n}\n\nfunc Test_adjustTo2Chars(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\ts    string\n\t\twant string\n\t}{\n\t\t{\n\t\t\tname: \"empty\",\n\t\t\ts:    \"\",\n\t\t\twant: \"  \",\n\t\t},\n\t\t{\n\t\t\tname: \"1 character\",\n\t\t\ts:    \"1\",\n\t\t\twant: \"1 \",\n\t\t},\n\t\t{\n\t\t\tname: \"2 characters\",\n\t\t\ts:    \"12\",\n\t\t\twant: \"12\",\n\t\t},\n\t\t{\n\t\t\tname: \"3 characters\",\n\t\t\ts:    \"123\",\n\t\t\twant: \"12\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.s, func(t *testing.T) {\n\t\t\tif got := adjustTo2Chars(tt.s); got != tt.want {\n\t\t\t\tt.Errorf(\"adjustTo2Chars() = %v, want %v\", got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestNotFound_Error(t *testing.T) {\n\tfile := \"test\"\n\tn := &NotFound{\n\t\tCowfile: file,\n\t}\n\twant := fmt.Sprintf(\"not found %q cowfile\", file)\n\tif want != n.Error() {\n\t\tt.Fatalf(\"want %q but got %q\", want, n.Error())\n\t}\n}\n"
  },
  {
    "path": "cows/beavis.zen.cow",
    "content": "##\n## Beavis, with Zen philosophy removed.\n##\n$the_cow = <<EOC;\n   $thoughts         __------~~-,\n    $thoughts      ,'            ,\n          /               \\\\\n         /                :\n        |                  '\n        |                  |\n        |                  |\n         |   _--           |\n         _| =-.     .-.   ||\n         o|/o/       _.   |\n         /  ~          \\\\ |\n       (____\\@)  ___~    |\n          |_===~~~.`    |\n       _______.--~     |\n       \\\\________       |\n                \\\\      |\n              __/-___-- -__\n             /            _ \\\\\nEOC\n"
  },
  {
    "path": "cows/bong.cow",
    "content": "##\n## A cow with a bong, from lars@csua.berkeley.edu\n##\n$the_cow = <<EOC;\n         $thoughts\n          $thoughts\n            ^__^ \n    _______/($eyes)\n/\\\\/(       /(__)\n   | W----|| |~|\n   ||     || |~|  ~~\n             |~|  ~\n             |_| o\n             |#|/\n            _+#+_\nEOC\n"
  },
  {
    "path": "cows/bud-frogs.cow",
    "content": "##\n## The Budweiser frogs\n##\n$the_cow = <<EOC;\n     $thoughts\n      $thoughts\n          oO)-.                       .-(Oo\n         /__  _\\\\                     /_  __\\\\\n         \\\\  \\\\(  |     ()~()         |  )/  /\n          \\\\__|\\\\ |    (-___-)        | /|__/\n          '  '--'    ==`-'==        '--'  '\nEOC\n"
  },
  {
    "path": "cows/bunny.cow",
    "content": "##\n## A cute little wabbit\n##\n$the_cow = <<EOC;\n  $thoughts\n   $thoughts   \\\\\n        \\\\ /\\\\\n        ( )\n      .( o ).\nEOC\n"
  },
  {
    "path": "cows/cheese.cow",
    "content": "##\n## The cheese from milk & cheese\n##\n$the_cow = <<EOC;\n   $thoughts\n    $thoughts\n      _____   _________\n     /     \\\\_/         |\n    |                 ||\n    |                 ||\n   |    ###\\\\  /###   | |\n   |     0  \\\\/  0    | |\n  /|                 | |\n / |        <        |\\\\ \\\\\n| /|                 | | |\n| |     \\\\_______/   |  | |\n| |                 | / /\n/||                 /|||\n   ----------------|\n        | |    | |\n        ***    ***\n       /___\\\\  /___\\\\\nEOC\n"
  },
  {
    "path": "cows/cower.cow",
    "content": "##\n## A cowering cow\n##\n$the_cow = <<EOC;\n     $thoughts\n      $thoughts\n        ,__, |    | \n        (oo)\\\\|    |___\n        (__)\\\\|    |   )\\\\_\n             |    |_w |  \\\\\n             |    |  ||   *\n\n             Cower....\nEOC\n"
  },
  {
    "path": "cows/daemon.cow",
    "content": "##\n## 4.4 >> 5.4\n##\n$the_cow = <<EOC;\n   $thoughts         ,        ,\n    $thoughts       /(        )`\n     $thoughts      \\\\ \\\\___   / |\n            /- _  `-/  '\n           (/\\\\/ \\\\ \\\\   /\\\\\n           / /   | `    \\\\\n           O O   ) /    |\n           `-^--'`<     '\n          (_.)  _  )   /\n           `.___/`    /\n             `-----' /\n<----.     __ / __   \\\\\n<----|====O)))==) \\\\) /====\n<----'    `--' `.__,' \\\\\n             |        |\n              \\\\       /\n        ______( (_  / \\\\______\n      ,'  ,-----'   |        \\\\\n      `--{__________)        \\\\/\nEOC\n"
  },
  {
    "path": "cows/default.cow",
    "content": "$the_cow = <<EOC;\n        $thoughts   ^__^\n         $thoughts  ($eyes)\\\\_______\n            (__)\\\\       )\\\\/\\\\\n             $tongue ||----w |\n                ||     ||\nEOC\n"
  },
  {
    "path": "cows/deno.cow",
    "content": "## https://github.com/kawarimidoll/deno-cli-tools/blob/30107adad1dd7d00da8be08c76f843bbfd88b455/denosay/mod.ts#L64-L73\n$the_cow = <<EOC;\n     $thoughts\n      $thoughts  _\n        ( ･ヽ\n          \\ \\\n           ⎞ \\\n           |  ｀ヽ\n           ⎩      ﾄ､\n            u¯u︶u\nEOC"
  },
  {
    "path": "cows/docker.cow",
    "content": "##\n## Docker Cow\n##\n$the_cow = <<EOC;\n    $thoughts\n     $thoughts\n      $thoughts\n                    ##         .\n              ## ## ##        ==\n           ## ## ## ## ##    ===\n       /\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\\___/ ===\n      {                       /  ===-\n       \\______ O           __/\n         \\    \\         __/\n          \\____\\_______/\n\nEOC\n"
  },
  {
    "path": "cows/dragon-and-cow.cow",
    "content": "##\n## A dragon smiting a cow, possible credit to kube@csua.berkeley.edu\n##\n$the_cow = <<EOC;\n                       $thoughts                    ^    /^\n                        $thoughts                  / \\\\  // \\\\\n                         $thoughts   |\\\\___/|      /   \\\\//  .\\\\\n                          $thoughts  /O  O  \\\\__  /    //  | \\\\ \\\\           *----*\n                            /     /  \\\\/_/    //   |  \\\\  \\\\          \\\\   |\n                            \\@___\\@`    \\\\/_   //    |   \\\\   \\\\         \\\\/\\\\ \\\\\n                           0/0/|       \\\\/_ //     |    \\\\    \\\\         \\\\  \\\\\n                       0/0/0/0/|        \\\\///      |     \\\\     \\\\       |  |\n                    0/0/0/0/0/_|_ /   (  //       |      \\\\     _\\\\     |  /\n                 0/0/0/0/0/0/`/,_ _ _/  ) ; -.    |    _ _\\\\.-~       /   /\n                             ,-}        _      *-.|.-~-.           .~    ~\n            \\\\     \\\\__/        `/\\\\      /                 ~-. _ .-~      /\n             \\\\____($eyes)           *.   }            {                   /\n             (    (--)          .----~-.\\\\        \\\\-`                 .~\n             //__\\\\\\\\  \\\\__ Ack!   ///.----..<        \\\\             _ -~\n            //    \\\\\\\\               ///-._ _ _ _ _ _ _{^ - - - - ~\nEOC\n"
  },
  {
    "path": "cows/dragon.cow",
    "content": "##\n## The Whitespace Dragon\n##\n$the_cow = <<EOC;\n      $thoughts                    / \\\\  //\\\\\n       $thoughts    |\\\\___/|      /   \\\\//  \\\\\\\\\n            /0  0  \\\\__  /    //  | \\\\ \\\\    \n           /     /  \\\\/_/    //   |  \\\\  \\\\  \n           \\@_^_\\@'/   \\\\/_   //    |   \\\\   \\\\ \n           //_^_/     \\\\/_ //     |    \\\\    \\\\\n        ( //) |        \\\\///      |     \\\\     \\\\\n      ( / /) _|_ /   )  //       |      \\\\     _\\\\\n    ( // /) '/,_ _ _/  ( ; -.    |    _ _\\\\.-~        .-~~~^-.\n  (( / / )) ,-{        _      `-.|.-~-.           .~         `.\n (( // / ))  '/\\\\      /                 ~-. _ .-~      .-~^-.  \\\\\n (( /// ))      `.   {            }                   /      \\\\  \\\\\n  (( / ))     .----~-.\\\\        \\\\-'                 .~         \\\\  `. \\\\^-.\n             ///.----..>        \\\\             _ -~             `.  ^-`  ^-_\n               ///-._ _ _ _ _ _ _}^ - - - - ~                     ~-- ,.-~\n                                                                  /.-~\nEOC\n"
  },
  {
    "path": "cows/elephant-in-snake.cow",
    "content": "##\n## Do we need to explain this?\n##\n$the_cow = <<EOC;\n   $thoughts\n    $thoughts              ....       \n           ........    .      \n          .            .      \n         .             .      \n.........              .......\n..............................\n\nElephant inside ASCII snake\nEOC\n"
  },
  {
    "path": "cows/elephant.cow",
    "content": "##\n## An elephant out and about\n##\n$the_cow = <<EOC;\n $thoughts     /\\\\  ___  /\\\\\n  $thoughts   // \\\\/   \\\\/ \\\\\\\\\n     ((    O O    ))\n      \\\\\\\\ /     \\\\ //\n       \\\\/  | |  \\\\/ \n        |  | |  |  \n        |  | |  |  \n        |   o   |  \n        | |   | |  \n        |m|   |m|  \nEOC\n"
  },
  {
    "path": "cows/eyes.cow",
    "content": "##\n## Evil-looking eyes\n##\n$the_cow = <<EOC;\n    $thoughts\n     $thoughts\n                                   .::!!!!!!!:.\n  .!!!!!:.                        .:!!!!!!!!!!!!\n  ~~~~!!!!!!.                 .:!!!!!!!!!UWWW\\$\\$\\$ \n      :\\$\\$NWX!!:           .:!!!!!!XUWW\\$\\$\\$\\$\\$\\$\\$\\$\\$P \n      \\$\\$\\$\\$\\$##WX!:      .<!!!!UW\\$\\$\\$\\$\"  \\$\\$\\$\\$\\$\\$\\$\\$# \n      \\$\\$\\$\\$\\$  \\$\\$\\$UX   :!!UW\\$\\$\\$\\$\\$\\$\\$\\$\\$   4\\$\\$\\$\\$\\$* \n      ^\\$\\$\\$B  \\$\\$\\$\\$\\\\     \\$\\$\\$\\$\\$\\$\\$\\$\\$\\$\\$\\$   d\\$\\$R\" \n        \"*\\$bd\\$\\$\\$\\$      '*\\$\\$\\$\\$\\$\\$\\$\\$\\$\\$\\$o+#\" \n             \"\"\"\"          \"\"\"\"\"\"\" \nEOC\n"
  },
  {
    "path": "cows/flaming-sheep.cow",
    "content": "##\n## The flaming sheep, contributed by Geordan Rosario (geordan@csua.berkeley.edu)\n##\n$the_cow = <<EOC;\n  $thoughts            .    .     .   \n   $thoughts      .  . .     `  ,     \n    $thoughts    .; .  : .' :  :  : . \n     $thoughts   i..`: i` i.i.,i  i . \n      $thoughts   `,--.|i |i|ii|ii|i: \n           U${eyes}U\\\\.'\\@\\@\\@\\@\\@\\@`.||' \n           \\\\__/(\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@)'  \n                (\\@\\@\\@\\@\\@\\@\\@\\@)    \n                `YY~~~~YY'    \n                 ||    ||     \nEOC\n"
  },
  {
    "path": "cows/ghostbusters.cow",
    "content": "##\n## Ghostbusters!\n##\n$the_cow = <<EOC;\n          $thoughts\n           $thoughts\n            $thoughts          __---__\n                    _-       /--______\n               __--( /     \\\\ )XXXXXXXXXXX\\\\v.\n             .-XXX(   O   O  )XXXXXXXXXXXXXXX-\n            /XXX(       U     )        XXXXXXX\\\\\n          /XXXXX(              )--_  XXXXXXXXXXX\\\\\n         /XXXXX/ (      O     )   XXXXXX   \\\\XXXXX\\\\\n         XXXXX/   /            XXXXXX   \\\\__ \\\\XXXXX\n         XXXXXX__/          XXXXXX         \\\\__---->\n ---___  XXX__/          XXXXXX      \\\\__         /\n   \\\\-  --__/   ___/\\\\  XXXXXX            /  ___--/=\n    \\\\-\\\\    ___/    XXXXXX              '--- XXXXXX\n       \\\\-\\\\/XXX\\\\ XXXXXX                      /XXXXX\n         \\\\XXXXXXXXX   \\\\                    /XXXXX/\n          \\\\XXXXXX      >                 _/XXXXX/\n            \\\\XXXXX--__/              __-- XXXX/\n             -XXXXXXXX---------------  XXXXXX-\n                \\\\XXXXXXXXXXXXXXXXXXXXXXXXXX/\n                  \"\"VXXXXXXXXXXXXXXXXXXV\"\"\nEOC\n"
  },
  {
    "path": "cows/gopher.cow",
    "content": "$the_cow = <<EOC;\n    $thoughts \n     $thoughts    ,_---~~~~~----._         \n  _,,_,*^____      _____``*g*\\\\\"*, \n / __/ /'     ^.  /      \\\\ ^@q   f \n[  @f | @))    |  | @))   l  0 _/  \n \\`/   \\~____ / __ \\_____/    \\\\   \n  |           _l__l_           I   \n  |          [______]           I  \n  |            | | |            |  \n  |             ~ ~             |  \n  |                             |   \n  |                             |\nEOC\n"
  },
  {
    "path": "cows/head-in.cow",
    "content": "##\n## Go stick yer head in a cow.\n##\n$the_cow = <<EOC;\n    $thoughts\n     $thoughts\n    ^__^         /\n    ($eyes)\\\\_______/  _________\n    (__)\\\\       )=(  ____|_ \\\\_____\n     $tongue ||----w |  \\\\ \\\\     \\\\_____ |\n        ||     ||   ||           ||\nEOC\n"
  },
  {
    "path": "cows/hellokitty.cow",
    "content": "##\n## Hello Kitty\n##\n$the_cow = <<EOC;\n  $thoughts\n   $thoughts\n      /\\\\_)o<\n     |      \\\\\n     | O . O|\n      \\\\_____/\nEOC\n"
  },
  {
    "path": "cows/kiss.cow",
    "content": "##\n## A lovers' empbrace\n##\n$the_cow = <<EOC;\n     $thoughts\n      $thoughts\n             ,;;;;;;;,\n            ;;;;;;;;;;;,\n           ;;;;;'_____;'\n           ;;;(/))))|((\\\\\n           _;;((((((|))))\n          / |_\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n     .--~(  \\\\ ~))))))))))))\n    /     \\\\  `\\\\-(((((((((((\\\\\\\\\n    |    | `\\\\   ) |\\\\       /|)\n     |    |  `. _/  \\\\_____/ |\n      |    , `\\\\~            /\n       |    \\\\  \\\\           /\n      | `.   `\\\\|          /\n      |   ~-   `\\\\        /\n       \\\\____~._/~ -_,   (\\\\\n        |-----|\\\\   \\\\    ';;\n       |      | :;;;'     \\\\\n      |  /    |            |\n      |       |            |\nEOC\n"
  },
  {
    "path": "cows/kitty.cow",
    "content": "##\n## A kitten of sorts, I think\n##\n$the_cow = <<EOC;\n     $thoughts\n      $thoughts\n       (\"`-'  '-/\") .___..--' ' \"`-._\n         ` *_ *  )    `-.   (      ) .`-.__. `)\n         (_Y_.) ' ._   )   `._` ;  `` -. .-'\n      _.. `--'_..-_/   /--' _ .' ,4\n   ( i l ),-''  ( l i),'  ( ( ! .-'    \nEOC\n"
  },
  {
    "path": "cows/koala.cow",
    "content": "##\n## From the canonical koala collection\n##\n$the_cow = <<EOC;\n  $thoughts\n   $thoughts\n       ___  \n     {~._.~}\n      ( Y )\n     ()~*~()   \n     (_)-(_)   \nEOC\n"
  },
  {
    "path": "cows/kosh.cow",
    "content": "##\n## It's a Kosh Cow!\n##\n$the_cow = <<EOC;\n    $thoughts\n     $thoughts\n      $thoughts\n  ___       _____     ___\n /   \\\\     /    /|   /   \\\\\n|     |   /    / |  |     |\n|     |  /____/  |  |     |     \n|     |  |    |  |  |     |\n|     |  | {} | /   |     |\n|     |  |____|/    |     |\n|     |    |==|     |     |\n|      \\\\___________/      |\n|                         |\n|                         |\nEOC\n"
  },
  {
    "path": "cows/luke-koala.cow",
    "content": "##\n## From the canonical koala collection\n##\n$the_cow = <<EOC;\n  $thoughts\n   $thoughts          .\n       ___   //\n     {~._.~}// \n      ( Y )K/  \n     ()~*~()   \n     (_)-(_)   \n     Luke    \n     Sywalker\n     koala   \nEOC\n"
  },
  {
    "path": "cows/meow.cow",
    "content": "##\n## A meowing tiger?\n##\n$the_cow = <<EOC;\n  $thoughts\n   $thoughts ,   _ ___.--'''`--''//-,-_--_.\n      \\\\`\"' ` || \\\\\\\\ \\\\ \\\\\\\\/ / // / ,-\\\\\\\\`,_\n     /'`  \\\\ \\\\ || Y  | \\\\|/ / // / - |__ `-,\n    /\\@\"\\\\  ` \\\\ `\\\\ |  | ||/ // | \\\\/  \\\\  `-._`-,_.,\n   /  _.-. `.-\\\\,___/\\\\ _/|_/_\\\\_\\\\/|_/ |     `-._._)\n   `-'``/  /  |  // \\\\__/\\\\__  /  \\\\__/ \\\\\n        `-'  /-\\\\/  | -|   \\\\__ \\\\   |-' |\n          __/\\\\ / _/ \\\\/ __,-'   ) ,' _|'\n         (((__/(((_.' ((___..-'((__,'\nEOC\n"
  },
  {
    "path": "cows/milk.cow",
    "content": "##\n## Milk from Milk and Cheese\n##\n$the_cow = <<EOC;\n $thoughts     ____________ \n  $thoughts    |__________|\n      /           /\\\\\n     /           /  \\\\\n    /___________/___/|\n    |          |     |\n    |  ==\\\\ /== |     |\n    |   O   O  | \\\\ \\\\ |\n    |     <    |  \\\\ \\\\|\n   /|          |   \\\\ \\\\\n  / |  \\\\_____/ |   / /\n / /|          |  / /|\n/||\\\\|          | /||\\\\/\n    -------------|   \n        | |    | | \n       <__/    \\\\__>\nEOC\n"
  },
  {
    "path": "cows/moofasa.cow",
    "content": "##\n## MOOfasa.\n##\n$the_cow = <<EOC;\n       $thoughts    ____\n        $thoughts  /    \\\\\n          | ^__^ |\n          | ($eyes) |______\n          | (__) |      )\\\\/\\\\\n           \\\\____/|----w |\n                ||     ||\n\n             Moofasa\nEOC\n"
  },
  {
    "path": "cows/moose.cow",
    "content": "$the_cow = <<EOC;\n  $thoughts\n   $thoughts   \\\\_\\\\_    _/_/\n    $thoughts      \\\\__/\n           ($eyes)\\\\_______\n           (__)\\\\       )\\\\/\\\\\n            $tongue ||----w |\n               ||     ||\nEOC\n"
  },
  {
    "path": "cows/mutilated.cow",
    "content": "##\n## A mutilated cow, from aspolito@csua.berkeley.edu\n##\n$the_cow = <<EOC;\n       $thoughts   \\\\_______\n v__v   $thoughts  \\\\   O   )\n ($eyes)      ||----w |\n (__)      ||     ||  \\\\/\\\\\n  $tongue\nEOC\n"
  },
  {
    "path": "cows/ren.cow",
    "content": "##\n## Ren \n##\n$the_cow = <<EOC;\n   $thoughts\n    $thoughts\n    ____  \n   /# /_\\\\_\n  |  |/o\\\\o\\\\\n  |  \\\\\\\\_/_/\n / |_   |  \n|  ||\\\\_ ~| \n|  ||| \\\\/  \n|  |||_    \n \\\\//  |    \n  ||  |    \n  ||_  \\\\   \n  \\\\_|  o|  \n  /\\\\___/   \n /  ||||__ \n    (___)_)\nEOC\n"
  },
  {
    "path": "cows/sage.cow",
    "content": "## http://www.chris.com/ascii/joan/www.geocities.com/SoHo/7373/men.html#confucious\n$the_cow = <<EOC;\n   $thoughts\n    $thoughts\n      .\n    .:::.\n  .:::::::.\n V^V^V^V^V^V \n  (| ^ ^ |)      \n   | (_) | \n   `//=\\\\'      \n   (((()))\n    )))((\n    (())))\n     ))((\n     (()\n      ))\n      (\nEOC"
  },
  {
    "path": "cows/satanic.cow",
    "content": "##\n## Satanic cow, source unknown.\n##\n$the_cow = <<EOC;\n     $thoughts\n      $thoughts  (__)  \n         (\\\\/)  \n  /-------\\\\/    \n / | 666 ||    \n*  ||----||      \n   ~~    ~~      \nEOC\n"
  },
  {
    "path": "cows/sheep.cow",
    "content": "##\n## The non-flaming sheep.\n##\n$the_cow = <<EOC\n  $thoughts\n   $thoughts\n       __     \n      U${eyes}U\\\\.'\\@\\@\\@\\@\\@\\@`.\n      \\\\__/(\\@\\@\\@\\@\\@\\@\\@\\@\\@\\@)\n           (\\@\\@\\@\\@\\@\\@\\@\\@)\n           `YY~~~~YY'\n            ||    ||\nEOC\n"
  },
  {
    "path": "cows/skeleton.cow",
    "content": "##\n## This 'Scowleton' brought to you by one of \n## {appel,kube,rowe}@csua.berkeley.edu\n##\n$the_cow = <<EOC;\n          $thoughts      (__)      \n           $thoughts     /$eyes|  \n            $thoughts   (_\"_)*+++++++++*\n                   //I#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\I\\\\\n                   I[I|I|||||I I `\n                   I`I'///'' I I\n                   I I       I I\n                   ~ ~       ~ ~\n                     Scowleton\nEOC\n"
  },
  {
    "path": "cows/small.cow",
    "content": "##\n## A small cow, artist unknown\n##\n$the_cow = <<EOC;\n       $thoughts   ,__,\n        $thoughts  ($eyes)____\n           (__)    )\\\\\n            $tongue||--|| *\nEOC\n"
  },
  {
    "path": "cows/sodomized.cow",
    "content": "##\n## A cow performing an unnatural act, artist unknown.\n##\n$the_cow = <<EOC;\n      $thoughts                _\n       $thoughts              (_)\n        $thoughts   ^__^       / \\\\\n         $thoughts  ($eyes)\\\\_____/_\\\\ \\\\\n            (__)\\\\       ) /\n             $tongue ||----w ((\n                ||     ||>> \nEOC\n"
  },
  {
    "path": "cows/squirrel.cow",
    "content": "$the_cow = <<EOC;\n   $thoughts\n    $thoughts\n                  _ _\n       | \\__/|  .~    ~.\n       /$eyes `./      .'\n      {o__,   \\    {\n        / .  . )    \\\n        `-` '-' \\    }\n       .(   _(   )_.'\n      '---.~_ _ _|\n                                                     \nEOC\n"
  },
  {
    "path": "cows/stegosaurus.cow",
    "content": "##\n## A stegosaur with a top hat?\n##\n$the_cow = <<EOC;\n    $thoughts                         .       .\n     $thoughts                       / `.   .' \" \n      $thoughts              .---.  <    > <    >  .---.\n       $thoughts             |    \\\\  \\\\ - ~ ~ - /  /    |\n         _____          ..-~             ~-..-~\n        |     |   \\\\~~~\\\\.'                    `./~~~/\n       ---------   \\\\__/                        \\\\__/\n      .'  O    \\\\     /               /       \\\\  \" \n     (_____,    `._.'               |         }  \\\\/~~~/\n      `----.          /       }     |        /    \\\\__/\n            `-.      |       /      |       /      `. ,~~|\n                ~-.__|      /_ - ~ ^|      /- _      `..-'   \n                     |     /        |     /     ~-.     `-. _  _  _\n                     |_____|        |_____|         ~ - . _ _ _ _ _>\nEOC\n"
  },
  {
    "path": "cows/stimpy.cow",
    "content": "##\n## Stimpy!\n##\n$the_cow = <<EOC;\n  $thoughts     .    _  .    \n   $thoughts    |\\\\_|/__/|    \n       / / \\\\/ \\\\  \\\\  \n      /__|O||O|__ \\\\ \n     |/_ \\\\_/\\\\_/ _\\\\ |  \n     | | (____) | ||  \n     \\\\/\\\\___/\\\\__/  // \n     (_/         ||\n      |          ||\n      |          ||\\\\   \n       \\\\        //_/  \n        \\\\______//\n       __ || __||\n      (____(____)\nEOC\n"
  },
  {
    "path": "cows/supermilker.cow",
    "content": "##\n## A cow being milked, probably from Lars Smith (lars@csua.berkeley.edu)\n##\n$the_cow = <<EOC;\n  $thoughts   ^__^\n   $thoughts  ($eyes)\\\\_______        ________\n      (__)\\\\       )\\\\/\\\\    |Super |\n       $tongue ||----W |       |Milker|\n          ||    UDDDDDDDDD|______|\nEOC\n"
  },
  {
    "path": "cows/surgery.cow",
    "content": "##\n## A cow operation, artist unknown\n##\n$the_cow = <<EOC;\n          $thoughts           \\\\  / \n           $thoughts           \\\\/  \n               (__)    /\\\\         \n               ($eyes)   O  O        \n               _\\\\/_   //         \n         *    (    ) //       \n          \\\\  (\\\\\\\\    //       \n           \\\\(  \\\\\\\\    )                              \n            (   \\\\\\\\   )   /\\\\                          \n  ___[\\\\______/^^^^^^^\\\\__/) o-)__                     \n |\\\\__[=======______//________)__\\\\                    \n \\\\|_______________//____________|                    \n     |||      || //||     |||\n     |||      || @.||     |||                        \n      ||      \\\\/  .\\\\/      ||                        \n                 . .                                 \n                '.'.`                                \n\n            COW-OPERATION                           \nEOC\n"
  },
  {
    "path": "cows/telebears.cow",
    "content": "##\n## A cow performing an unnatural act, artist unknown.\n##\n$the_cow = <<EOC;\n      $thoughts                _\n       $thoughts              (_)   <-- TeleBEARS\n        $thoughts   ^__^       / \\\\\n         $thoughts  ($eyes)\\\\_____/_\\\\ \\\\\n            (__)\\\\  you  ) /\n             $tongue ||----w ((\n                ||     ||>> \nEOC\n"
  },
  {
    "path": "cows/turkey.cow",
    "content": "##\n## Turkey!\n##\n$the_cow = <<EOC;\n  $thoughts                                  ,+*^^*+___+++_\n   $thoughts                           ,*^^^^              )\n    $thoughts                       _+*                     ^**+_\n     $thoughts                    +^       _ _++*+_+++_,         )\n              _+^^*+_    (     ,+*^ ^          \\\\+_        )\n             {       )  (    ,(    ,_+--+--,      ^)      ^\\\\\n            { (\\@)    } f   ,(  ,+-^ __*_*_  ^^\\\\_   ^\\\\       )\n           {:;-/    (_+*-+^^^^^+*+*<_ _++_)_    )    )      /\n          ( /  (    (        ,___    ^*+_+* )   <    <      \\\\\n           U _/     )    *--<  ) ^\\\\-----++__)   )    )       )\n            (      )  _(^)^^))  )  )\\\\^^^^^))^*+/    /       /\n          (      /  (_))_^)) )  )  ))^^^^^))^^^)__/     +^^\n         (     ,/    (^))^))  )  ) ))^^^^^^^))^^)       _)\n          *+__+*       (_))^)  ) ) ))^^^^^^))^^^^^)____*^\n          \\\\             \\\\_)^)_)) ))^^^^^^^^^^))^^^^)\n           (_             ^\\\\__^^^^^^^^^^^^))^^^^^^^)\n             ^\\\\___            ^\\\\__^^^^^^))^^^^^^^^)\\\\\\\\\n                  ^^^^^\\\\uuu/^^\\\\uuu/^^^^\\\\^\\\\^\\\\^\\\\^\\\\^\\\\^\\\\^\\\\\n                     ___) >____) >___   ^\\\\_\\\\_\\\\_\\\\_\\\\_\\\\_\\\\)\n                    ^^^//\\\\\\\\_^^//\\\\\\\\_^       ^(\\\\_\\\\_\\\\_\\\\)\n                      ^^^ ^^ ^^^ ^\nEOC\n"
  },
  {
    "path": "cows/turtle.cow",
    "content": "##\n## A mysterious turtle...\n##\n$the_cow = <<EOC;\n    $thoughts                                  ___-------___\n     $thoughts                             _-~~             ~~-_\n      $thoughts                         _-~                    /~-_\n             /^\\\\__/^\\\\         /~  \\\\                   /    \\\\\n           /|  O|| O|        /      \\\\_______________/        \\\\\n          | |___||__|      /       /                \\\\          \\\\\n          |          \\\\    /      /                    \\\\          \\\\\n          |   (_______) /______/                        \\\\_________ \\\\\n          |         / /         \\\\                      /            \\\\\n           \\\\         \\\\^\\\\\\\\         \\\\                  /               \\\\     /\n             \\\\         ||           \\\\______________/      _-_       //\\\\__//\n               \\\\       ||------_-~~-_ ------------- \\\\ --/~   ~\\\\    || __/\n                 ~-----||====/~     |==================|       |/~~~~~\n                  (_(__/  ./     /                    \\\\_\\\\      \\\\.\n                         (_(___/                         \\\\_____)_)\nEOC\n"
  },
  {
    "path": "cows/tux.cow",
    "content": "##\n## TuX\n## (c) pborys@p-soft.silesia.linux.org.pl \n##\n$the_cow = <<EOC;\n   $thoughts\n    $thoughts\n        .--.\n       |o_o |\n       |:_/ |\n      //   \\\\ \\\\\n     (|     | )\n    /'\\\\_   _/`\\\\\n    \\\\___)=(___/\n\nEOC\n"
  },
  {
    "path": "cows/vader-koala.cow",
    "content": "##\n## Another canonical koala?\n##\n$the_cow = <<EOC;\n   $thoughts\n    $thoughts        .\n     .---.  //\n    Y|o o|Y// \n   /_(i=i)K/ \n   ~()~*~()~  \n    (_)-(_)   \n\n     Darth \n     Vader    \n     koala        \nEOC\n"
  },
  {
    "path": "cows/vader.cow",
    "content": "##\n## Cowth Vader, from geordan@csua.berkeley.edu\n##\n$the_cow = <<EOC;\n        $thoughts    ,-^-.\n         $thoughts   !oYo!\n          $thoughts /./=\\\\.\\\\______\n               ##        )\\\\/\\\\\n                ||-----w||\n                ||      ||\n\n               Cowth Vader\nEOC\n"
  },
  {
    "path": "cows/www.cow",
    "content": "##\n## A cow wadvertising the World Wide Web, from lim@csua.berkeley.edu\n##\n$the_cow = <<EOC;\n        $thoughts   ^__^\n         $thoughts  ($eyes)\\\\_______\n            (__)\\\\       )\\\\/\\\\\n             $tongue ||--WWW |\n                ||     ||\nEOC\n"
  },
  {
    "path": "cowsay.go",
    "content": "package cowsay\n\nimport (\n\t\"io/ioutil\"\n\t\"math/rand\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n)\n\nfunc init() {\n\trand.Seed(time.Now().UTC().UnixNano())\n}\n\n// Say to return cowsay string.\nfunc Say(phrase string, options ...Option) (string, error) {\n\tcow, err := New(options...)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn cow.Say(phrase)\n}\n\n// LocationType indicates the type of COWPATH.\ntype LocationType int\n\nconst (\n\t// InBinary indicates the COWPATH in binary.\n\tInBinary LocationType = iota\n\n\t// InDirectory indicates the COWPATH in your directory.\n\tInDirectory\n)\n\n// CowPath is information of the COWPATH.\ntype CowPath struct {\n\t// Name is name of the COWPATH.\n\t// If you specified `COWPATH=/foo/bar`, Name is `/foo/bar`.\n\tName string\n\t// CowFiles are name of the cowfile which are trimmed \".cow\" suffix.\n\tCowFiles []string\n\t// LocationType is the type of COWPATH\n\tLocationType LocationType\n}\n\n// Lookup will look for the target cowfile in the specified path.\n// If it exists, it returns the cowfile information and true value.\nfunc (c *CowPath) Lookup(target string) (*CowFile, bool) {\n\tfor _, cowfile := range c.CowFiles {\n\t\tif cowfile == target {\n\t\t\treturn &CowFile{\n\t\t\t\tName:         cowfile,\n\t\t\t\tBasePath:     c.Name,\n\t\t\t\tLocationType: c.LocationType,\n\t\t\t}, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// CowFile is information of the cowfile.\ntype CowFile struct {\n\t// Name is name of the cowfile.\n\tName string\n\t// BasePath is the path which the cowpath is in.\n\tBasePath string\n\t// LocationType is the type of COWPATH\n\tLocationType LocationType\n}\n\n// ReadAll reads the cowfile content.\n// If LocationType is InBinary, the file read from binary.\n// otherwise reads from file system.\nfunc (c *CowFile) ReadAll() ([]byte, error) {\n\tif c.LocationType == InBinary {\n\t\t// go embed is used \"/\" separator\n\t\tjoinedPath := path.Join(c.BasePath, c.Name+\".cow\")\n\t\treturn Asset(joinedPath)\n\t}\n\tjoinedPath := filepath.Join(c.BasePath, c.Name+\".cow\")\n\treturn ioutil.ReadFile(joinedPath)\n}\n\n// Cows to get list of cows\nfunc Cows() ([]*CowPath, error) {\n\tcowPaths, err := cowsFromCowPath()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcowPaths = append(cowPaths, &CowPath{\n\t\tName:         \"cows\",\n\t\tCowFiles:     CowsInBinary(),\n\t\tLocationType: InBinary,\n\t})\n\treturn cowPaths, nil\n}\n\nfunc cowsFromCowPath() ([]*CowPath, error) {\n\tcowPaths := make([]*CowPath, 0)\n\tcowPath := os.Getenv(\"COWPATH\")\n\tif cowPath == \"\" {\n\t\treturn cowPaths, nil\n\t}\n\tpaths := splitPath(cowPath)\n\tfor _, path := range paths {\n\t\tdirEntries, err := ioutil.ReadDir(path)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tpath := &CowPath{\n\t\t\tName:         path,\n\t\t\tCowFiles:     []string{},\n\t\t\tLocationType: InDirectory,\n\t\t}\n\t\tfor _, entry := range dirEntries {\n\t\t\tname := entry.Name()\n\t\t\tif strings.HasSuffix(name, \".cow\") {\n\t\t\t\tname = strings.TrimSuffix(name, \".cow\")\n\t\t\t\tpath.CowFiles = append(path.CowFiles, name)\n\t\t\t}\n\t\t}\n\t\tsort.Strings(path.CowFiles)\n\t\tcowPaths = append(cowPaths, path)\n\t}\n\treturn cowPaths, nil\n}\n\n// GetCow to get cow's ascii art\nfunc (cow *Cow) GetCow() (string, error) {\n\tsrc, err := cow.typ.ReadAll()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tr := strings.NewReplacer(\n\t\t\"\\\\\\\\\", \"\\\\\",\n\t\t\"\\\\@\", \"@\",\n\t\t\"\\\\$\", \"$\",\n\t\t\"$eyes\", cow.eyes,\n\t\t\"${eyes}\", cow.eyes,\n\t\t\"$tongue\", cow.tongue,\n\t\t\"${tongue}\", cow.tongue,\n\t\t\"$thoughts\", string(cow.thoughts),\n\t\t\"${thoughts}\", string(cow.thoughts),\n\t)\n\tnewsrc := r.Replace(string(src))\n\tseparate := strings.Split(newsrc, \"\\n\")\n\tmow := make([]string, 0, len(separate))\n\tfor _, line := range separate {\n\t\tif strings.Contains(line, \"$the_cow = <<EOC\") || strings.HasPrefix(line, \"##\") {\n\t\t\tcontinue\n\t\t}\n\n\t\tif strings.HasPrefix(line, \"EOC\") {\n\t\t\tbreak\n\t\t}\n\n\t\tmow = append(mow, line)\n\t}\n\treturn strings.Join(mow, \"\\n\"), nil\n}\n"
  },
  {
    "path": "cowsay_test.go",
    "content": "package cowsay\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n)\n\nfunc TestCows(t *testing.T) {\n\tt.Run(\"no set COWPATH env\", func(t *testing.T) {\n\t\tcowPaths, err := Cows()\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif len(cowPaths) != 1 {\n\t\t\tt.Fatalf(\"want 1, but got %d\", len(cowPaths))\n\t\t}\n\t\tcowPath := cowPaths[0]\n\t\tif len(cowPath.CowFiles) == 0 {\n\t\t\tt.Fatalf(\"no cowfiles\")\n\t\t}\n\n\t\twantCowPath := &CowPath{\n\t\t\tName:         \"cows\",\n\t\t\tLocationType: InBinary,\n\t\t}\n\t\tif diff := cmp.Diff(wantCowPath, cowPath,\n\t\t\tcmpopts.IgnoreFields(CowPath{}, \"CowFiles\"),\n\t\t); diff != \"\" {\n\t\t\tt.Errorf(\"(-want, +got)\\n%s\", diff)\n\t\t}\n\t})\n\n\tt.Run(\"set COWPATH env\", func(t *testing.T) {\n\t\tcowpath := filepath.Join(\"testdata\", \"testdir\")\n\n\t\tos.Setenv(\"COWPATH\", cowpath)\n\t\tdefer os.Unsetenv(\"COWPATH\")\n\n\t\tcowPaths, err := Cows()\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif len(cowPaths) != 2 {\n\t\t\tt.Fatalf(\"want 2, but got %d\", len(cowPaths))\n\t\t}\n\n\t\twants := []*CowPath{\n\t\t\t{\n\t\t\t\tName:         filepath.Join(\"testdata\", \"testdir\"),\n\t\t\t\tLocationType: InDirectory,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:         \"cows\",\n\t\t\t\tLocationType: InBinary,\n\t\t\t},\n\t\t}\n\t\tif diff := cmp.Diff(wants, cowPaths,\n\t\t\tcmpopts.IgnoreFields(CowPath{}, \"CowFiles\"),\n\t\t); diff != \"\" {\n\t\t\tt.Errorf(\"(-want, +got)\\n%s\", diff)\n\t\t}\n\n\t\tif len(cowPaths[0].CowFiles) != 1 {\n\t\t\tt.Fatalf(\"unexpected cowfiles len = %d, %+v\",\n\t\t\t\tlen(cowPaths[0].CowFiles), cowPaths[0].CowFiles,\n\t\t\t)\n\t\t}\n\n\t\tif cowPaths[0].CowFiles[0] != \"test\" {\n\t\t\tt.Fatalf(\"want %q but got %q\", \"test\", cowPaths[0].CowFiles[0])\n\t\t}\n\t})\n\n\tt.Run(\"set COWPATH env\", func(t *testing.T) {\n\t\tos.Setenv(\"COWPATH\", \"notfound\")\n\t\tdefer os.Unsetenv(\"COWPATH\")\n\n\t\t_, err := Cows()\n\t\tif err == nil {\n\t\t\tt.Fatal(\"want error\")\n\t\t}\n\t})\n\n}\n\nfunc TestCowPath_Lookup(t *testing.T) {\n\tt.Run(\"looked for cowfile\", func(t *testing.T) {\n\t\tc := &CowPath{\n\t\t\tName:         \"basepath\",\n\t\t\tCowFiles:     []string{\"test\"},\n\t\t\tLocationType: InBinary,\n\t\t}\n\t\tgot, ok := c.Lookup(\"test\")\n\t\tif !ok {\n\t\t\tt.Errorf(\"want %v\", ok)\n\t\t}\n\t\twant := &CowFile{\n\t\t\tName:         \"test\",\n\t\t\tBasePath:     \"basepath\",\n\t\t\tLocationType: InBinary,\n\t\t}\n\n\t\tif diff := cmp.Diff(want, got); diff != \"\" {\n\t\t\tt.Errorf(\"(-want, +got)\\n%s\", diff)\n\t\t}\n\t})\n\n\tt.Run(\"no cowfile\", func(t *testing.T) {\n\t\tc := &CowPath{\n\t\t\tName:         \"basepath\",\n\t\t\tCowFiles:     []string{\"test\"},\n\t\t\tLocationType: InBinary,\n\t\t}\n\t\tgot, ok := c.Lookup(\"no cowfile\")\n\t\tif ok {\n\t\t\tt.Errorf(\"want %v\", !ok)\n\t\t}\n\t\tif got != nil {\n\t\t\tt.Error(\"want nil\")\n\t\t}\n\t})\n}\n\nfunc TestCowFile_ReadAll(t *testing.T) {\n\tfromTestData := &CowFile{\n\t\tName:         \"test\",\n\t\tBasePath:     filepath.Join(\"testdata\", \"testdir\"),\n\t\tLocationType: InDirectory,\n\t}\n\tfromTestdataContent, err := fromTestData.ReadAll()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tfromBinary := &CowFile{\n\t\tName:         \"default\",\n\t\tBasePath:     \"cows\",\n\t\tLocationType: InBinary,\n\t}\n\tfromBinaryContent, err := fromBinary.ReadAll()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tif !bytes.Equal(fromTestdataContent, fromBinaryContent) {\n\t\tt.Fatalf(\"testdata\\n%s\\n\\nbinary%s\\n\", string(fromTestdataContent), string(fromBinaryContent))\n\t}\n\n}\n\nconst defaultSay = ` ________ \n< cowsay >\n -------- \n        \\   ^__^\n         \\  (oo)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||`\n\nfunc TestSay(t *testing.T) {\n\ttype args struct {\n\t\tphrase  string\n\t\toptions []Option\n\t}\n\ttests := []struct {\n\t\tname     string\n\t\targs     args\n\t\twantFile string\n\t\twantErr  bool\n\t}{\n\t\t{\n\t\t\tname: \"default\",\n\t\t\targs: args{\n\t\t\t\tphrase: \"hello!\",\n\t\t\t},\n\t\t\twantFile: \"default.cow\",\n\t\t\twantErr:  false,\n\t\t},\n\t\t{\n\t\t\tname: \"nest\",\n\t\t\targs: args{\n\t\t\t\tphrase: defaultSay,\n\t\t\t\toptions: []Option{\n\t\t\t\t\tDisableWordWrap(),\n\t\t\t\t},\n\t\t\t},\n\t\t\twantFile: \"nest.cow\",\n\t\t\twantErr:  false,\n\t\t},\n\t\t{\n\t\t\tname: \"error\",\n\t\t\targs: args{\n\t\t\t\tphrase: \"error\",\n\t\t\t\toptions: []Option{\n\t\t\t\t\tfunc(*Cow) error {\n\t\t\t\t\t\treturn errors.New(\"error\")\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\twantErr: true,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot, err := Say(tt.args.phrase, tt.args.options...)\n\t\t\tif (err != nil) != tt.wantErr {\n\t\t\t\tt.Errorf(\"Say() error = %v, wantErr %v\", err, tt.wantErr)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif tt.wantErr {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tfilename := filepath.Join(\"testdata\", tt.wantFile)\n\t\t\tcontent, err := ioutil.ReadFile(filename)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tgot = strings.Replace(got, \"\\r\", \"\", -1)               // for windows\n\t\t\twant := strings.Replace(string(content), \"\\r\", \"\", -1) // for windows\n\t\t\tif want != got {\n\t\t\t\tt.Log(cmp.Diff([]byte(want), []byte(got)))\n\t\t\t\tt.Fatalf(\"want\\n%s\\n\\ngot\\n%s\", want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "decoration/aurora.go",
    "content": "package decoration\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\nfunc (w *Writer) writeAsAurora(b []byte) (nn int, err error) {\n\tdefer w.buf.Reset()\n\n\tfor len(b) > 0 {\n\t\tchar, size := utf8.DecodeRune(b)\n\t\tif char == '\\n' {\n\t\t\tw.buf.WriteRune(char)\n\t\t\tb = b[size:]\n\t\t\tcontinue\n\t\t}\n\t\tif unicode.IsSpace(char) {\n\t\t\tw.buf.WriteRune(char)\n\t\t} else {\n\t\t\tfmt.Fprintf(&w.buf, \"\\033[38;5;%d%sm%c\\033[0m\",\n\t\t\t\trgb(float64(w.options.colorSeq)),\n\t\t\t\tw.options.maybeBold(),\n\t\t\t\tchar,\n\t\t\t)\n\t\t}\n\t\tw.options.colorSeq++\n\t\tb = b[size:]\n\t}\n\n\treturn w.writer.Write(w.buf.Bytes())\n}\n\nfunc (w *Writer) writeStringAsAurora(s string) (nn int, err error) {\n\tdefer w.buf.Reset()\n\n\tfor _, char := range s {\n\t\tif char == '\\n' {\n\t\t\tw.buf.WriteRune(char)\n\t\t\tcontinue\n\t\t}\n\t\tif unicode.IsSpace(char) {\n\t\t\tw.buf.WriteRune(char)\n\t\t} else {\n\t\t\tfmt.Fprintf(&w.buf, \"\\033[38;5;%d%sm%c\\033[0m\",\n\t\t\t\trgb(float64(w.options.colorSeq)),\n\t\t\t\tw.options.maybeBold(),\n\t\t\t\tchar,\n\t\t\t)\n\t\t}\n\t\tw.options.colorSeq++\n\t}\n\tif sw, ok := w.writer.(io.StringWriter); ok {\n\t\treturn sw.WriteString(w.buf.String())\n\t}\n\treturn w.writer.Write(w.buf.Bytes())\n}\n\n// https://sking7.github.io/articles/139888127.html#:~:text=value%20of%20frequency.-,Using,-out-of-phase\nconst (\n\tfreq = 0.01\n\tm    = math.Pi / 3\n\n\tredPhase   = 0\n\tgreenPhase = 2 * m\n\tbluePhase  = 4 * m\n)\n\nvar rgbMemo = map[float64]int64{}\n\nfunc rgb(i float64) int64 {\n\tif v, ok := rgbMemo[i]; ok {\n\t\treturn v\n\t}\n\tred := int64(6*(math.Sin(freq*i+redPhase)*127+128)/256) * 36\n\tgreen := int64(6*(math.Sin(freq*i+greenPhase)*127+128)/256) * 6\n\tblue := int64(6*(math.Sin(freq*i+bluePhase)*127+128)/256) * 1\n\trgbMemo[i] = 16 + red + green + blue\n\treturn rgbMemo[i]\n}\n"
  },
  {
    "path": "decoration/bold.go",
    "content": "package decoration\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\nfunc (w *Writer) writeAsDefaultBold(b []byte) (nn int, err error) {\n\tdefer w.buf.Reset()\n\n\tfor len(b) > 0 {\n\t\tchar, size := utf8.DecodeRune(b)\n\t\tif char == '\\n' {\n\t\t\tw.buf.WriteRune(char)\n\t\t\tb = b[size:]\n\t\t\tcontinue\n\t\t}\n\t\tif unicode.IsSpace(char) {\n\t\t\tw.buf.WriteRune(char)\n\t\t} else {\n\t\t\tfmt.Fprintf(&w.buf, \"\\x1b[1m%c\\x1b[0m\", char)\n\t\t}\n\t\tb = b[size:]\n\t}\n\treturn w.writer.Write(w.buf.Bytes())\n}\n\nfunc (w *Writer) writeStringAsDefaultBold(s string) (nn int, err error) {\n\tdefer w.buf.Reset()\n\n\tfor _, char := range s {\n\t\tif char == '\\n' {\n\t\t\tw.buf.WriteRune(char)\n\t\t\tcontinue\n\t\t}\n\t\tif unicode.IsSpace(char) {\n\t\t\tw.buf.WriteRune(char)\n\t\t} else {\n\t\t\tfmt.Fprintf(&w.buf, \"\\x1b[1m%c\\x1b[0m\", char)\n\t\t}\n\t}\n\tif sw, ok := w.writer.(io.StringWriter); ok {\n\t\treturn sw.WriteString(w.buf.String())\n\t}\n\treturn w.writer.Write(w.buf.Bytes())\n}\n"
  },
  {
    "path": "decoration/decoration.go",
    "content": "package decoration\n\nimport (\n\t\"bytes\"\n\t\"io\"\n)\n\ntype options struct {\n\twithBold    bool\n\twithRainbow bool\n\twithAurora  bool\n\tcolorSeq    int\n}\n\nfunc (o *options) maybeBold() string {\n\tif o.withBold {\n\t\treturn \";1\"\n\t}\n\treturn \"\"\n}\n\n// Option for any writer in this package.\ntype Option func(o *options)\n\n// WithBold writes with bold.\nfunc WithBold() Option {\n\treturn func(o *options) {\n\t\to.withBold = true\n\t}\n}\n\n// WithRainbow writes with rainbow.\nfunc WithRainbow() Option {\n\treturn func(o *options) {\n\t\to.withRainbow = true\n\t}\n}\n\n// WithAurora writes with aurora.\nfunc WithAurora(initialSeq int) Option {\n\treturn func(o *options) {\n\t\to.withAurora = true\n\t\to.colorSeq = initialSeq\n\t}\n}\n\n// Writer is a writer to decorates.\ntype Writer struct {\n\twriter  io.Writer\n\tbuf     bytes.Buffer\n\toptions *options\n}\n\nvar _ interface {\n\tio.Writer\n\tio.StringWriter\n} = (*Writer)(nil)\n\n// NewWriter creates a new writer.\nfunc NewWriter(w io.Writer, opts ...Option) *Writer {\n\toptions := new(options)\n\tfor _, optFunc := range opts {\n\t\toptFunc(options)\n\t}\n\treturn &Writer{\n\t\twriter:  w,\n\t\toptions: options,\n\t}\n}\n\n// SetColorSeq sets current color sequence.\nfunc (w *Writer) SetColorSeq(colorSeq int) {\n\tw.options.colorSeq = colorSeq\n}\n\n// Write writes bytes. which is implemented io.Writer.\n//\n// If Bold is enabled in the options, the text will be written as Bold.\n// If both Aurora and Rainbow are enabled in the options, Aurora will take precedence.\nfunc (w *Writer) Write(b []byte) (nn int, err error) {\n\tswitch {\n\tcase w.options.withAurora:\n\t\treturn w.writeAsAurora(b)\n\tcase w.options.withRainbow:\n\t\treturn w.writeAsRainbow(b)\n\tcase w.options.withBold:\n\t\treturn w.writeAsDefaultBold(b)\n\tdefault:\n\t\treturn w.writer.Write(b)\n\t}\n}\n\n// WriteString writes string. which is implemented io.StringWriter.\n//\n// See also Write.\nfunc (w *Writer) WriteString(s string) (n int, err error) {\n\tswitch {\n\tcase w.options.withAurora:\n\t\treturn w.writeStringAsAurora(s)\n\tcase w.options.withRainbow:\n\t\treturn w.writeStringAsRainbow(s)\n\tcase w.options.withBold:\n\t\treturn w.writeStringAsDefaultBold(s)\n\tdefault:\n\t\tif sw, ok := w.writer.(io.StringWriter); ok {\n\t\t\treturn sw.WriteString(w.buf.String())\n\t\t}\n\t\treturn w.writer.Write([]byte(s))\n\t}\n}\n"
  },
  {
    "path": "decoration/rainbow.go",
    "content": "package decoration\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\nconst (\n\tred = iota + 31\n\tgreen\n\tyellow\n\tblue\n\tmagenta\n\tcyan\n)\n\nvar rainbow = []int{magenta, red, yellow, green, cyan, blue}\n\nfunc (w *Writer) writeAsRainbow(b []byte) (nn int, err error) {\n\tdefer w.buf.Reset()\n\n\tfor len(b) > 0 {\n\t\tchar, size := utf8.DecodeRune(b)\n\t\tif char == '\\n' {\n\t\t\tw.options.colorSeq = 0\n\t\t\tw.buf.WriteRune(char)\n\t\t\tb = b[size:]\n\t\t\tcontinue\n\t\t}\n\t\tif unicode.IsSpace(char) {\n\t\t\tw.buf.WriteRune(char)\n\t\t} else {\n\t\t\tfmt.Fprintf(&w.buf, \"\\x1b[%d%sm%c\\x1b[0m\",\n\t\t\t\trainbow[w.options.colorSeq%len(rainbow)],\n\t\t\t\tw.options.maybeBold(),\n\t\t\t\tchar,\n\t\t\t)\n\t\t}\n\t\tw.options.colorSeq++\n\t\tb = b[size:]\n\t}\n\n\treturn w.writer.Write(w.buf.Bytes())\n}\n\nfunc (w *Writer) writeStringAsRainbow(s string) (nn int, err error) {\n\tdefer w.buf.Reset()\n\n\tfor _, char := range s {\n\t\tif char == '\\n' {\n\t\t\tw.options.colorSeq = 0\n\t\t\tw.buf.WriteRune(char)\n\t\t\tcontinue\n\t\t}\n\t\tif unicode.IsSpace(char) {\n\t\t\tw.buf.WriteRune(char)\n\t\t} else {\n\t\t\tfmt.Fprintf(&w.buf, \"\\x1b[%d%sm%c\\x1b[0m\",\n\t\t\t\trainbow[w.options.colorSeq%len(rainbow)],\n\t\t\t\tw.options.maybeBold(),\n\t\t\t\tchar,\n\t\t\t)\n\t\t}\n\t\tw.options.colorSeq++\n\t}\n\n\tif sw, ok := w.writer.(io.StringWriter); ok {\n\t\treturn sw.WriteString(w.buf.String())\n\t}\n\treturn w.writer.Write(w.buf.Bytes())\n}\n"
  },
  {
    "path": "doc/cowsay.1",
    "content": "'\\\" t\n.\\\"     Title: cowsay\n.\\\"    Author: [see the \"AUTHOR(S)\" section]\n.\\\" Generator: Asciidoctor 2.0.16\n.\\\"      Date: 2021-11-13\n.\\\"    Manual: \\ \\&\n.\\\"    Source: \\ \\&\n.\\\"  Language: English\n.\\\"\n.TH \"NEO COWSAY/COWTHINK\" \"1\" \"2021-11-13\" \"\\ \\&\" \"\\ \\&\"\n.ie \\n(.g .ds Aq \\(aq\n.el       .ds Aq '\n.ss \\n[.ss] 0\n.nh\n.ad l\n.de URL\n\\fI\\\\$2\\fP <\\\\$1>\\\\$3\n..\n.als MTO URL\n.if \\n[.g] \\{\\\n.  mso www.tmac\n.  am URL\n.    ad l\n.  .\n.  am MTO\n.    ad l\n.  .\n.  LINKSTYLE blue R < >\n.\\}\n.SH \"NAME\"\nNeo cowsay/cowthink \\- configurable speaking/thinking cow (and a bit more)\n.SH \"SYNOPSIS\"\n.sp\ncowsay [\\-e \\fIeye_string\\fP] [\\-f \\fIcowfile\\fP] [\\-h] [\\-l] [\\-n] [\\-T \\fItongue_string\\fP] [\\-W \\fIcolumn\\fP] [\\-bdgpstwy]\n[\\-\\-random] [\\-\\-bold] [\\-\\-rainbow] [\\-\\-aurora] [\\-\\-super] [\\fImessage\\fP]\n.SH \"DESCRIPTION\"\n.sp\n\\fINeo\\-cowsay\\fP (cowsay) generates an ASCII picture of a cow saying something provided by the\nuser.  If run with no arguments, it accepts standard input, word\\-wraps\nthe message given at about 40 columns, and prints the cow saying the\ngiven message on standard output.\n.sp\nTo aid in the use of arbitrary messages with arbitrary whitespace,\nuse the \\fB\\-n\\fP option.  If it is specified, the given message will not be\nword\\-wrapped.  This is possibly useful if you want to make the cow\nthink or speak in figlet(6).  If \\fB\\-n\\fP is specified, there must not be any command\\-line arguments left\nafter all the switches have been processed.\n.sp\nThe \\fB\\-W\\fP specifies roughly (where the message should be wrapped. The default\nis equivalent to \\fB\\-W 40\\fP i.e. wrap words at or before the 40th column.\n.sp\nIf any command\\-line arguments are left over after all switches have\nbeen processed, they become the cow\\(cqs message. The program will not\naccept standard input for a message in this case.\n.sp\nThere are several provided modes which change the appearance of the\ncow depending on its particular emotional/physical state.\n.sp\nThe \\fB\\-b\\fP option initiates Borg mode\n.sp\n\\fB\\-d\\fP causes the cow to appear dead\n.sp\n\\fB\\-g\\fP invokes greedy mode\n.sp\n\\fB\\-p\\fP causes a state of paranoia to come over the cow\n.sp\n\\fB\\-s\\fP makes the cow appear thoroughly stoned\n.sp\n\\fB\\-t\\fP yields a tired cow\n.sp\n\\fB\\-w\\fP is somewhat the opposite of \\fB\\-t\\fP and initiates wired mode\n.sp\n\\fB\\-y\\fP brings on the cow\\(cqs youthful appearance.\n.sp\nThe user may specify the \\fB\\-e\\fP option to select the appearance of the cow\\(cqs eyes, in which case\nthe first two characters of the argument string \\fIeye_string\\fP will be used. The default eyes are \\fIoo\\fP. The tongue is similarly\nconfigurable through \\fB\\-T\\fP and \\fItongue_string\\fP; it must be two characters and does not appear by default. However,\nit does appear in the \\fIdead\\fP and \\fIstoned\\fP modes. Any configuration\ndone by \\fB\\-e\\fP and \\fB\\-T\\fP will be lost if one of the provided modes is used.\n.sp\nThe \\fB\\-f\\fP option specifies a particular cow picture file (\\(lqcowfile\\(rq) to\nuse. If the cowfile spec contains \\fI/\\fP then it will be interpreted\nas a path relative to the current directory. Otherwise, cowsay\nwill search the path specified in the \\fBCOWPATH\\fP environment variable. If \\fB\\-f \\-\\fP is specified, provides\ninteractive Unix filter (command\\-line fuzzy finder) to search the cowfile.\n.sp\nTo list all cowfiles on the current \\fBCOWPATH\\fP, invoke \\fBcowsay\\fP with the \\fB\\-l\\fP switch.\n.sp\n\\fB\\-\\-random\\fP pick randomly from available cowfiles\n.sp\n\\fB\\-\\-bold\\fP outputs as bold text\n.sp\n\\fB\\-\\-rainbow\\fP and \\fB\\-\\-aurora\\fP filters with colors an ASCII picture of a cow saying something\n.sp\n\\fB\\-\\-super\\fP ...enjoy!\n.sp\nIf the program is invoked as \\fBcowthink\\fP then the cow will think its message instead of saying it.\n.SH \"COWFILE FORMAT\"\n.sp\nA cowfile is made up of a simple block of \\fBperl(1)\\fP code, which assigns a picture of a cow to the variable \\fB$the_cow\\fP.\nShould you wish to customize the eyes or the tongue of the cow,\nthen the variables \\fB$eyes\\fP and \\fB$tongue\\fP may be used. The trail leading up to the cow\\(cqs message balloon is\ncomposed of the character(s) in the \\fB$thoughts\\fP variable. Any backslashes must be reduplicated to prevent interpolation.\nThe name of a cowfile should end with \\fB.cow ,\\fP otherwise it is assumed not to be a cowfile. Also, at\\-signs (\\(lq@\\(rq)\nmust be backslashed because that is what Perl 5 expects.\n.SH \"ENVIRONMENT\"\n.sp\nThe COWPATH environment variable, if present, will be used to search\nfor cowfiles.  It contains a colon\\-separated list of directories,\nmuch like \\fBPATH or MANPATH\\fP. It should always contain the \\fB/usr/local/share/cows\\fP\ndirectory, or at least a directory with a file called \\fBdefault.cow\\fP in it.\n.SH \"FILES\"\n.sp\n\\fB%PREFIX%/share/cows\\fP holds a sample set of cowfiles. If your \\fBCOWPATH\\fP is not explicitly set, it automatically contains this directory.\n.SH \"BUGS\"\n.sp\n.URL \"https://github.com/Code\\-Hex/Neo\\-cowsay\" \"\" \"\"\n.sp\nIf there are any, please report bugs and feature requests in the issue tracker.\nPlease do your best to provide a reproducible test case for bugs. This should\ninclude the \\fBcowsay\\fP command, the actual output and the expected output.\n.SH \"AUTHORS\"\n.sp\nNeo\\-cowsay author is Kei Kamikawa (\\c\n.MTO \"x00.x7f.x86\\(atgmail.com\" \"\" \").\"\n.sp\nThe original author is Tony Monroe (\\c\n.MTO \"tony\\(atnog.net\" \"\" \"),\"\nwith suggestions from Shannon\nAppel (\\c\n.MTO \"appel\\(atCSUA.Berkeley.EDU\" \"\" \")\"\nand contributions from Anthony Polito\n(\\c\n.MTO \"aspolito\\(atCSUA.Berkeley.EDU\" \"\" \").\"\n.SH \"SEE ALSO\"\n.sp\nperl(1), wall(1), nwrite(1), figlet(6)"
  },
  {
    "path": "doc/cowsay.1.txt.tpl",
    "content": "cowsay(1)\n=========\n\nName\n----\nNeo cowsay/cowthink - configurable speaking/thinking cow (and a bit more)\n\nSYNOPSIS\n--------\ncowsay [-e _eye_string_] [-f _cowfile_] [-h] [-l] [-n] [-T _tongue_string_] [-W _column_] [-bdgpstwy]\n       [--random] [--bold] [--rainbow] [--aurora] [--super] [_message_]\n\nDESCRIPTION\n-----------\n_Neo-cowsay_ (cowsay) generates an ASCII picture of a cow saying something provided by the\nuser.  If run with no arguments, it accepts standard input, word-wraps\nthe message given at about 40 columns, and prints the cow saying the\ngiven message on standard output.\n\nTo aid in the use of arbitrary messages with arbitrary whitespace,\nuse the *-n* option.  If it is specified, the given message will not be\nword-wrapped.  This is possibly useful if you want to make the cow\nthink or speak in figlet(6).  If *-n* is specified, there must not be any command-line arguments left\nafter all the switches have been processed.\n\nThe *-W* specifies roughly (where the message should be wrapped. The default\nis equivalent to *-W 40* i.e. wrap words at or before the 40th column.\n\nIf any command-line arguments are left over after all switches have\nbeen processed, they become the cow's message. The program will not\naccept standard input for a message in this case.\n\nThere are several provided modes which change the appearance of the\ncow depending on its particular emotional/physical state. \n\nThe *-b* option initiates Borg mode\n\n*-d* causes the cow to appear dead \n\n*-g* invokes greedy mode\n\n*-p* causes a state of paranoia to come over the cow\n\n*-s* makes the cow appear thoroughly stoned\n\n*-t* yields a tired cow\n\n*-w* is somewhat the opposite of *-t* and initiates wired mode\n\n*-y* brings on the cow's youthful appearance.\n\nThe user may specify the *-e* option to select the appearance of the cow's eyes, in which case\nthe first two characters of the argument string _eye_string_ will be used. The default eyes are 'oo'. The tongue is similarly\nconfigurable through *-T* and _tongue_string_; it must be two characters and does not appear by default. However,\nit does appear in the 'dead' and 'stoned' modes. Any configuration\ndone by *-e* and *-T* will be lost if one of the provided modes is used.\n\nThe *-f* option specifies a particular cow picture file (``cowfile'') to\nuse. If the cowfile spec contains '/' then it will be interpreted\nas a path relative to the current directory. Otherwise, cowsay\nwill search the path specified in the *COWPATH* environment variable. If *-f -* is specified, provides\ninteractive Unix filter (command-line fuzzy finder) to search the cowfile.\n\nTo list all cowfiles on the current *COWPATH*, invoke *cowsay* with the *-l* switch.\n\n*--random* pick randomly from available cowfiles\n\n*--bold* outputs as bold text\n\n*--rainbow* and *--aurora* filters with colors an ASCII picture of a cow saying something\n\n*--super* ...enjoy!\n\nIf the program is invoked as *cowthink* then the cow will think its message instead of saying it.\n\nCOWFILE FORMAT\n--------------\nA cowfile is made up of a simple block of *perl(1)* code, which assigns a picture of a cow to the variable *$the_cow*.\nShould you wish to customize the eyes or the tongue of the cow,\nthen the variables *$eyes* and *$tongue* may be used. The trail leading up to the cow's message balloon is\ncomposed of the character(s) in the *$thoughts* variable. Any backslashes must be reduplicated to prevent interpolation.\nThe name of a cowfile should end with *.cow ,* otherwise it is assumed not to be a cowfile. Also, at-signs (``@'')\nmust be backslashed because that is what Perl 5 expects.\n\nENVIRONMENT\n-----------\nThe COWPATH environment variable, if present, will be used to search\nfor cowfiles.  It contains a colon-separated list of directories,\nmuch like *PATH or MANPATH*. It should always contain the */usr/local/share/cows*\ndirectory, or at least a directory with a file called *default.cow* in it.\n\nFILES\n-----\n*%PREFIX%/share/cows* holds a sample set of cowfiles. If your *COWPATH* is not explicitly set, it automatically contains this directory.\n\nBUGS\n----\nhttps://github.com/Code-Hex/Neo-cowsay\n\nIf there are any, please report bugs and feature requests in the issue tracker.\nPlease do your best to provide a reproducible test case for bugs. This should\ninclude the *cowsay* command, the actual output and the expected output.\n\nAUTHORS\n-------\nNeo-cowsay author is Kei Kamikawa (x00.x7f.x86@gmail.com).\n\nThe original author is Tony Monroe (tony@nog.net), with suggestions from Shannon\nAppel (appel@CSUA.Berkeley.EDU) and contributions from Anthony Polito\n(aspolito@CSUA.Berkeley.EDU).\n\nSEE ALSO\n--------\nperl(1), wall(1), nwrite(1), figlet(6)"
  },
  {
    "path": "embed.go",
    "content": "package cowsay\n\nimport (\n\t\"embed\"\n\t\"sort\"\n\t\"strings\"\n)\n\n//go:embed cows/*\nvar cowsDir embed.FS\n\n// Asset loads and returns the asset for the given name.\n// It returns an error if the asset could not be found or\n// could not be loaded.\nfunc Asset(path string) ([]byte, error) {\n\treturn cowsDir.ReadFile(path)\n}\n\n// AssetNames returns the list of filename of the assets.\nfunc AssetNames() []string {\n\tentries, err := cowsDir.ReadDir(\"cows\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tnames := make([]string, 0, len(entries))\n\tfor _, entry := range entries {\n\t\tname := strings.TrimSuffix(entry.Name(), \".cow\")\n\t\tnames = append(names, name)\n\t}\n\tsort.Strings(names)\n\treturn names\n}\n\nvar cowsInBinary = AssetNames()\n\n// CowsInBinary returns the list of cowfiles which are in binary.\n// the list is memoized.\nfunc CowsInBinary() []string {\n\treturn cowsInBinary\n}\n"
  },
  {
    "path": "examples/basic/go.mod",
    "content": "module github.com/Code-Hex/Neo-cowsay/v2/example\n\ngo 1.16\n\nrequire github.com/Code-Hex/Neo-cowsay/v2 v2.0.1\n\nreplace github.com/Code-Hex/Neo-cowsay/v2 => ../../\n"
  },
  {
    "path": "examples/basic/go.sum",
    "content": "github.com/Code-Hex/go-wordwrap v1.0.0 h1:yl5fLyZEz3+hPGbpTRlTQ8mQJ1HXWcTq1FCNR1ch6zM=\ngithub.com/Code-Hex/go-wordwrap v1.0.0/go.mod h1:/SsbgkY2Q0aPQRyvXcyQwWYTQOIwSORKe6MPjRVGIWU=\ngithub.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=\ngithub.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=\ngithub.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=\ngithub.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\n"
  },
  {
    "path": "examples/basic/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\n\tcowsay \"github.com/Code-Hex/Neo-cowsay/v2\"\n)\n\nfunc main() {\n\tif false {\n\t\tsimple()\n\t} else {\n\t\tcomplex()\n\t}\n}\n\nfunc simple() {\n\tsay, err := cowsay.Say(\n\t\t\"Hello\",\n\t\tcowsay.Type(\"default\"),\n\t\tcowsay.BallonWidth(40),\n\t)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(say)\n}\n\nfunc complex() {\n\tcow, err := cowsay.New(\n\t\tcowsay.BallonWidth(40),\n\t\t//cowsay.Thinking(),\n\t\tcowsay.Random(),\n\t)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tsay, err := cow.Say(\"Hello\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(say)\n}\n"
  },
  {
    "path": "examples/echo-server/README.md",
    "content": "## echo server\n\n```\n$ go build\n$ ./echo-server\n2021/11/14 16:16:27 server addr => 127.0.0.1:54456\n```\n\n\n## client\n\nUse [netcat](https://en.wikipedia.org/wiki/Netcat)\n\nPlease enter `^D` (control + D) after you enter any characters.\n\n```\n$ nc 127.0.0.1 54456\nhello\n _______\n< hello >\n -------\n        \\   ^__^\n         \\  (oo)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||\n```\n"
  },
  {
    "path": "examples/echo-server/go.mod",
    "content": "module github.com/Code-Hex/Neo-cowsay/v2/examples/echo-server\n\ngo 1.16\n\nrequire github.com/Code-Hex/Neo-cowsay/v2 v2.0.1\n\nreplace github.com/Code-Hex/Neo-cowsay/v2 => ../../\n"
  },
  {
    "path": "examples/echo-server/go.sum",
    "content": "github.com/Code-Hex/go-wordwrap v1.0.0 h1:yl5fLyZEz3+hPGbpTRlTQ8mQJ1HXWcTq1FCNR1ch6zM=\ngithub.com/Code-Hex/go-wordwrap v1.0.0/go.mod h1:/SsbgkY2Q0aPQRyvXcyQwWYTQOIwSORKe6MPjRVGIWU=\ngithub.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=\ngithub.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=\ngithub.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=\ngithub.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\n"
  },
  {
    "path": "examples/echo-server/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"log\"\n\t\"net\"\n\t\"os\"\n\t\"os/signal\"\n\t\"strings\"\n\t\"time\"\n\n\tcowsay \"github.com/Code-Hex/Neo-cowsay/v2\"\n)\n\nconst limit = 1000\n\nfunc main() {\n\tln, err := net.Listen(\"tcp\", \"127.0.0.1:0\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tlog.Println(\"server addr =>\", ln.Addr())\n\n\tctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)\n\tdefer cancel()\n\n\tgo func() {\n\t\tfor {\n\t\t\tconn, err := ln.Accept()\n\t\t\tif err != nil {\n\t\t\t\tlog.Println(err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconn.SetDeadline(time.Now().Add(5 * time.Second))\n\n\t\t\tgo func() {\n\t\t\t\tdefer conn.Close()\n\t\t\t\tgo func() {\n\t\t\t\t\t<-ctx.Done()\n\t\t\t\t\t// cancel\n\t\t\t\t\tconn.SetDeadline(time.Now())\n\t\t\t\t}()\n\n\t\t\t\tvar buf strings.Builder\n\t\t\t\trd := io.LimitReader(conn, limit)\n\t\t\t\tif _, err := io.Copy(&buf, rd); err != nil {\n\t\t\t\t\tlog.Println(\"error:\", err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tphrase := strings.TrimSpace(buf.String())\n\t\t\t\tlog.Println(phrase)\n\t\t\t\tsay, _ := cowsay.Say(phrase)\n\t\t\t\tconn.Write([]byte(say))\n\t\t\t}()\n\t\t}\n\t}()\n\n\t<-ctx.Done()\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/Code-Hex/Neo-cowsay/v2\n\nrequire (\n\tgithub.com/Code-Hex/go-wordwrap v1.0.0\n\tgithub.com/google/go-cmp v0.5.6\n\tgithub.com/mattn/go-runewidth v0.0.13\n\tgolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect\n)\n\ngo 1.16\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/Code-Hex/go-wordwrap v1.0.0 h1:yl5fLyZEz3+hPGbpTRlTQ8mQJ1HXWcTq1FCNR1ch6zM=\ngithub.com/Code-Hex/go-wordwrap v1.0.0/go.mod h1:/SsbgkY2Q0aPQRyvXcyQwWYTQOIwSORKe6MPjRVGIWU=\ngithub.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=\ngithub.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=\ngithub.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=\ngithub.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\n"
  },
  {
    "path": "split.go",
    "content": "//go:build !windows\n// +build !windows\n\npackage cowsay\n\nimport \"strings\"\n\nfunc splitPath(s string) []string {\n\treturn strings.Split(s, \":\")\n}\n"
  },
  {
    "path": "split_windows.go",
    "content": "//go:build windows\n// +build windows\n\npackage cowsay\n\nimport \"strings\"\n\nfunc splitPath(s string) []string {\n\treturn strings.Split(s, \";\")\n}\n"
  },
  {
    "path": "testdata/default.cow",
    "content": " ________ \n< hello! >\n -------- \n        \\   ^__^\n         \\  (oo)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||"
  },
  {
    "path": "testdata/nest.cow",
    "content": " ______________________________ \n/  ________                    \\\n| < cowsay >                   |\n|  --------                    |\n|         \\   ^__^             |\n|          \\  (oo)\\_______     |\n|             (__)\\       )\\/\\ |\n|                 ||----w |    |\n\\                 ||     ||    /\n ------------------------------ \n        \\   ^__^\n         \\  (oo)\\_______\n            (__)\\       )\\/\\\n                ||----w |\n                ||     ||"
  },
  {
    "path": "testdata/testdir/test.cow",
    "content": "$the_cow = <<EOC;\n        $thoughts   ^__^\n         $thoughts  ($eyes)\\\\_______\n            (__)\\\\       )\\\\/\\\\\n             $tongue ||----w |\n                ||     ||\nEOC\n"
  }
]