kwbar


Namekwbar JSON
Version 1.0.0 PyPI version JSON
download
home_page
SummaryPrint kwargs as a bar chart.
upload_time2023-12-22 11:44:01
maintainer
docs_urlNone
authorJohn Pocock
requires_python>=3.8,<4.0
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # β–ˆ kwbar – Print Keywords as a Bar Chart

[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/charliermarsh/ruff)
[![GitMoji](https://img.shields.io/badge/gitmoji-%20😜%20😍-FFDD67.svg)](https://gitmoji.dev)
[![image](https://img.shields.io/pypi/v/kwbar.svg)](https://pypi.python.org/pypi/kwbar)
[![image](https://img.shields.io/pypi/l/kwbar.svg)](https://pypi.python.org/pypi/kwbar)
[![image](https://img.shields.io/pypi/pyversions/kwbar.svg)](https://pypi.python.org/pypi/kwbar)
[![Continuous Integration](https://github.com/John-P/kwbar/actions/workflows/ci.yml/badge.svg)](https://github.com/John-P/kwbar/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/John-P/kwbar/graph/badge.svg?token=AYTCMEYTCU)](https://codecov.io/gh/John-P/kwbar)

Easily create a bar chart with `kwbar`; pass keyword arguments that can be converted to float.

![kwbar](https://github.com/John-P/kwbar/raw/main/images/kwbar-solarized-dark.svg)

I made this for fun, but then I thought other people might actually find it useful.

## Features

`kwbar` several useful features:

- Plots bars showing the relative magnitide (absolute value) of kwargs.
- Prints the values of the passed keyword arguments in scientific notation.
- Pure Python and zero dependencies.
- Minimal implementation (<100 lines total) which can be audited in a few minutes.
- Prints the names of the passed keyword arguments.
- Plots any object that can be converted to float (SupportsFloat).
- Customizable width, the entire terminal width is used by default.
- Customizable significant figures, 3 by default.
- Shows value labels inside bars, making the output width predictable. If the bars are too small, the value labels appear outside of them.
- Handles inf and NaN values.
- Negative values are [(ANSI) colored](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) red and can be customized.
- Respects the [`NO_COLOR` environment variable](https://no-color.org).
- Has an ASCII mode, enabled on import when stdout is not TTY.
- Warns on stderr (can be disabled) if the output will have to overrun the configured width. Overflow can generally be avoided by configuting [options](#options) such as `BEFORE=True`.
- Fixed output width. This can be done by either:
    1. Setting `BEFORE = True`, or
    2. setting `TRUNCATE` and `WIDTH` to satisfy: `WIDTH` - `TRUNCATE` - `SF` - 17 >= 0.

## Options

`kwbar` supports the following options, which are set by modifying module variables:

```python
import kwbar

kwbar.WIDTH = -1  # Set the output width, -1 = use the terminal width.
kwbar.SF = 2  # The number of sig figs to show.
kwbar.SHOW_VAL = True  # Show values inside the bars
kwbar.TRUNCATE = 0.25  # Truncate long keys (<=1 = % of WIDTH, >1 = columns).
kwbar.BAR_CHARS = " β–β–Žβ–β–Œβ–‹β–Šβ–‰β–ˆ"  # Characters to use for the bars.
kwbar.POS = ""  # ANSI escape code for positive values.
kwbar.NEG = "\x1b[31m"  # ANSI escape code for negative values.
kwbar.WARN = True  # Show a warning if the output will overrun the configured width.
kwbar.PAD = " "  # Padding characters shown before finite and non-finite values.
kwbar.BEFORE = False  # Show the value labels before the bar instead of inside.
```

## Convenience Functions

There are also a couple of functions to set multiple options at once:

### ASCII Mode

Sets `BAR_CHARS` and `PAD` to ASCII characters. Also disables all ANSI escape codes and sets `BEFORE` true.

```python
import kwbar
kwbar.WIDTH = 50
kwbar.ascii()
kwbar.kwbar(one=1, two=2, three=3, four=4)
```

```plain
  one +1.00e+00 XXXXXXXX
  two +2.00e+00 XXXXXXXXXXXXXXXXX
three +3.00e+00 XXXXXXXXXXXXXXXXXXXXXXXXX
 four +4.00e+00 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

### Hotdog Mode

```python
import kwbar
kwbar.WIDTH = 33
kwbar.hotdog()
kwbar.kwbar(one=1, two=2, three=3, four=4)
```

```plain
  one 🌭🌭🌭🌭🌭🌭¾
  two 🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭½
three 🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭¼
 four 🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭
```

## How do I...?

### Reset All Options

```python
import kwbar

kwbar.ascii()

# Reset to defaults.
import importlib

importlib.reload(kwbar)
```

### Use Keys That Are Not Valid Python Keywords

```python
import kwbar

kwbar.ascii()
kwbar.kwbar(**{"one": 1, "-2": -2, "pi": 3.14})
```

```plain
one +1.00e+00 XXXXXX
 -2 -2.00e+00 XXXXXXXXXXXX
 pi +3.14e+00 XXXXXXXXXXXXXXXXXXX
```

### Print Dogs Instead of Hotdogs

```python
import kwbar
kwbar.hotdog()
kwbar.BAR_CHARS = kwbar.BAR_CHARS[:-1] + "🐢" # Replace the last character.
kwbar.kwbar(one=1, two=2, pi=3.14)
```

```plain
one 🐢🐢🐢🐢🐢🐢🐢🐢🐢¼
two 🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢½
 pi 🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢🐢
```

## Themes

Just some ideas for how you could customize the output.

### Lines

```python
import kwbar
kwbar.hotdog()
kwbar.BAR_CHARS = "╸━"
```

![Red and blue lines in Solarized Dark colorscheme](https://github.com/John-P/kwbar/raw/main/images/lines-solarized-dark.svg)

### Blue Red Lines

```python
import kwbar
kwbar.hotdog()
kwbar.BAR_CHARS = "╸━"
kwbar.POS = "\x1b[34m"
kwbar.NEG = "\x1b[31m"
```

![Red and blue lines in Solarized Dark colorscheme](https://github.com/John-P/kwbar/raw/main/images/rb-lines-solarized-dark.svg)

### Slices

```python
import kwbar
kwbar.hotdog()
kwbar.BAR_CHARS = "◔◑◕●"
```

![Slices in Solarized Dark colorscheme](https://github.com/John-P/kwbar/raw/main/images/slices-solarized-dark.svg)

### Quater Tally

```python
import kwbar
kwbar.hotdog()
kwbar.BAR_CHARS = " ΒΌΒ½ΒΎ1"
```

![Quater tally in Solarized Dark colorscheme](https://github.com/John-P/kwbar/raw/main/images/quater-tally-solarized-dark.svg)

### Eighths

```python
kwbar.hotdog()
kwbar.BAR_CHARS = " β…›ΒΌβ…œΒ½β…ΒΎβ…ž1"
```

![Eighths in Solarized Dark colorscheme](https://github.com/John-P/kwbar/raw/main/images/eighths-solarized-dark.svg)

### Hatching

```python
kwbar.hotdog()
kwbar.BAR_CHARS = "πŸ₯šπŸ£πŸ₯"
```

![Hatching in Solarized Dark colorscheme](https://github.com/John-P/kwbar/raw/main/images/hatching-solarized-dark.svg)


## FAQs

These are questions that I frequently asked myself while making this.

### Why did you make this?
For fun!

### Why did you format the script to fill 80 characters on a line?
Because I could and it made me happy.

### Why did you use module variables for configuration?
Because it kept the implementation simple/minimal.
This also means that if you import kwbar in multiple places within a script,
it will have a consistent style and does not need to be configured multiple times.

### How do I have multiple kwbar copies with different configurations?
The configuration for kwbar affects all calls to `kwbar.kwbar`, becuase it is a static
function using module variables for configuration.
If you *really* want to do this, you can, but it feels like a hideous hack:

```python
import sys
import importlib

SPEC_KWBAR = importlib.util.find_spec('kwbar')
kwbar2 = importlib.util.module_from_spec(SPEC_KWBAR)
SPEC_KWBAR.loader.exec_module(kwbar2)
sys.modules['kwbar2'] = kwbar2
```

Now you have another kwbar called kwbar2 with a completely seperate configuration.

```python
>>> kwbar.WIDTH = 40
>>> kwbar2.WIDTH = 50
>>> print(kwbar.WIDTH)
40
>>> print(kwbar2.WIDTH)
50
```

## Why didn't you just make the first argument a dictionary and use kwargs for configuration?
Becuase that was less fun that using only kwargs.



            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "kwbar",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8,<4.0",
    "maintainer_email": "",
    "keywords": "",
    "author": "John Pocock",
    "author_email": "pypi@pocock.io",
    "download_url": "https://files.pythonhosted.org/packages/27/4e/de125117aacce5ee6f65ab1cfa58fdeed301bb8a4f9d233d92af6be9f6f1/kwbar-1.0.0.tar.gz",
    "platform": null,
    "description": "# \u2588 kwbar \u2013 Print Keywords as a Bar Chart\n\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/charliermarsh/ruff)\n[![GitMoji](https://img.shields.io/badge/gitmoji-%20\ud83d\ude1c%20\ud83d\ude0d-FFDD67.svg)](https://gitmoji.dev)\n[![image](https://img.shields.io/pypi/v/kwbar.svg)](https://pypi.python.org/pypi/kwbar)\n[![image](https://img.shields.io/pypi/l/kwbar.svg)](https://pypi.python.org/pypi/kwbar)\n[![image](https://img.shields.io/pypi/pyversions/kwbar.svg)](https://pypi.python.org/pypi/kwbar)\n[![Continuous Integration](https://github.com/John-P/kwbar/actions/workflows/ci.yml/badge.svg)](https://github.com/John-P/kwbar/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/John-P/kwbar/graph/badge.svg?token=AYTCMEYTCU)](https://codecov.io/gh/John-P/kwbar)\n\nEasily create a bar chart with `kwbar`; pass keyword arguments that can be converted to float.\n\n![kwbar](https://github.com/John-P/kwbar/raw/main/images/kwbar-solarized-dark.svg)\n\nI made this for fun, but then I thought other people might actually find it useful.\n\n## Features\n\n`kwbar` several useful features:\n\n- Plots bars showing the relative magnitide (absolute value) of kwargs.\n- Prints the values of the passed keyword arguments in scientific notation.\n- Pure Python and zero dependencies.\n- Minimal implementation (<100 lines total) which can be audited in a few minutes.\n- Prints the names of the passed keyword arguments.\n- Plots any object that can be converted to float (SupportsFloat).\n- Customizable width, the entire terminal width is used by default.\n- Customizable significant figures, 3 by default.\n- Shows value labels inside bars, making the output width predictable. If the bars are too small, the value labels appear outside of them.\n- Handles inf and NaN values.\n- Negative values are [(ANSI) colored](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) red and can be customized.\n- Respects the [`NO_COLOR` environment variable](https://no-color.org).\n- Has an ASCII mode, enabled on import when stdout is not TTY.\n- Warns on stderr (can be disabled) if the output will have to overrun the configured width. Overflow can generally be avoided by configuting [options](#options) such as `BEFORE=True`.\n- Fixed output width. This can be done by either:\n    1. Setting `BEFORE = True`, or\n    2. setting `TRUNCATE` and `WIDTH` to satisfy: `WIDTH` - `TRUNCATE` - `SF` - 17 >= 0.\n\n## Options\n\n`kwbar` supports the following options, which are set by modifying module variables:\n\n```python\nimport kwbar\n\nkwbar.WIDTH = -1  # Set the output width, -1 = use the terminal width.\nkwbar.SF = 2  # The number of sig figs to show.\nkwbar.SHOW_VAL = True  # Show values inside the bars\nkwbar.TRUNCATE = 0.25  # Truncate long keys (<=1 = % of WIDTH, >1 = columns).\nkwbar.BAR_CHARS = \" \u258f\u258e\u258d\u258c\u258b\u258a\u2589\u2588\"  # Characters to use for the bars.\nkwbar.POS = \"\"  # ANSI escape code for positive values.\nkwbar.NEG = \"\\x1b[31m\"  # ANSI escape code for negative values.\nkwbar.WARN = True  # Show a warning if the output will overrun the configured width.\nkwbar.PAD = \" \"  # Padding characters shown before finite and non-finite values.\nkwbar.BEFORE = False  # Show the value labels before the bar instead of inside.\n```\n\n## Convenience Functions\n\nThere are also a couple of functions to set multiple options at once:\n\n### ASCII Mode\n\nSets `BAR_CHARS` and `PAD` to ASCII characters. Also disables all ANSI escape codes and sets `BEFORE` true.\n\n```python\nimport kwbar\nkwbar.WIDTH = 50\nkwbar.ascii()\nkwbar.kwbar(one=1, two=2, three=3, four=4)\n```\n\n```plain\n  one +1.00e+00 XXXXXXXX\n  two +2.00e+00 XXXXXXXXXXXXXXXXX\nthree +3.00e+00 XXXXXXXXXXXXXXXXXXXXXXXXX\n four +4.00e+00 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n```\n\n### Hotdog Mode\n\n```python\nimport kwbar\nkwbar.WIDTH = 33\nkwbar.hotdog()\nkwbar.kwbar(one=1, two=2, three=3, four=4)\n```\n\n```plain\n  one \ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\u00be\n  two \ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\u00bd\nthree \ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\u00bc\n four \ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\ud83c\udf2d\n```\n\n## How do I...?\n\n### Reset All Options\n\n```python\nimport kwbar\n\nkwbar.ascii()\n\n# Reset to defaults.\nimport importlib\n\nimportlib.reload(kwbar)\n```\n\n### Use Keys That Are Not Valid Python Keywords\n\n```python\nimport kwbar\n\nkwbar.ascii()\nkwbar.kwbar(**{\"one\": 1, \"-2\": -2, \"pi\": 3.14})\n```\n\n```plain\none +1.00e+00 XXXXXX\n -2 -2.00e+00 XXXXXXXXXXXX\n pi +3.14e+00 XXXXXXXXXXXXXXXXXXX\n```\n\n### Print Dogs Instead of Hotdogs\n\n```python\nimport kwbar\nkwbar.hotdog()\nkwbar.BAR_CHARS = kwbar.BAR_CHARS[:-1] + \"\ud83d\udc36\" # Replace the last character.\nkwbar.kwbar(one=1, two=2, pi=3.14)\n```\n\n```plain\none \ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\u00bc\ntwo \ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\u00bd\n pi \ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\ud83d\udc36\n```\n\n## Themes\n\nJust some ideas for how you could customize the output.\n\n### Lines\n\n```python\nimport kwbar\nkwbar.hotdog()\nkwbar.BAR_CHARS = \"\u2578\u2501\"\n```\n\n![Red and blue lines in Solarized Dark colorscheme](https://github.com/John-P/kwbar/raw/main/images/lines-solarized-dark.svg)\n\n### Blue Red Lines\n\n```python\nimport kwbar\nkwbar.hotdog()\nkwbar.BAR_CHARS = \"\u2578\u2501\"\nkwbar.POS = \"\\x1b[34m\"\nkwbar.NEG = \"\\x1b[31m\"\n```\n\n![Red and blue lines in Solarized Dark colorscheme](https://github.com/John-P/kwbar/raw/main/images/rb-lines-solarized-dark.svg)\n\n### Slices\n\n```python\nimport kwbar\nkwbar.hotdog()\nkwbar.BAR_CHARS = \"\u25d4\u25d1\u25d5\u25cf\"\n```\n\n![Slices in Solarized Dark colorscheme](https://github.com/John-P/kwbar/raw/main/images/slices-solarized-dark.svg)\n\n### Quater Tally\n\n```python\nimport kwbar\nkwbar.hotdog()\nkwbar.BAR_CHARS = \" \u00bc\u00bd\u00be1\"\n```\n\n![Quater tally in Solarized Dark colorscheme](https://github.com/John-P/kwbar/raw/main/images/quater-tally-solarized-dark.svg)\n\n### Eighths\n\n```python\nkwbar.hotdog()\nkwbar.BAR_CHARS = \" \u215b\u00bc\u215c\u00bd\u215d\u00be\u215e1\"\n```\n\n![Eighths in Solarized Dark colorscheme](https://github.com/John-P/kwbar/raw/main/images/eighths-solarized-dark.svg)\n\n### Hatching\n\n```python\nkwbar.hotdog()\nkwbar.BAR_CHARS = \"\ud83e\udd5a\ud83d\udc23\ud83d\udc25\"\n```\n\n![Hatching in Solarized Dark colorscheme](https://github.com/John-P/kwbar/raw/main/images/hatching-solarized-dark.svg)\n\n\n## FAQs\n\nThese are questions that I frequently asked myself while making this.\n\n### Why did you make this?\nFor fun!\n\n### Why did you format the script to fill 80 characters on a line?\nBecause I could and it made me happy.\n\n### Why did you use module variables for configuration?\nBecause it kept the implementation simple/minimal.\nThis also means that if you import kwbar in multiple places within a script,\nit will have a consistent style and does not need to be configured multiple times.\n\n### How do I have multiple kwbar copies with different configurations?\nThe configuration for kwbar affects all calls to `kwbar.kwbar`, becuase it is a static\nfunction using module variables for configuration.\nIf you *really* want to do this, you can, but it feels like a hideous hack:\n\n```python\nimport sys\nimport importlib\n\nSPEC_KWBAR = importlib.util.find_spec('kwbar')\nkwbar2 = importlib.util.module_from_spec(SPEC_KWBAR)\nSPEC_KWBAR.loader.exec_module(kwbar2)\nsys.modules['kwbar2'] = kwbar2\n```\n\nNow you have another kwbar called kwbar2 with a completely seperate configuration.\n\n```python\n>>> kwbar.WIDTH = 40\n>>> kwbar2.WIDTH = 50\n>>> print(kwbar.WIDTH)\n40\n>>> print(kwbar2.WIDTH)\n50\n```\n\n## Why didn't you just make the first argument a dictionary and use kwargs for configuration?\nBecuase that was less fun that using only kwargs.\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Print kwargs as a bar chart.",
    "version": "1.0.0",
    "project_urls": null,
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6857485bb9cf56e9cdaa2f09c664f54809294bfeffa9c2ee3736c6582761e25c",
                "md5": "19275b07209652a61570490438a00630",
                "sha256": "bdcedaa1cb9dca06dc2e5fbe94de0c24fdf2ac22b44c2b18370e357094039281"
            },
            "downloads": -1,
            "filename": "kwbar-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "19275b07209652a61570490438a00630",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8,<4.0",
            "size": 7105,
            "upload_time": "2023-12-22T11:43:59",
            "upload_time_iso_8601": "2023-12-22T11:43:59.401317Z",
            "url": "https://files.pythonhosted.org/packages/68/57/485bb9cf56e9cdaa2f09c664f54809294bfeffa9c2ee3736c6582761e25c/kwbar-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "274ede125117aacce5ee6f65ab1cfa58fdeed301bb8a4f9d233d92af6be9f6f1",
                "md5": "47a91153db190dd6745c49ed92d410f9",
                "sha256": "f5443f9767fb4779831caf937e287b3817cda5ff672b493793daf54459dc1cc1"
            },
            "downloads": -1,
            "filename": "kwbar-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "47a91153db190dd6745c49ed92d410f9",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8,<4.0",
            "size": 6514,
            "upload_time": "2023-12-22T11:44:01",
            "upload_time_iso_8601": "2023-12-22T11:44:01.302219Z",
            "url": "https://files.pythonhosted.org/packages/27/4e/de125117aacce5ee6f65ab1cfa58fdeed301bb8a4f9d233d92af6be9f6f1/kwbar-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-12-22 11:44:01",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "kwbar"
}
        
Elapsed time: 0.40612s