{"id":26649062,"url":"https://github.com/mandelsoft/ttyprogress","last_synced_at":"2026-04-27T12:05:18.561Z","repository":{"id":283498579,"uuid":"951960231","full_name":"mandelsoft/ttyprogress","owner":"mandelsoft","description":"Progress Indicator Framework for Terminal Output","archived":false,"fork":false,"pushed_at":"2025-10-15T20:51:04.000Z","size":24921,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-16T21:52:49.940Z","etag":null,"topics":["colors","console","golang","golang-library","indicators","progress","progressbar","terminal","tty"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mandelsoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-03-20T14:09:53.000Z","updated_at":"2025-10-15T20:51:08.000Z","dependencies_parsed_at":"2025-04-04T19:20:54.540Z","dependency_job_id":"80a35faa-f650-4d9f-8b7f-99bc86844f24","html_url":"https://github.com/mandelsoft/ttyprogress","commit_stats":null,"previous_names":["mandelsoft/ttyprogress"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mandelsoft/ttyprogress","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandelsoft%2Fttyprogress","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandelsoft%2Fttyprogress/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandelsoft%2Fttyprogress/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandelsoft%2Fttyprogress/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mandelsoft","download_url":"https://codeload.github.com/mandelsoft/ttyprogress/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mandelsoft%2Fttyprogress/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32335353,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"online","status_checked_at":"2026-04-27T02:00:06.769Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["colors","console","golang","golang-library","indicators","progress","progressbar","terminal","tty"],"created_at":"2025-03-25T00:47:52.523Z","updated_at":"2026-04-27T12:05:18.548Z","avatar_url":"https://github.com/mandelsoft.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Progress Indicators for Terminal Output\n\nThis module provides various progress indicators for terminal\noutput and a framework to create new such indicators.\n\nIt is possible to combine multiple progress indicators in \na 'Context' object. It covers and manages trailing lines of a terminal\noutput and acts as group to add any number of indicators.\nAdditionally, indicators can be grouped again. Those groups are\nvisualized as indicators, also.\n\nThe following indicators are directly supported by the library:\n- [Simple Spinners](#spinner)\n- [Scrolling Text Spinners](#scrolling-text-spinners)\n- [Progress bars](#progress-bar)\n- [Progress bars for estimated remaining time](#progress-bar-for-estimated-total-time) \n- [Step lists](#progress-bar-for-steps)\n- [Step lists using indicators to visualize step progress](#nested-steps)\n- [Simple text output](#text-output)\n- [Text output with leading spinner](#text-output-with-spinner-title-line)\n- [Indicator Groups](#indicator-groups)\n\nThere are various presets with the visualization of bars and spinners.\nAdditionally, they can freely be configured.\n\n## Usage\n\nThe usage of the library based on the `Context` type. It is created\nusing the `For` function for an `io.Writer`, which should represent\na terminal output. The `Context` acts as `Container` for a sequence of\nindicators.\n\n```golang\nimport \"github.com/mandelsoft/ttyprogress\"\n\nfunc main() {\n\t\n    // setup output context\n    p := ttyprogress.For(os.Stdout)\n\t\n    // configure indicator (types)\n    bar := ttyprogress.NewBar().\n            SetPredefined(10).\n            SetTotal(500).\n            SetWidth(ttyprogress.PercentTerminalSize(30)).\n            PrependMessage(\"Downloading...\").\n            PrependElapsed().AppendCompleted().\n            AppendFunc(ttyprogress.Amount(units.Bytes(1024)))\n\n    // instantiate bar definition for context\n    // (similar to elem, _ := bar.Add(p) )\n    // and run some process updating the progress on the indicator element.\n    ttyprogress.RunWith(p, bar, func(elem ttyprogress.Bar) {\n        for i := 0; i \u003c= 20; i++ {\n            elem.Set(i * 5 * 5)\n            time.Sleep(time.Millisecond * 500)\n        }\n    })\n\n    // close context to indicate, that no new indicators are created anymore\n    p.Close()\n\t\n    // wait until all indicators are finished\t\n    p.Wait(context.Background())\n}\n```\n\nOnce a `Context` object is created for a writer, the writer MUST NOT be used\nuntil the progress is finished (for example by calling `Wait`).\nAs long a `Close` is not called, it is possible to add progress indicators.\n\nTo create an indicator a definition has to be created and configured by\ncalling configuration methods. Every definition can be instantiated\nmultiple time by adding it to a context (or group).\n\n`Close` on the context or group MUST be called prior to `Wait`. `Wait` waits until the context object is closed and all added indicators are closed and finished.\n\nProgress indicators are defined by progress indicator definition \nobjects. For every archetype there is one constructor function providing\na basic configuration.\n\n```golang\n\nbartype := ttyprogress.NewBar()\n```\n\nThis configuration can be refined by various chainable setters. \n\n```golang\nbartype.SetWidth(ttypprogress.PercentTerminalSize(50))\n```\n\nAny such configuration can be used as preconfigured type, which can be\ninstantiated with `New`. It creates a new configuration based on the given\none, which can furthermore be configured independently of the original configuration.\n\n```golang\nnewtype := ttyprogress.New(bartype)\n```\n\nTo save a configuration to a new immutable basic type, the function `TypeFor` can be used:\n\n```golang\nvar BarElapsed = ttyprogress.TypeFor(NewBar(5).SetWidth(50).AppendElapsed())\n```\n\nThis type is now independent of further modifications of the initial configuration and does not provide methods for further modifications.\nBut it can be used to create new preconfigured configurations with `New`, again. See the type example in [examples/progress/def](examples/progress/def/main.go).\n\n```golang\nnewtype := ttyprogress.New(BarElapsed)\n```\n\nAny configuration, regardless of its creation method,  can be used to add an arbitrary number of instances\nof such a progress indicator to a `Context` object.\n\n```golang\nnewtype.Add(p)\n```\n\nThe indicator is started by calling the `Start` method.\nSome indicator archetypes implicitly start the indicator when\nsome progress is indicated by an appropriate indicator method\nlike `Incr` on a `Bar` indicator.\n\nOnce all indicators are added the `Context` object can be closed.\nIt is not possible anymore o add more indicators to a closed group.\nWith calling the `Wait` method, the calling Go routine waits\nuntil the group and all included indicators are closed.\n\nIf a context is given `Wait` also returns if the context is cancelled.\n\n```golang\nctx, _ := context.WithTimeout(context.Background(), time.Minute)\np.Wait(ctx)\n```\n\n## Examples\n\nHere some examples for the usage of the various archetypes are shown.\n\n### Spinner\n\nThe `Spinner` progress indicator visualizes unlimited progress\nby cycling a sequence of fixed sized strings.\nThe look is completely\nconfigurable, but there are several preconfigured setting.\nThey can be found in `ttyprogress.SpinnerTypes`. It maps an integer\nto a spinner configuration.\n\n```golang\nspinner := ttyprogress.NewSpinner().\n\t         SetPredefined(1000).\n\t\t\t SetSpeed(1).\n\t\t\t SetColor(color.New(color.BgGreen, color.Underline)).\n\t\t\t PrependMessage(\"working on task ...\").\n\t\t\t AppendElapsed()\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/progress/spinner/demo.gif\" alt=\"Spinner Demo\" title=\"Spinner Demo\" /\u003e\n\u003c/p\u003e\n\nThis example can be found in [examples/progress/spinner/main.go](examples/progress/spinner/main.go).\n\n### Scrolling Text Spinners\n\nA scrolling text spinner is basically a spinner.\nBut it uses a scrolling text to indicate the progress.\n\n```golang\nspinner := ttyprogress.NewScrollingSpinner(\"doing some calculations\", 10).\n\t\tSetDone(\"calculations done\").\n\t\tAppendElapsed()\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/progress/scrollingspinner/demo.gif\" alt=\"Scrolling Text Spinner Demo\" title=\"Scrolling Text Spinner Demo\" /\u003e\n\u003c/p\u003e\n\nScrolling text can also be used as decorator for other progress indicators using the `specs.ScrollingText(text, length)` decorator.\n\n### Progress Bar\n\nThe `Bar` progress indicator visualizers the progress \nby a fixed length sequence of characters. The look is completely\nconfigurable, but there are several preconfigured setting.\nThey can be found in `ttyprogress.BarTypes`. It maps an integer\nto a bar configuration. For the brackets around the progress sequence\npredefined ones can be provided by the map `ttyprogress.BracketTypes`.\n\nThe progress is defined an integer value between 0 and a configurable total amount. It can be set absolutely by calling `Set` or incrementally ba calling `Incr`.\n\n```golang\nbar := ttyprogress.NewBar().\n\t\tSetPredefined(10).\n\t\tSetTotal(500).\n\t\tSetWidth(ttyprogress.PercentTerminalSize(30)).\n\t\tPrependMessage(\"Downloading...\").\n\t\tPrependElapsed().AppendCompleted().\n\t\tAppendFunc(ttyprogress.Amount(units.Bytes(1024))).\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/progress/bar/demo.gif\" alt=\"Progress Bar Demo\" title=\"Progress Bar Demo\" /\u003e\n\u003c/p\u003e\n\nThis example can be found in [examples/progress/bar/main.go](examples/progress/bar/main.go).\n\nThe `LineBar` progress indicator does not use an explicit\nprogress visualization, but the complete progress line\nby reversing the output according to the achieved\nprogress.\n\n```golang\nbar := ttyprogress.NewLineBar().\n\t\tSetTotal(500).\n\t\tPrependMessage(\"Downloading...\").\n\t\tPrependElapsed().AppendCompleted().\n\t\tSetDecoratorFormat(ttycolors.FmtGreen).\n\t\tAppendFunc(ttyprogress.Amount(units.Bytes(1024)))\n```\n\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/progress/linebar/demo.gif\" alt=\"Line Bar Demo\" title=\"Line Bar Demo\" /\u003e\n\u003c/p\u003e\n\nThis example can be found in [examples/progress/linebar/main.go](examples/progress/linebar/main.go).\n\n### Progress Bar for Steps\n\nIf there is a fixed set of sequential steps the progress can be indicated with a `Steps` indicator archetype.\nIt is a `Bar` progress indicator prepared to\nindicate the progress of a predefined sequence of steps.\n\n```golang\nbar := ttyprogress.NewSteps(\"downloading\", \"unpacking\", \"installing\", \"verifying\").\n\t\tPrependStep().\n\t\tPrependFunc(ttyprogress.Message(\"progressbar\"), 0).\n\t\tPrependElapsed().AppendCompleted()\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/progress/steps/demo.gif\" alt=\"Progress Bar Demo\" title=\"Progress Bar Demo\" /\u003e\n\u003c/p\u003e\n\nThis example can be found in [examples/progress/steps/main.go](examples/progress/steps/main.go).\n\n### Progress Bar for estimated Total Time.\n\nIf there is a time estimation for a progress the `Estimated` archetype can be used. It is a progress bar indicating the progress based on elapsed and total time. Instead of setting the progress, the estimated total time can be updated.\n\n```golang\nest := ttyprogress.NewEstimated(10 *time.Second).\n\t\tSetWidth(ttyprogress.ReserveTerminalSize(40)).\n\t\tSetPredefined(10).\n\t\tPrependFunc(ttyprogress.Message(\"Downloading...\")).\n\t\tPrependEstimated().\n\t\tAppendCompleted().\n\t\tAppendElapsed()\n```\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/progress/estimated/demo.gif\" alt=\"Estimated Total Time Demo\" title=\"Estimated Total Time Demo\" /\u003e\n\u003c/p\u003e\n\nThis example can be found in [examples/progress/estimated/main.go](examples/progress/estimated/main.go).\n\n\n### Text Output\n\nThe `Text` progress indicator visualizes an output steam.\nDuring the progress it shows a configured number of trailing lines\nby providing an `io.Writer`.\nAfter the indicator is closed the complete lines are \nwritten to the terminal, after all preceding indicators in the group\nand all outer groups are also closed.\n\nIt is intended to visualize multiple parallel output streams\nwithout mixing the output.\n\n```golang\ntext := ttyprogress.NewText().\n\t\tSetTitleLine(\"some output\").\n\t\tSetFollowUpGap(\"\u003e \").\n\t\tSetView(3).\n\t\tSetAuto()\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/progress/text/demo.gif\" alt=\"Progress Bar Demo\" title=\"Progress Bar Demo\" /\u003e\n\u003c/p\u003e\n\nThis example can be found in [examples/progress/text/main.go](examples/progress/text/main.go).\n\n### Text Output with Spinner Title Line\n\nThe `Text` progress indicator visualizes an output steam.\nDuring the progress it shows a configured number of trailing lines\nby providing an `io.Writer`, like a [Text](#text-output) indicator.\nBut instead an optional simple static title line a [Spinner](#spinner)\nis used.\n\n\n```golang\ntext := ttyprogress.NewTextSpinner().\n          SetPredefined(5).\n          SetView(3).\n          SetFollowUpGap(\"\u003e \").\n\t      PrependMessage(fmt.Sprintf(\"working on task %d...\", s+1)).\n          AppendElapsed()\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/progress/textspinner/demo.gif\" alt=\"Text Spinner Demo\" title=\"Text Spinner Demo\" /\u003e\n\u003c/p\u003e\n\nThis example can be found in [examples/progress/textspinner/main.go](examples/progress/textspinner/main.go).\n\n### Indicator Groups\n\nThe initial `Context` object holds a sequence of progress\nindicators. It is an initial indicator group. \nThere other `Group` indicators, which act as indicator and can\nhold an arbitrary sequence of indicators, again.\nThe group progress is indicated by another indicator configuration\nimplementing the adapter API (`GroupProgressElementDefinition`).\nSo farm this is supported by the `Bar` and `Spinner` archetype.\n\nAs long as the groups is not closed more indicators can be\nadded, even if there are additional indicators in an outer group.\nThe group indicator is finished, if the group is closed and\nall contained indicators are finished.\n\n```golang\n\nfunc text(g ttyprogress.Group) {\n\tfor t := 0; t \u003c 2; t++ {\n\t\ttext, _ := ttyprogress.NewTextSpinner().\n\t\t\tSetPredefined(70).\n\t\t\tSetView(3).\n\t\t\tSetSpeed(1).\n\t\t\tSetFollowUpGap(\"\u003e \").\n\t\t\tPrependFunc(ttyprogress.Message(fmt.Sprintf(\"working on task %d...\", t+1))).\n\t\t\tAppendElapsed().\n\t\t\tAdd(g)\n\n\t\tgo func() {\n\t\t\tm := 3 + rand.Int()%8\n\t\t\tfor i := 0; i \u003c= m; i++ {\n\t\t\t\tfmt.Fprintf(text, \"doing step %d of task %d\\n\", i+1, t+1)\n\t\t\t\ttime.Sleep(time.Millisecond * 100 * time.Duration(1+rand.Int()%20))\n\t\t\t}\n\t\t\ttext.Close()\n\t\t}()\n\t}\n}\n\nfunc main() {\n\tp := ttyprogress.For(os.Stdout)\n\n\t// use spinner to indicate group progress.\n\ts := ttyprogress.NewSpinner().\n\t\tSetSpeed(5).\n\t\tSetPredefined(86).\n\t\tPrependFunc(ttyprogress.Message(fmt.Sprintf(\"Grouped work\"))).\n\t\tAppendElapsed()\n\n\tg, _ := ttyprogress.NewGroup[ttyprogress.Spinner](s).\n\t\tSetGap(\"- \").\n\t\tSetFollowUpGap(\"  \").Add(p)\n\ttext(g)\n\tg.Close()\n\tp.Close()\n\tp.Wait(nil)\n}\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/progress/group/demo.gif\" alt=\"Group Demo\" title=\"Group Demo\" /\u003e\n\u003c/p\u003e\n\nThis example can be found in [examples/progress/group/main.go](examples/progress/group/main.go).\n\nA second group flavor `AnonymousGroup` acts as a sole indicator group\nwithout own indicator visualizing the group progress. \nIt can be used for a common handling of a sequence of other\nindicators. It offers hiding and the gap handling as shown above.\n\n```golang\ng := ttyprogress.NewAnonymousGroup().\n\t\tHideOnClose().\n\t\tSetGap(\"- \").\n\t\tSetFollowUpGap(\"  \")\n```\n\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/progress/anongroup/demo.gif\" alt=\"Anonymous Group Demo\" title=\"Anonymous Group Demo\" /\u003e\n\u003c/p\u003e\n\nThis example can be found in [examples/progress/anongroup/main.go](examples/progress/group/main.go).\n\n### Nested Steps\n\nIf the progress of steps for a `Steps` indicator should be visualized\na `NestedSteps` archetype can be used. It is a group controlled\nby a `Steps` indicator.\nHere, steps are defined by a name and an indicator configuration.\nThe indicators are added to the group sequentially after the previous\nstep is finished.\n\n```golang\n\nfunc Step(n string) ttyprogress.NestedStep {\n  return ttyprogress.NewNestedStep[ttyprogress.Bar](\n    n, ttyprogress.NewBar().SetTotal(100).\n         PrependElapsed().\n         AppendCompleted())\n}\n\nsteps := ttyprogress.NewNestedSteps(\n\t\tStep(\"downloading\"),\n\t\tStep(\"unpacking\"),\n\t\tStep(\"installing\"),\n\t\tStep(\"verifying\")).\n\t\tSetGap(\"  \").\n\t\tSetWidth(40).\n\t\tShowStepTitle(false).\n\t\tPrependFunc(ttyprogress.Message(\"progressbar\"), 0).\n\t\tPrependElapsed().\n\t\tAppendCompleted()\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/progress/nestedsteps/demo.gif\" alt=\"Nested Steps Demo\" title=\"Nested Steps Demo\" /\u003e\n\u003c/p\u003e\n\nThis example can be found in [examples/progress/nestedsteps/main.go](examples/progress/nestedsteps/main.go).\n\n### Bringing it all together\n\nUsing groups complex scenarios can be visualized as shown\nin the example  [examples/progress/complex/main.go](examples/progress/complex/main.go).\n\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/progress/complex/demo.gif\" alt=\"Complex Orchestration Demo\" title=\"Complex Orchestration Demo\" /\u003e\n\u003c/p\u003e\n\n### Variables\n\nProgress indicator decorations can be based on variables. This can be used\nfor example to visualize an execution status in addition to the progress.\nVariable values can be dynamically set on the progress elements.\n\n```golang\nfunc main() {\n\tp := ttyprogress.For(os.Stdout)\n\n\tbars := []int{1000, specs.SpinnerType}\n\n\tdef := ttyprogress.NewSpinner().\n\t\tSetSpeed(1).\n\t\tAppendElapsed().\n\t\tPrependMessage(\"working on\").\n\t\tPrependVariable(\"name\").\n\t\tPrependMessage(\"...\")\n\n\tfor i, b := range bars {\n\t\tbar, _ := def.SetPredefined(b).Add(p)\n\t\tbar.SetVariable(\"name\", fmt.Sprintf(\"task %d\", i+1))\n\t\tbar.Start()\n\t\tgo func() {\n\t\t\ttime.Sleep(time.Second * time.Duration(10+rand.Int()%20))\n\t\t\tbar.Close()\n\t\t}()\n\t}\n\n\tp.Close()\n\tp.Wait(nil)\n}\n```\n\nWith `AppendVariable` or `PrependVariable` variable values can be\nadded to the progress line. The state passed to the decorators can access the\nvariable values, which enabled to create more complex decorators using\nvariable values of an arbitrary structure.\nWhile feeding the progress the variables can be modified on the progress\nelement with `SetVariable`.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/progress/variables/demo.gif\" alt=\"Using Variables\" title=\"Using Variables\" /\u003e\n\u003c/p\u003e\n\nThis example can be found in [examples/progress/variables/main.go](examples/progress/variables/main.go).\n\n### Colors\n\nThis library works together with the terminal color library [github.com/mandelsoft/ttycolors](https://github.com/mandelsoft/ttycolors).\n\nThe `Context` object is based on a `ttycolors.TTYContext` to control\nthe output formatting  colorized in terms of [ANSI Escape Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors).\nBy default, it is initialized by checking the writer for writing to a terminal.\nBut it can be configured, explicitly, by using the `EnableColors` method.\n\n\nFor example\n\n```golang\np := ttyprogress.New(os.StdOut).EnableColors(false)\n```\n\ndisables the output formatting, even if the standard output is directed to a terminal.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"examples/progress/colors/demo.gif\" alt=\"Colorized Progress Bar Demo\" title=\"Colorized Progress Bar Demo\" /\u003e\n\u003c/p\u003e\n\nElements of the main progress line can be colorized separately.\n\nThis example can be found in [examples/progress/colors/main.go](examples/progress/colors/main.go).\n\nBe careful using colors in text views. This only works, if a line \ncontains a complete output format ANSI sequences. Text based indicators\nsupport the `SetViewFormat` method to configure the output format for\nthe text view to set the format for the complete text independently of the\n`Write` operations.\n\n\n## Acknowledgment of Prior Work\n\nThis library is inspired by libraries provided by [Greg Osuri](https://github.com/gosuri): [github.com/gosuri/uilive](https://github.com/gosuri/uilive) and [github.com/gosuri/uiprogress](https://github.com/gosuri/uiprogress) ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmandelsoft%2Fttyprogress","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmandelsoft%2Fttyprogress","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmandelsoft%2Fttyprogress/lists"}