{"id":13477744,"url":"https://github.com/orhun/daktilo","last_synced_at":"2025-05-14T03:11:52.794Z","repository":{"id":196262422,"uuid":"695473735","full_name":"orhun/daktilo","owner":"orhun","description":"Turn your keyboard into a typewriter! 📇","archived":false,"fork":false,"pushed_at":"2025-05-06T20:53:38.000Z","size":4722,"stargazers_count":1119,"open_issues_count":16,"forks_count":23,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-05-06T21:38:58.840Z","etag":null,"topics":["daktilo","hacktoberfest","keyboard","rust","sound","typewriter","typewriter-animation","typewriter-effect","typewriter-effects","typewriter-mode","typewriter-sounds"],"latest_commit_sha":null,"homepage":"https://daktilo.cli.rs/","language":"Rust","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/orhun.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE-APACHE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"orhun","patreon":"orhunp","buy_me_a_coffee":"orhun"}},"created_at":"2023-09-23T09:44:30.000Z","updated_at":"2025-05-06T20:53:35.000Z","dependencies_parsed_at":"2024-11-07T22:18:13.412Z","dependency_job_id":"79cb8022-5e90-4c1b-a38b-1b3f77eda56c","html_url":"https://github.com/orhun/daktilo","commit_stats":{"total_commits":356,"total_committers":10,"mean_commits":35.6,"dds":0.4157303370786517,"last_synced_commit":"637dfda2f068abbb43f3a16fc264c40f027573d4"},"previous_names":["orhun/typewriter"],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orhun%2Fdaktilo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orhun%2Fdaktilo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orhun%2Fdaktilo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orhun%2Fdaktilo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/orhun","download_url":"https://codeload.github.com/orhun/daktilo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252776259,"owners_count":21802459,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["daktilo","hacktoberfest","keyboard","rust","sound","typewriter","typewriter-animation","typewriter-effect","typewriter-effects","typewriter-mode","typewriter-sounds"],"created_at":"2024-07-31T16:01:47.007Z","updated_at":"2025-05-14T03:11:47.758Z","avatar_url":"https://github.com/orhun.png","language":"Rust","funding_links":["https://github.com/sponsors/orhun","https://patreon.com/orhunp","https://buymeacoffee.com/orhun","https://patreon.com/join/orhunp","https://www.patreon.com/join/orhunp)!"],"categories":["Rust","\u003ca name=\"funny\"\u003e\u003c/a\u003eFunny tools"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n  \u003ca href=\"https://github.com/orhun/daktilo\"\u003e\n    \u003cimg src=\"assets/daktilo-logo.png\" width=\"400\"\u003e\n  \u003c/a\u003e\n\n\u003ch4\u003eTurn your keyboard into a typewriter! 📇\u003c/h4\u003e\n\n\u003ca href=\"https://github.com/orhun/daktilo/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/orhun/daktilo?style=flat\u0026amp;labelColor=1D272B\u0026amp;color=819188\u0026amp;logo=GitHub\u0026amp;logoColor=white\" alt=\"GitHub Release\"\u003e\u003c/a\u003e\n\u003ca href=\"https://crates.io/crates/daktilo/\"\u003e\u003cimg src=\"https://img.shields.io/crates/v/daktilo?style=flat\u0026amp;labelColor=1D272B\u0026amp;color=819188\u0026amp;logo=Rust\u0026amp;logoColor=white\" alt=\"Crate Release\"\u003e\u003c/a\u003e\n\u003ca href=\"https://codecov.io/gh/orhun/daktilo\"\u003e\u003cimg src=\"https://img.shields.io/codecov/c/gh/orhun/daktilo?style=flat\u0026amp;labelColor=1D272B\u0026amp;color=819188\u0026amp;logo=Codecov\u0026amp;logoColor=white\" alt=\"Coverage\"\u003e\u003c/a\u003e\n\u003cbr\u003e\n\u003ca href=\"https://github.com/orhun/daktilo/actions?query=workflow%3A%22Continuous+Integration%22\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/orhun/daktilo/ci.yml?branch=main\u0026amp;style=flat\u0026amp;labelColor=1D272B\u0026amp;color=819188\u0026amp;logo=GitHub%20Actions\u0026amp;logoColor=white\" alt=\"Continuous Integration\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/orhun/daktilo/actions?query=workflow%3A%22Release%22\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/orhun/daktilo/release.yml?style=flat\u0026amp;labelColor=1D272B\u0026amp;color=819188\u0026amp;logo=GitHub%20Actions\u0026amp;logoColor=white\u0026amp;label=release\" alt=\"Continuous Deployment\"\u003e\u003c/a\u003e\n\u003ca href=\"https://docs.rs/daktilo/\"\u003e\u003cimg src=\"https://img.shields.io/docsrs/daktilo?style=flat\u0026amp;labelColor=1D272B\u0026amp;color=819188\u0026amp;logo=Rust\u0026amp;logoColor=white\" alt=\"Documentation\"\u003e\u003c/a\u003e\n\n\u003cvideo src=\"https://github.com/orhun/daktilo/assets/24392180/b2b0d9c5-422f-401d-a25d-e6bc797d8976\" alt=\"daktilo demo\"\u003e\n\n\u003c/div\u003e\n\n**daktilo** (\"typewriter\" in Turkish, pronounced _\"duck-til-oh\"_, derived from the Ancient Greek word [δάκτυλος](https://lsj.gr/wiki/%CE%B4%CE%AC%CE%BA%CF%84%CF%85%CE%BB%CE%BF%CF%82) for \"finger\") is a small command-line program that plays typewriter sounds every time you press a key. It also offers the flexibility to customize keypress sounds to your liking. You can use the built-in sound presets to create an enjoyable typing experience, whether you're crafting emails or up to some prank on your boss.\n\n✨ Inspiration: [\"Taking notes in class with my typewriter\"](https://www.youtube.com/watch?v=Bs5TEuZPQl8)\n\nNow you can recreate this moment without the actual need for a physical typewriter!\n\n\u003cdetails\u003e\n  \u003csummary\u003eTable of Contents\u003c/summary\u003e\n\n\u003c!-- vim-markdown-toc GFM --\u003e\n\n- [Getting Started](#getting-started)\n- [Supported Platforms](#supported-platforms)\n- [Installation](#installation)\n  - [Cargo](#cargo)\n  - [Arch Linux](#arch-linux)\n  - [Alpine Linux](#alpine-linux)\n  - [MacPorts](#macports)\n  - [Binary releases](#binary-releases)\n  - [Build from source](#build-from-source)\n- [Usage](#usage)\n- [Configuration](#configuration)\n  - [Adding custom presets](#adding-custom-presets)\n  - [Sound Variation](#sound-variation)\n- [Similar Projects](#similar-projects)\n- [MacOS permissions](#macos-permissions)\n- [Acknowledgements](#acknowledgements)\n- [Donations](#donations)\n- [Contributing](#contributing)\n- [License](#license)\n- [Copyright](#copyright)\n\n\u003c!-- vim-markdown-toc --\u003e\n\n\u003c/details\u003e\n\n## Getting Started\n\nSimply run `daktilo` for the classic typewriter effect.\n\nThere are also different presets available:\n\n| Preset Name | Description                                     |\n| ----------- | ----------------------------------------------- |\n| `default`   | the classic typewriter effect                   |\n| `basic`     | an alternative and more basic typewriter effect |\n| `musicbox`  | plays random notes like a music box             |\n| `ducktilo`  | quack quack 🦆                                  |\n| `drumkit`   | dum, tss, cha! 🥁                               |\n| `spark`     | high voltage high current typing experience ⚡  |\n\nTo list the presets:\n\n```sh\ndaktilo --list-presets\n```\n\nTo use a preset:\n\n```sh\ndaktilo --preset musicbox\n```\n\nYou can also use multiple presets at the same time:\n\n```sh\n# orchestra\ndaktilo -p default -p musicbox -p drumkit\n```\n\nTo use a different output device:\n\n```sh\ndaktilo --device pipewire\n```\n\nAlso, you can use `--list-devices` to list the available output devices.\n\nTo variate the sounds and have a more realistic typewriter experience:\n\n```sh\ndaktilo --variate-tempo 0.9,0.4 --variate-volume 0.1,0.5\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eSpoiler warning\u003c/summary\u003e\n\nThere are easter eggs. If that is something you do not like you can disable them either via the config file option `no_surprises = true` or using the command-line flag:\n\n```sh\ndaktilo --no-surprises\n```\n\n\u003c/details\u003e\n\n## Supported Platforms\n\n- [x] Linux\n  - [x] X11\n  - [ ] Wayland[\\*](https://github.com/Narsil/rdev#linux)\n- [x] Windows\n- [x] MacOS\n\n## Installation\n\n[![Packaging status](https://repology.org/badge/vertical-allrepos/daktilo.svg)](https://repology.org/project/daktilo/versions)\n\n### Cargo\n\n**daktilo** can be installed from [crates.io](https://crates.io/crates/daktilo) using [`cargo`](https://doc.rust-lang.org/cargo/) if [Rust](https://www.rust-lang.org/tools/install) is installed.\n\n```sh\ncargo install daktilo\n```\n\nThe minimum supported Rust version is `1.70.0`.\n\nOn Linux, the following packages should be installed:\n\n- Arch Linux: `alsa-lib libxtst libxi`\n- Alpine Linux: `alsa-lib-dev libxi-dev libxtst-dev`\n- Debian/Ubuntu: `libasound2-dev libxi-dev libxtst-dev`\n\n### Arch Linux\n\n**daktilo** can be installed from the [official repositories](https://archlinux.org/packages/extra/x86_64/daktilo/) using [pacman](https://wiki.archlinux.org/title/Pacman):\n\n```sh\npacman -S daktilo\n```\n\n### Alpine Linux\n\n**daktilo** is available for [Alpine Edge](https://pkgs.alpinelinux.org/packages?name=daktilo\u0026branch=edge). It can be installed via [apk](https://wiki.alpinelinux.org/wiki/Alpine_Package_Keeper) after enabling the [testing repository](https://wiki.alpinelinux.org/wiki/Repositories).\n\n```sh\napk add daktilo\n```\n\n### MacPorts\n\nOn macOS, **daktilo** can be installed via [MacPorts](https://www.macports.org/):\n\n```sh\nsudo port install daktilo\n```\n\nMore info [here](https://ports.macports.org/port/daktilo/).\n\n### Binary releases\n\nSee the available binaries for different targets from the [releases page](https://github.com/orhun/daktilo/releases).\n\n### Build from source\n\n1. Clone the repository.\n\n```sh\ngit clone https://github.com/orhun/daktilo \u0026\u0026 cd daktilo/\n```\n\n2. Build.\n\n```sh\nCARGO_TARGET_DIR=target cargo build --release\n```\n\nBinary will be located at `target/release/daktilo`.\n\n## Usage\n\n```sh\ndaktilo [OPTIONS]\n```\n\n**Options**:\n\n```sh\n-v, --verbose                                    Enables verbose logging [env: VERBOSE=]\n-p, --preset [\u003cPRESET\u003e...]                       Sets the name of the sound preset to use [env: PRESET=]\n-l, --list-presets                               Lists the available presets\n    --list-devices                               Lists the available output devices\n-d, --device \u003cDEVICE\u003e                            Sets the device for playback [env: DAKTILO_DEVICE=]\n-c, --config \u003cPATH\u003e                              Sets the configuration file [env: DAKTILO_CONFIG=]\n-i, --init                                       Writes the default configuration file\n    --variate-volume \u003cPERCENT_UP[,PERCENT_DOWN]\u003e Variate volume +/- in percent [env: DAKTILO_VOLUME=]\n    --variate-tempo \u003cPERCENT_UP[,PERCENT_DOWN]\u003e  Variate tempo +/- in percent [env: DAKTILO_TEMPO=]\n-h, --help                                       Print help (see more with '--help')\n-V, --version                                    Print version\n```\n\n## Configuration\n\n**daktilo** can be configured with a configuration file using the [TOML](https://en.wikipedia.org/wiki/TOML) format.\n\nThe path of the configuration file can be specified via `--config` argument or `DAKTILO_CONFIG` environment variable.\n\nIt can also be placed in one of the following global locations:\n\n- `\u003cconfig_dir\u003e` `/` `daktilo.toml`\n- `\u003cconfig_dir\u003e` `/` `daktilo/daktilo.toml`\n- `\u003cconfig_dir\u003e` `/` `daktilo/config`\n\n`\u003cconfig_dir\u003e` depends on the platform as shown in the following table:\n\n| Platform | Value                                 | Example                                  |\n| -------- | ------------------------------------- | ---------------------------------------- |\n| Linux    | `$XDG_CONFIG_HOME` or `$HOME`/.config | /home/orhun/.config                      |\n| macOS    | `$HOME`/Library/Application Support   | /Users/Orhun/Library/Application Support |\n| Windows  | `{FOLDERID_RoamingAppData}`           | C:\\Users\\Orhun\\AppData\\Roaming           |\n\nSee [daktilo.toml](config/daktilo.toml) for the default configuration options.\n\nYou can also create the default configuration file in the current directory with `--init` flag:\n\n```sh\ndaktilo --init\n```\n\n### Adding custom presets\n\nThe configuration file consists of an array of `sound_preset` entries.\n\nTo define an array in TOML, you can create different sections as follows:\n\n```toml\n[[sound_preset]]\nname = \"custom\"\nkey_config = []\n\n[[sound_preset]]\nname = \"another_custom\"\nkey_config = []\ndisabled_keys = []\nvariation = { volume: [0.1, 0.1], tempo: [0.05, 0.05] }\n```\n\nAs shown above, `sound_preset` consists of 2 entries:\n\n- `name`: The name of the preset. It will be used in conjunction with `--preset` flag. e.g. `--preset custom`\n- `key_config`: An array of key press/release events for assigning audio files to the specified keys. It can also be used to control the volume etc.\n- `disabled_keys`: An array of keys that will not be used for playback.\n- `variation`: Variate the sound on each event for `key_config`s that do not specify variations[\\*](#sound-variation)\n\n\u003cdetails\u003e\n  \u003csummary\u003eClick for the \u003ca href=\"https://docs.rs/rdev/latest/rdev/enum.Key.html\"\u003elist of available keys\u003c/a\u003e.\u003c/summary\u003e\n\n`Alt`, `AltGr`, `Backspace`, `CapsLock`, `ControlLeft`, `ControlRight`, `Delete`, `DownArrow`, `End`, `Escape`, `F1`, `F10`, `F11`, `F12`, `F2`, `F3`, `F4`, `F5`, `F6`, `F7`, `F8`, `F9`, `Home`, `LeftArrow`, `MetaLeft`, `MetaRight`, `PageDown`, `PageUp`, `Return`, `RightArrow`, `ShiftLeft`, `ShiftRight`, `Space`, `Tab`, `UpArrow`, `PrintScreen`, `ScrollLock`, `Pause`, `NumLock`, `BackQuote`, `Num1`, `Num2`, `Num3`, `Num4`, `Num5`, `Num6`, `Num7`, `Num8`, `Num9`, `Num0`, `Minus`, `Equal`, `KeyQ`, `KeyW`, `KeyE`, `KeyR`, `KeyT`, `KeyY`, `KeyU`, `KeyI`, `KeyO`, `KeyP`, `LeftBracket`, `RightBracket`, `KeyA`, `KeyS`, `KeyD`, `KeyF`, `KeyG`, `KeyH`, `KeyJ`, `KeyK`, `KeyL`, `SemiColon`, `Quote`, `BackSlash`, `IntlBackslash`, `KeyZ`, `KeyX`, `KeyC`, `KeyV`, `KeyB`, `KeyN`, `KeyM`, `Comma`, `Dot`, `Slash`, `Insert`, `KpReturn`, `KpMinus`, `KpPlus`, `KpMultiply`, `KpDivide`, `Kp0`, `Kp1`, `Kp2`, `Kp3`, `Kp4`, `Kp5`, `Kp6`, `Kp7`, `Kp8`, `Kp9`, `KpDelete`, `Function`, `Unknown`\n\n\u003c/details\u003e\n\nAs an example, here is how you can configure `key_config`:\n\n```toml\nkey_config = [\n  { event = \"press\", keys = \"Return\", files = [{ path = \"ding.mp3\", volume = 1.0 }] },\n]\n```\n\n- `event`: \"press\" or \"release\"\n- `keys`: A regular expression (regex) for matching the keys.\n- `files`: An array of files.\n  - `path`: The absolute path of the file. If the file is embedded in the binary (i.e. if it is inside `sounds/` directory) then it is the name of the file without full path.\n  - `volume`: The volume of the sound. The value 1.0 is the \"normal\" volume (unfiltered input). Any value other than 1.0 will multiply each sample by this value.\n- `variation`: Variate the sound on each `event`[\\*](#sound-variation)\n\nIf you have defined multiple files for a key event, you can also specify a strategy for how to play them:\n\n```toml\nkey_config = [\n  { event = \"press\", keys = \".*\", files = [{ path = \"1.mp3\" }, { path = \"2.mp3\" }], strategy = \"random\" },\n]\n```\n\nCurrently supported strategies are:\n\n- `strategy = \"random\"`: pick a random file from the list and play it.\n- `strategy = \"sequential\"`: play the files sequentially.\n\nHere is how you can combine everything together:\n\n```toml\n[[sound_preset]]\n# Custom sound preset named \"custom\"\nname = \"custom\"\n\n# Key configurations for various events\nkey_config = [\n  # When a key starting with \"Key\" is pressed, play 1.mp3, 2.mp3, and 3.mp3 sequentially\n  { event = \"press\", keys = \"Key*\", files = [\n    { path = \"1.mp3\" },\n    { path = \"2.mp3\" },\n    { path = \"3.mp3\" },\n  ], strategy = \"sequential\" },\n\n  # When a key starting with \"Key\" is released, play 4.mp3\n  { event = \"release\", keys = \"Key*\", files = [\n    { path = \"4.mp3\" },\n  ] },\n\n  # When a key starting with \"Num\" is pressed, play num.mp3 at a very high volume (10.0)\n  { event = \"press\", keys = \"Num*\", files = [\n    { path = \"num.mp3\", volume = 10.0 },\n  ] },\n\n  # When any key is pressed, play a random sound from cat.mp3, dog.mp3, or bird.mp3\n  { event = \"press\", keys = \".*\", files = [\n    { path = \"cat.mp3\" },\n    { path = \"dog.mp3\" },\n    { path = \"bird.mp3\" },\n  ], strategy = \"random\", variation = { volume: [0.1, 0.1], tempo: [0.05, 0.05] } },\n]\n\n# Disabled keys that won't trigger any sound events\ndisabled_keys = [\"CapsLock\", \"NumLock\"]\n```\n\n### Sound Variation\n\nTo make the keyboard sounds more varied it is possible to variate both volume and playback speed (the later also varies the pitch).\n\nValues are in percent, where the first value determines the maximum increase and the second the maximum decrease. The actual value is determined randomly on each keypress.\n\n- If command line arguments or environment variables are set configurations made in the presets are overridden.\n  - Values need to be separated by a \",\".\n  - If only one value is supplied it is used for both increase and decrease\n- If a `key_config` is set the preset values are overridden.\n- The configuration on a preset applies to all `key_config`'s that do not have any values set.\n\n## Similar Projects\n\n- [`bucklespring`](https://github.com/zevv/bucklespring): Nostalgia bucklespring keyboard sound\n- [`selectric-mode`](https://github.com/rbanffy/selectric-mode): Make your Emacs sound like a proper typewriter\n\n## MacOS permissions\n\nOn MacOS, you need to give some permissions to the terminal where you run **daktilo**.\n\nThe first time you run **daktilo**, you will probably see this popup:\n\n![macos-permissions](assets/mac_terminal_permission.png)\n\nIf you see it, click on \"Open System Settings\", otherwise open \"System Settings\" manually and go to \"Privacy and Security\".\nFrom here, enable \"Input Monitoring\" for your terminal application:\n\n![macos-input-monitoring](assets/mac_input_monitoring.png)\n\n## Acknowledgements\n\nHuge thanks to [H. Arda Güler](https://github.com/arda-guler/) for giving me the idea for this project, sharing the inspiration behind it and implementing the first iteration in Python.\n\nKudos! 👾\n\n## Donations\n\n[![Support me on GitHub Sponsors](https://img.shields.io/github/sponsors/orhun?style=flat\u0026logo=GitHub\u0026labelColor=1D272B\u0026color=819188\u0026logoColor=white)](https://github.com/sponsors/orhun)\n[![Support me on Patreon](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3Dorhunp%26type%3Dpatrons\u0026style=flat\u0026logo=Patreon\u0026labelColor=1D272B\u0026color=819188\u0026logoColor=white)](https://patreon.com/join/orhunp)\n[![Support me on Patreon](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3Dorhunp%26type%3Dpledges\u0026style=flat\u0026logo=Patreon\u0026labelColor=1D272B\u0026color=819188\u0026logoColor=white\u0026label=)](https://patreon.com/join/orhunp)\n\nIf you find **daktilo** and/or other projects on my [GitHub](https://github.com/orhun) useful, consider supporting me on [GitHub Sponsors](https://github.com/sponsors/orhun) or [becoming a patron](https://www.patreon.com/join/orhunp)!\n\n## Contributing\n\nSee our [Contribution Guide](./CONTRIBUTING.md) and please follow the [Code of Conduct](./CODE_OF_CONDUCT.md) in all your interactions with the project.\n\nAlso, see how you can add new presets [here](CONTRIBUTING.md#how-to-add-new-presets).\n\n## License\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat\u0026logo=GitHub\u0026labelColor=1D272B\u0026color=819188\u0026logoColor=white)](./LICENSE-MIT)\n[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg?style=flat\u0026logo=GitHub\u0026labelColor=1D272B\u0026color=819188\u0026logoColor=white)](./LICENSE-APACHE)\n\nLicensed under either of [Apache License Version 2.0](./LICENSE-APACHE) or [The MIT License](./LICENSE-MIT) at your option.\n\n🦀 ノ( º \\_ º ノ) - respect crables!\n\n## Copyright\n\nCopyright © 2023-2024, [Orhun Parmaksız](mailto:orhunparmaksiz@gmail.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forhun%2Fdaktilo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Forhun%2Fdaktilo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forhun%2Fdaktilo/lists"}