├── .github ├── FUNDING.yml ├── stale.yml └── workflows │ └── build.yml ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── PLING.bbcode ├── README.md ├── bitmapper ├── Makefile ├── package.json ├── packages │ ├── core │ │ ├── package.json │ │ ├── src │ │ │ ├── BitmapsGenerator.ts │ │ │ ├── SVGHandler │ │ │ │ ├── SvgDirectoryParser.ts │ │ │ │ ├── colorSvg.ts │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── util │ │ │ │ ├── frameNumber.ts │ │ │ │ ├── matchImages.ts │ │ │ │ └── toHTML.ts │ │ └── tsconfig.json │ ├── modern │ │ ├── package.json │ │ ├── src │ │ │ ├── config.ts │ │ │ └── index.ts │ │ └── tsconfig.json │ └── original │ │ ├── package.json │ │ ├── src │ │ ├── config.ts │ │ └── index.ts │ │ └── tsconfig.json ├── tsconfig.json └── yarn.lock ├── builder ├── Makefile ├── build.py └── src │ ├── __init__.py │ ├── configure.py │ ├── constants.py │ ├── generator.py │ └── symlinks.py ├── pyrightconfig.json └── svg ├── link.py ├── modern ├── animated │ ├── left_ptr_watch.svg │ └── wait.svg └── static │ ├── X_cursor.svg │ ├── bd_double_arrow.svg │ ├── bottom_left_corner.svg │ ├── bottom_right_corner.svg │ ├── bottom_side.svg │ ├── bottom_tee.svg │ ├── center_ptr.svg │ ├── circle.svg │ ├── context-menu.svg │ ├── copy.svg │ ├── cross.svg │ ├── crossed_circle.svg │ ├── crosshair.svg │ ├── dnd-ask.svg │ ├── dnd-copy.svg │ ├── dnd-link.svg │ ├── dnd-move.svg │ ├── dnd_no_drop.svg │ ├── dotbox.svg │ ├── fd_double_arrow.svg │ ├── grabbing.svg │ ├── hand1.svg │ ├── hand2.svg │ ├── left_ptr.svg │ ├── left_side.svg │ ├── left_tee.svg │ ├── link.svg │ ├── ll_angle.svg │ ├── lr_angle.svg │ ├── move.svg │ ├── pencil.svg │ ├── plus.svg │ ├── pointer-move.svg │ ├── question_arrow.svg │ ├── right_ptr.svg │ ├── right_side.svg │ ├── right_tee.svg │ ├── sb_down_arrow.svg │ ├── sb_h_double_arrow.svg │ ├── sb_left_arrow.svg │ ├── sb_right_arrow.svg │ ├── sb_up_arrow.svg │ ├── sb_v_double_arrow.svg │ ├── tcross.svg │ ├── top_left_corner.svg │ ├── top_right_corner.svg │ ├── top_side.svg │ ├── top_tee.svg │ ├── ul_angle.svg │ ├── ur_angle.svg │ ├── vertical-text.svg │ ├── wayland-cursor.svg │ ├── xterm.svg │ ├── zoom-in.svg │ └── zoom-out.svg └── original ├── animated ├── left_ptr_watch.svg └── wait.svg └── static ├── X_cursor.svg ├── bd_double_arrow.svg ├── bottom_left_corner.svg ├── bottom_right_corner.svg ├── bottom_side.svg ├── bottom_tee.svg ├── center_ptr.svg ├── circle.svg ├── context-menu.svg ├── copy.svg ├── cross.svg ├── crossed_circle.svg ├── crosshair.svg ├── dnd-ask.svg ├── dnd-copy.svg ├── dnd-link.svg ├── dnd-move.svg ├── dnd_no_drop.svg ├── dotbox.svg ├── fd_double_arrow.svg ├── grabbing.svg ├── hand1.svg ├── hand2.svg ├── left_ptr.svg ├── left_side.svg ├── left_tee.svg ├── link.svg ├── ll_angle.svg ├── lr_angle.svg ├── move.svg ├── pencil.svg ├── plus.svg ├── pointer-move.svg ├── question_arrow.svg ├── right_ptr.svg ├── right_side.svg ├── right_tee.svg ├── sb_down_arrow.svg ├── sb_h_double_arrow.svg ├── sb_left_arrow.svg ├── sb_right_arrow.svg ├── sb_up_arrow.svg ├── sb_v_double_arrow.svg ├── tcross.svg ├── top_left_corner.svg ├── top_right_corner.svg ├── top_side.svg ├── top_tee.svg ├── ul_angle.svg ├── ur_angle.svg ├── vertical-text.svg ├── wayland-cursor.svg ├── xterm.svg ├── zoom-in.svg └── zoom-out.svg /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | liberapay: ful1e5 2 | patreon: ful1e5 3 | custom: https://www.paypal.me/kaizkhatri 4 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # --------------------------------------------- Custom 2 | bitmaps 3 | themes 4 | bin 5 | 6 | # --------------------------------------------- Python 7 | 8 | # Byte-compiled / optimized / DLL files 9 | __pycache__/ 10 | *.py[cod] 11 | *$py.class 12 | 13 | # C extensions 14 | *.so 15 | 16 | # Distribution / packaging 17 | .Python 18 | build/ 19 | develop-eggs/ 20 | dist/ 21 | downloads/ 22 | eggs/ 23 | .eggs/ 24 | lib/ 25 | lib64/ 26 | parts/ 27 | sdist/ 28 | var/ 29 | wheels/ 30 | pip-wheel-metadata/ 31 | share/python-wheels/ 32 | *.egg-info/ 33 | .installed.cfg 34 | *.egg 35 | MANIFEST 36 | 37 | # PyInstaller 38 | # Usually these files are written by a python script from a template 39 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 40 | *.manifest 41 | *.spec 42 | 43 | # Installer logs 44 | pip-log.txt 45 | pip-delete-this-directory.txt 46 | 47 | # Unit test / coverage reports 48 | htmlcov/ 49 | .tox/ 50 | .nox/ 51 | .coverage 52 | .coverage.* 53 | .cache 54 | nosetests.xml 55 | coverage.xml 56 | *.cover 57 | *.py,cover 58 | .hypothesis/ 59 | .pytest_cache/ 60 | 61 | # Translations 62 | *.mo 63 | *.pot 64 | 65 | # Django stuff: 66 | *.log 67 | local_settings.py 68 | db.sqlite3 69 | db.sqlite3-journal 70 | 71 | # Flask stuff: 72 | instance/ 73 | .webassets-cache 74 | 75 | # Scrapy stuff: 76 | .scrapy 77 | 78 | # Sphinx documentation 79 | docs/_build/ 80 | 81 | # PyBuilder 82 | target/ 83 | 84 | # Jupyter Notebook 85 | .ipynb_checkpoints 86 | 87 | # IPython 88 | profile_default/ 89 | ipython_config.py 90 | 91 | # pyenv 92 | .python-version 93 | 94 | # pipenv 95 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 96 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 97 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 98 | # install all needed dependencies. 99 | #Pipfile.lock 100 | 101 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 102 | __pypackages__/ 103 | 104 | # Celery stuff 105 | celerybeat-schedule 106 | celerybeat.pid 107 | 108 | # SageMath parsed files 109 | *.sage.py 110 | 111 | # Environments 112 | .env 113 | .venv 114 | env/ 115 | venv/ 116 | ENV/ 117 | env.bak/ 118 | venv.bak/ 119 | 120 | # Spyder project settings 121 | .spyderproject 122 | .spyproject 123 | 124 | # Rope project settings 125 | .ropeproject 126 | 127 | # mkdocs documentation 128 | /site 129 | 130 | # mypy 131 | .mypy_cache/ 132 | .dmypy.json 133 | dmypy.json 134 | 135 | # Pyre type checker 136 | .pyre/ 137 | 138 | 139 | # --------------------------------------------- Nodejs 140 | 141 | # Logs 142 | logs 143 | *.log 144 | npm-debug.log* 145 | yarn-debug.log* 146 | yarn-error.log* 147 | lerna-debug.log* 148 | 149 | # Diagnostic reports (https://nodejs.org/api/report.html) 150 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 151 | 152 | # Runtime data 153 | pids 154 | *.pid 155 | *.seed 156 | *.pid.lock 157 | 158 | # Directory for instrumented libs generated by jscoverage/JSCover 159 | lib-cov 160 | 161 | # Coverage directory used by tools like istanbul 162 | coverage 163 | *.lcov 164 | 165 | # nyc test coverage 166 | .nyc_output 167 | 168 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 169 | .grunt 170 | 171 | # Bower dependency directory (https://bower.io/) 172 | bower_components 173 | 174 | # node-waf configuration 175 | .lock-wscript 176 | 177 | # Compiled binary addons (https://nodejs.org/api/addons.html) 178 | build/Release 179 | 180 | # Dependency directories 181 | node_modules/ 182 | jspm_packages/ 183 | 184 | # Snowpack dependency directory (https://snowpack.dev/) 185 | web_modules/ 186 | 187 | # TypeScript cache 188 | *.tsbuildinfo 189 | 190 | # Optional npm cache directory 191 | .npm 192 | 193 | # Optional eslint cache 194 | .eslintcache 195 | 196 | # Microbundle cache 197 | .rpt2_cache/ 198 | .rts2_cache_cjs/ 199 | .rts2_cache_es/ 200 | .rts2_cache_umd/ 201 | 202 | # Optional REPL history 203 | .node_repl_history 204 | 205 | # Output of 'npm pack' 206 | *.tgz 207 | 208 | # Yarn Integrity file 209 | .yarn-integrity 210 | 211 | # dotenv environment variables file 212 | .env 213 | .env.test 214 | 215 | # parcel-bundler cache (https://parceljs.org/) 216 | .cache 217 | .parcel-cache 218 | 219 | # Next.js build output 220 | .next 221 | out 222 | 223 | # Nuxt.js build / generate output 224 | .nuxt 225 | dist 226 | 227 | # Gatsby files 228 | .cache/ 229 | # Comment in the public line in if your project uses Gatsby and not Next.js 230 | # https://nextjs.org/blog/next-9-1#public-directory-support 231 | # public 232 | 233 | # vuepress build output 234 | .vuepress/dist 235 | 236 | # Serverless directories 237 | .serverless/ 238 | 239 | # FuseBox cache 240 | .fusebox/ 241 | 242 | # DynamoDB Local files 243 | .dynamodb/ 244 | 245 | # TernJS port file 246 | .tern-port 247 | 248 | # Stores VSCode versions used for testing VSCode extensions 249 | .vscode-test 250 | 251 | # yarn v2 252 | .yarn/cache 253 | .yarn/unplugged 254 | .yarn/build-state.yml 255 | .yarn/install-state.gz 256 | .pnp.* 257 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [unreleased] 9 | 10 | ### Added 11 | 12 | - [Bibata Zebra](https://github.com/ful1e5/Bibata-Zebra-Cursor) link added inside README.md 13 | - [Bibata Bee](https://github.com/ful1e5/Bibata-Bee-Cursor) link added inside README.md 14 | - support creator with liberapay 15 | - minimal `README.md` 16 | - symlink common cursor svg files using `svg/link.py` 17 | - ci updated for symlink script 18 | - distributed artifacts inside `build` GitHub actions 19 | - Add cursor `top_left_arrow` BreezeX_Cursor#10 BreezeX_Cursor#11 20 | - ignore files in `build` GitHub Action 21 | - Uninstall docs ful1e5/apple_cursor#79 ful1e5/apple_cursor#80 22 | 23 | ### Changed 24 | 25 | - used `THEME_PREFIX` variable in make commands 26 | - removed emojis from README.md 27 | - Github Action renamed to `build` from `bibata-ci` 28 | - prettier `bitmapping` logs 29 | - `svg/link.py` file added inside pyright config 30 | - Fix `None` value warning in `builder/symlinks.py` 31 | 32 | ## [v1.0.1] - 25 Jun 2021 33 | 34 | ### Added 35 | 36 | - Support button inside `PLING.bbcode` product page 37 | - `pyrightconfig.json` init 38 | - `make prepare` for preparing binaries 39 | 40 | ### Changed 41 | 42 | - Removed **clean** target from `builder/Makefile` 43 | - Compact code inside `builder/*` 44 | - Remove `setup.py` 45 | - Builder code moved to `src` 46 | - Import `src` module directly inside `build.py` 47 | - `Makefile` build commands re-arrange with groups 48 | - `Turqouise` typo fixed #9 (by @yochananmarqos) 49 | 50 | ## [v1.0.0] - 5 Apr 2021 51 | 52 | ### Changed 53 | 54 | - `main` as **default** branch 55 | - Package **size** reduced 56 | - Build process with `python` & [**clickgen**](https://github.com/ful1e5/clickgen) 57 | - Cursors Redesign => `all_scroll`, `pencil`, `wayland_cursor`, `xcursor` and all `pointer symbols`(with Bigger Symbols) cursors 58 | - Bitmaps Rendering with [**puppeteer**](https://github.com/puppeteer/puppeteer) 59 | - Build Docs 60 | 61 | ### Added 62 | 63 | - Bibata Original (Old Bibata) 64 | - Windows Package with **Double Click** installation 😍 65 | - Maintaining [CHANGELOG.md](./CHANGELOG.md) 66 | - [PLING.bbcode](./PLING.bbcode) for pling.com Product page docs 67 | - [GitHub Actions](https://github.com/ful1e5/Bibata_Extra_Cursor/actions) added 68 | - New Build with **10x** faster rendering. 69 | - Customizable Colors in **Bibata** Cursors. 70 | - Auto framing in animated cursors with [**pixelmatch**](https://github.com/mapbox/pixelmatch) 71 | 72 | ## [v0.3] - 12 Jan 2020 73 | 74 | ### Added 75 | 76 | - Initial release 🎊 77 | 78 | [unreleased]: https://github.com/ful1e5/Bibata_Extra_Cursor/compare/v1.0.1...main 79 | [v1.0.1]: https://github.com/ful1e5/Bibata_Extra_Cursor/compare/v1.0.0...v1.0.1 80 | [v1.0.0]: https://github.com/ful1e5/Bibata_Extra_Cursor/compare/v0.3...v1.0.0 81 | [v0.3]: https://github.com/ful1e5/Bibata_Extra_Cursor/tree/v0.3 82 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | education, socio-economic status, nationality, personal appearance, race, 10 | religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at kaizmandhu@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Bibata 2 | 3 | I love your input! I want to make contributing to this project as easy and transparent as possible, whether it's: 4 | 5 | - Reporting a bug 6 | - Discussing the current state of the code 7 | - Submitting a fix 8 | - Proposing new features 9 | - Becoming a maintainer 10 | 11 | ## I Develop with Github 12 | 13 | I use github to host code, to track issues and feature requests, as well as accept pull requests. 14 | 15 | ## I Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests 16 | 17 | Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your pull requests: 18 | 19 | 1. Fork the repo and create your branch from `main`. 20 | 2. If you've added code that should be tested, add tests. 21 | 3. If you've changed Look, update the documentation. 22 | 4. Issue that pull request! 23 | 24 | ## Any contributions you make will be under the GPL - 3.0 Software License 25 | 26 | In short, when you submit code changes, your submissions are understood to be under the same [GPL - 3.0 License](https://www.gnu.org/licenses/gpl-3.0.en.html) that covers the project. Feel free to contact the maintainers if that's a concern. 27 | 28 | ## Report bugs using Github's [issues](https://github.com/ful1e5/Bibata_Extra_Cursor/issues) 29 | 30 | I use GitHub issues to track public bugs. Report a bug by opening a new issue, it's that easy! 31 | 32 | ## Write bug reports with detail, background, and sample code 33 | 34 | **Great Bug Reports** tend to have: 35 | 36 | - A quick summary and/or background 37 | - Steps to reproduce 38 | - Be specific! 39 | - Give sample code if you can. 40 | - What you expected would happen 41 | - What actually happens 42 | - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) 43 | 44 | People _love_ thorough bug reports. I'm not even kidding. 45 | 46 | ## License 47 | 48 | By contributing, you agree that your contributions will be licensed under its `GPL - 3.0` License. 49 | 50 | ## References 51 | 52 | This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md) 53 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: clean render build 2 | .PHONY: all 3 | 4 | clean: 5 | @rm -rf bitmaps themes 6 | 7 | render: svg bitmapper 8 | @cd bitmapper && $(MAKE) 9 | 10 | build: bitmaps 11 | @cd builder && make setup build 12 | 13 | 14 | # Build Only UNIX cursors 15 | unix: clean render bitmaps 16 | @cd builder && make setup build_unix 17 | 18 | 19 | # Build Only Windows cursors 20 | windows: clean render bitmaps 21 | @cd builder && make setup build_windows 22 | 23 | 24 | # Build Bibata-Modern Cursors 25 | modern: clean render_modern build_modern 26 | 27 | render_modern: bitmapper svg 28 | @cd bitmapper && make yarn_install render_modern 29 | 30 | build_modern: bitmaps 31 | @cd builder && make setup build_modern 32 | 33 | 34 | # Build Bibata-Original Cursors 35 | original:clean render_original build_original 36 | 37 | render_original: bitmapper svg 38 | @cd bitmapper && make yarn_install render_original 39 | 40 | build_original: bitmaps 41 | @cd builder && make setup build_original 42 | 43 | 44 | # Installation 45 | 46 | .ONESHELL: 47 | SHELL := /bin/bash 48 | THEME_PREFIX = Bibata 49 | 50 | src = ./themes/$(THEME_PREFIX)-* 51 | local := ~/.icons 52 | local_dest := $(local)/$(THEME_PREFIX)-* 53 | 54 | root := /usr/share/icons 55 | root_dest := $(root)/$(THEME_PREFIX)-* 56 | 57 | install: themes 58 | @if [[ $EUID -ne 0 ]]; then 59 | @echo "> Installing '$(THEME_PREFIX)' cursors inside $(local)/..." 60 | @mkdir -p $(local) 61 | @cp -r $(src) $(local)/ && echo "> Installed!" 62 | @else 63 | @echo "> Installing '$(THEME_PREFIX)' cursors inside $(root)/..." 64 | @mkdir -p $(root) 65 | @sudo cp -r $(src) $(root)/ && echo "> Installed!" 66 | @fi 67 | 68 | uninstall: 69 | @if [[ $EUID -ne 0 ]]; then 70 | @echo "> Removing '$(THEME_PREFIX)' cursors from '$(local)'..." 71 | @rm -rf $(local_dest) 72 | @else 73 | @echo "> Removing '$(THEME_PREFIX)' cursors from '$(root)'..." 74 | @sudo rm -rf $(root_dest) 75 | @fi 76 | 77 | reinstall: uninstall install 78 | 79 | 80 | # generates binaries 81 | THEMES = DarkRed DodgerBlue Pink Turquoise 82 | BIN_DIR = ../bin 83 | 84 | modern = $(THEME_PREFIX)-Modern 85 | original = $(THEME_PREFIX)-Original 86 | prepare: bitmaps themes 87 | # Bitmaps 88 | @rm -rf bin && mkdir bin 89 | @cd bitmaps && zip -r $(BIN_DIR)/bitmaps.zip * && cd .. 90 | @cd themes 91 | # 92 | # Bibata-Modern 93 | # 94 | @$(foreach theme,$(THEMES), tar -czvf $(BIN_DIR)/$(modern)-$(theme).tar.gz $(modern)-$(theme);) 95 | @$(foreach theme,$(THEMES), zip -r $(BIN_DIR)/$(modern)-$(theme)-Windows.zip $(modern)-$(theme)-Windows;) 96 | @tar -czvf $(BIN_DIR)/$(modern).tar.gz $(modern)-DarkRed $(modern)-DodgerBlue $(modern)-Pink $(modern)-Turquoise 97 | @zip -r $(BIN_DIR)/$(modern)-Windows.zip $(modern)-DarkRed-Windows $(modern)-DodgerBlue-Windows $(modern)-Pink-Windows $(modern)-Turquoise-Windows 98 | # 99 | # Bibata-Original 100 | # 101 | @$(foreach theme,$(THEMES), tar -czvf $(BIN_DIR)/$(original)-$(theme).tar.gz $(original)-$(theme);) 102 | @$(foreach theme,$(THEMES), zip -r $(BIN_DIR)/$(original)-$(theme)-Windows.zip $(original)-$(theme)-Windows;) 103 | @tar -czvf $(BIN_DIR)/$(original).tar.gz $(original)-DarkRed $(original)-DodgerBlue $(original)-Pink $(original)-Turquoise 104 | @zip -r $(BIN_DIR)/$(original)-Windows.zip $(original)-DarkRed-Windows $(original)-DodgerBlue-Windows $(original)-Pink-Windows $(original)-Turquoise-Windows 105 | # 106 | # BibataExtra.tar.gz 107 | # 108 | @tar -czvf $(BIN_DIR)/BibataExtra.tar.gz --exclude='*-Windows' * 109 | @cd .. 110 | -------------------------------------------------------------------------------- /PLING.bbcode: -------------------------------------------------------------------------------- 1 | [b]Bibata[/b] Cursor Theme with [b]Extra colors[/b] and [b]HiDPi[/b] Display support. This Cursor is built with [b][url=https://github.com/ful1e5/clickgen]clickgen[/url][/b] and render with the [b][url=https://github.com/puppeteer/puppeteer/]puppeteer[/url][/b]. 2 | 3 | [i][b]Bibata Styles: [/b][/i] 4 | [i]Bibata Modern [/i] : Round Edges Bibata Cursors 5 | [i]Bibata Original [/i] : Sharp Edges Bibata Cursors 6 | 7 | [i]Available Sizes[/i] [b]22, 24, 28, 32, 40, 48, 56, 64, 72, 80, 88, 96[/b] 8 | [i]Get the latest build[/i] @[b][url=https://github.com/ful1e5/Bibata_Extra_Cursor/actions]GitHub Actions[/url][/b] 9 | [i]Release Notification[/i] at [b][url=https://twitter.com/ful1e5]Twitter[/url][/b](@ful1e5) 10 | For [i]Customizing Size[/i] check [b][url=https://github.com/ful1e5/Bibata_Extra_Cursor#manual-build]README.md[/url][/b] 11 | 12 | [b] Support Creator[/b] 13 | 14 | [url=https://www.buymeacoffee.com/Nt7Wg4V][img]https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png[/img][/url] 15 | 16 | [b]Linux/X11 installation[/b] 17 | Get the latest stable Linux release from the [b][url=https://www.pling.com/p/1269768/#files-panel]Pling[/url][/b]. Unpack [b].tar.gz[/b] file and follow these [b]commands[/b]. 18 | 19 | [b]Install[/b] 20 | [b]For all user:[/b] 21 | [code]sudo mv Bibata-* /usr/share/icons[/code] 22 | [b]For local user: 23 | [/b][code]mv Bibata-* ~/.icons[/code] 24 | 25 | [b][size=100]Uninstall[/size][/b] 26 | 27 | [b]From all user:[/b] 28 | [code]sudo rm -r /usr/share/icons/Bibata-*[/code] 29 | 30 | [b]From local user:[/b] 31 | [code]rm -r ~/.icons/Bibata-*[/code] 32 | 33 | [size=150][b]Window installation[/b][/size] 34 | [list=1] 35 | [*]unzip [b].zip[/b] file[/*] 36 | [*]Open [b]unziped[/b] directory in Explorer, and [b]right-click[/b] on [b]install.inf[/b].[/*] 37 | [*]Click 'Install' from the context menu, and authorize the modifications to your system.[/*] 38 | [*]Open [i]Control Panel > Personalisation and Appearance > Change mouse pointers[/i], and select [b]Bibata Cursors[/b].[/*] 39 | [*]Click '[b]Apply[/b]'.[/*] 40 | [/list] 41 | 42 | [b]How I help the Creator?[/b] 43 | [list=2] 44 | [*][size=85]Give a [b]Star[/b] or [b]Follow[/b] on [b][url=https://github.com/ful1e5/Bibata_Extra_Cursor]GitHub[/url][/b] (issues & PullRequest are welcome).[/size][/*] 45 | [*][size=85]By giving a [b]Pling[/b] or [b][url=https://www.paypal.me/kaizkhatri]Donation[/url][/b].[/size][/*] 46 | [*][size=85][b]Download[/b] from[url=https://www.pling.com/p/1269768] Pling.com[/url] Product page that helps to [b]increases[/b] my [b]monthly payout[/b].[/size][/*] 47 | [*][size=85][b][url=https://www.pling.com/support]Become a Supporter of Pling.com[/url][/b], So we become [b]Full-Time [/b]Libre & FOSS content creator [b];)[/b][/size][/*] 48 | [/list] 49 | 50 | [size=150][b]License & Terms[/b][/size] 51 | '[b]Bibata[/b]' and '[b]Bibata Extra[/b]' Cursor Theme are available under the terms of the [b]GPL-3.0[/b] license. 52 | -------------------------------------------------------------------------------- /bitmapper/Makefile: -------------------------------------------------------------------------------- 1 | all: yarn_install render 2 | 3 | .PHONY: all 4 | 5 | clean: 6 | @find . -type f -name "yarn.lock" -exec rm -rf "{}" +; 7 | @find . -type d -name "node_modules" -exec rm -rf "{}" +; 8 | 9 | node_modules: 10 | @mkdir -p $@ 11 | 12 | yarn_install: node_modules package.json 13 | @yarn install 14 | 15 | render_modern: 16 | @yarn render:bibata-modern 17 | 18 | render_original: 19 | @yarn render:bibata-original 20 | 21 | render: render_modern render_original 22 | -------------------------------------------------------------------------------- /bitmapper/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bibata-cursor", 3 | "version": "1.0.1", 4 | "description": "Material Based Cursors", 5 | "main": "index.js", 6 | "author": "Kaiz Khatri", 7 | "license": "GPL-3.0", 8 | "private": true, 9 | "scripts": { 10 | "render:bibata-modern": "yarn workspace bibata-modern render", 11 | "render:bibata-original": "yarn workspace bibata-original render", 12 | "render:bibata-rainbow": "yarn workspace bibata-rainbow render" 13 | }, 14 | "workspaces": [ 15 | "packages/*" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /bitmapper/packages/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bibata-core", 3 | "version": "1.1.0", 4 | "description": "Bibata bitmapper's core modules", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "author": "Kaiz Khatri", 8 | "license": "GPL-3.0", 9 | "private": true, 10 | "dependencies": { 11 | "pixelmatch": "^5.2.1", 12 | "pngjs": "^6.0.0", 13 | "puppeteer": "^7.1.0" 14 | }, 15 | "devDependencies": { 16 | "@types/pixelmatch": "^5.2.2", 17 | "@types/pngjs": "^6.0.0", 18 | "@types/puppeteer": "^5.4.3", 19 | "ts-node": "^9.1.1", 20 | "typescript": "^4.1.5" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /bitmapper/packages/core/src/BitmapsGenerator.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import path from "path"; 3 | 4 | import puppeteer, { Browser, ElementHandle, Page } from "puppeteer"; 5 | 6 | import { frameNumber } from "./util/frameNumber"; 7 | import { matchImages } from "./util/matchImages"; 8 | import { toHTML } from "./util/toHTML"; 9 | 10 | class BitmapsGenerator { 11 | /** 12 | * Generate Png files from svg code. 13 | * @param themeName Give name, So all bitmaps files are organized in one directory. 14 | * @param bitmapsDir `absolute` or `relative` path, Where `.png` files will store. 15 | */ 16 | constructor(private bitmapsDir: string) { 17 | this.bitmapsDir = path.resolve(bitmapsDir); 18 | this.createDir(this.bitmapsDir); 19 | } 20 | 21 | /** 22 | * Create directory if it doesn't exists. 23 | * @param dirPath directory `absolute` path. 24 | */ 25 | private createDir(dirPath: string) { 26 | if (!fs.existsSync(dirPath)) { 27 | fs.mkdirSync(dirPath, { recursive: true }); 28 | } 29 | } 30 | 31 | /** 32 | * Prepare headless browser. 33 | */ 34 | public async getBrowser(): Promise { 35 | return puppeteer.launch({ 36 | ignoreDefaultArgs: ["--no-sandbox"], 37 | headless: true, 38 | }); 39 | } 40 | 41 | private async getSvgElement( 42 | page: Page, 43 | content: string 44 | ): Promise> { 45 | if (!content) { 46 | throw new Error(`${content} File Read error`); 47 | } 48 | 49 | const html = toHTML(content); 50 | await page.setContent(html, { timeout: 0 }); 51 | 52 | const svg = await page.$("#container svg"); 53 | 54 | if (!svg) { 55 | throw new Error("svg element not found!"); 56 | } 57 | return svg; 58 | } 59 | 60 | public async generateStatic(browser: Browser, content: string, key: string) { 61 | const page = await browser.newPage(); 62 | const svg = await this.getSvgElement(page, content); 63 | 64 | const out = path.resolve(this.bitmapsDir, `${key}.png`); 65 | 66 | await svg.screenshot({ omitBackground: true, path: out }); 67 | await page.close(); 68 | } 69 | 70 | private async screenshot( 71 | element: ElementHandle 72 | ): Promise { 73 | const buffer = await element.screenshot({ 74 | encoding: "binary", 75 | omitBackground: true, 76 | }); 77 | 78 | if (!buffer) { 79 | throw new Error("SVG element screenshot not working"); 80 | } 81 | return buffer; 82 | } 83 | 84 | private async stopAnimation(page: Page) { 85 | const client = await page.target().createCDPSession(); 86 | await client.send("Animation.setPlaybackRate", { 87 | playbackRate: 0, 88 | }); 89 | } 90 | 91 | private async resumeAnimation(page: Page, playbackRate: number) { 92 | const client = await page.target().createCDPSession(); 93 | await client.send("Animation.setPlaybackRate", { 94 | playbackRate, 95 | }); 96 | } 97 | 98 | private async saveFrameImage(key: string, frame: Buffer | string) { 99 | const out_path = path.resolve(this.bitmapsDir, key); 100 | fs.writeFileSync(out_path, frame); 101 | } 102 | 103 | public async generateAnimated( 104 | browser: Browser, 105 | content: string, 106 | key: string, 107 | options?: { 108 | playbackRate?: number; 109 | diff?: number; 110 | frameLimit?: number; 111 | framePadding?: number; 112 | } 113 | ) { 114 | const opt = Object.assign( 115 | { 116 | playbackRate: 0.3, 117 | diff: 0, 118 | frameLimit: 300, 119 | framePadding: 4, 120 | }, 121 | options 122 | ); 123 | 124 | const page = await browser.newPage(); 125 | const svg = await this.getSvgElement(page, content); 126 | await this.stopAnimation(page); 127 | 128 | let index = 1; 129 | let breakRendering = false; 130 | let prevImg: Buffer | string; 131 | 132 | // Rendering frames till `imgN` matched to `imgN-1` (When Animation is done) 133 | while (!breakRendering) { 134 | if (index > opt.frameLimit) { 135 | throw new Error("Reached the frame limit."); 136 | } 137 | 138 | await this.resumeAnimation(page, opt.playbackRate); 139 | const img: string | Buffer = await this.screenshot(svg); 140 | await this.stopAnimation(page); 141 | 142 | if (index > 1) { 143 | // @ts-ignore 144 | const diff = matchImages(prevImg, img); 145 | if (diff <= opt.diff) { 146 | breakRendering = !breakRendering; 147 | } 148 | } 149 | const number = frameNumber(index, opt.framePadding); 150 | const frame = `${key}-${number}.png`; 151 | 152 | this.saveFrameImage(frame, img); 153 | 154 | prevImg = img; 155 | ++index; 156 | } 157 | await page.close(); 158 | } 159 | } 160 | 161 | export { BitmapsGenerator }; 162 | -------------------------------------------------------------------------------- /bitmapper/packages/core/src/SVGHandler/SvgDirectoryParser.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import path from "path"; 3 | 4 | interface Svg { 5 | key: string; 6 | content: string; 7 | } 8 | 9 | class SvgDirectoryParser { 10 | /** 11 | * Manage and Parse SVG file path in `absolute` fashion. 12 | * This Parser look svg files as below fashion: 13 | * ` 14 | * <@svgDir>/static 15 | * <@svgDir>/animated 16 | * ` 17 | * @param svgDir is relative/absolute path, Where `SVG` files are stored. 18 | */ 19 | semiAnimated: boolean = false; 20 | constructor(private svgDir: string) { 21 | if (!fs.existsSync(this.svgDir)) { 22 | throw new Error(`SVG files not found in ${this.svgDir}`); 23 | } 24 | } 25 | 26 | private readData(f: string): Svg { 27 | const content = fs.readFileSync(f, "utf-8"); 28 | const key = path.basename(f, ".svg"); 29 | return { content, key }; 30 | } 31 | 32 | /** 33 | * Return absolute paths array of SVG files data located inside '@svgDir/static' 34 | */ 35 | public getStatic(): Svg[] { 36 | const staticDir = path.resolve(this.svgDir, "static"); 37 | 38 | if (!fs.existsSync(staticDir)) { 39 | console.log(`${this.svgDir} contains semi-animated .svg files`); 40 | this.semiAnimated = true; 41 | return []; 42 | } else { 43 | const svgs = fs 44 | .readdirSync(staticDir) 45 | .map((f) => this.readData(path.resolve(staticDir, f))); 46 | 47 | if (svgs.length == 0) { 48 | throw new Error("Static Cursors directory is empty"); 49 | } 50 | return svgs; 51 | } 52 | } 53 | /** 54 | * Return absolute paths array of SVG files data located inside '@svgDir/animated' 55 | */ 56 | public getAnimated(): Svg[] { 57 | const animatedDir = path.resolve(this.svgDir, "animated"); 58 | 59 | if (!fs.existsSync(animatedDir)) { 60 | throw new Error("Animated Cursors directory not found"); 61 | } 62 | 63 | const svgs = fs 64 | .readdirSync(animatedDir) 65 | .map((f) => this.readData(path.resolve(animatedDir, f))); 66 | 67 | if (svgs.length == 0 && this.semiAnimated) { 68 | throw new Error( 69 | `Can't parse svg directory ${this.svgDir} as semi-animated theme` 70 | ); 71 | } 72 | 73 | return svgs; 74 | } 75 | } 76 | 77 | export { SvgDirectoryParser }; 78 | -------------------------------------------------------------------------------- /bitmapper/packages/core/src/SVGHandler/colorSvg.ts: -------------------------------------------------------------------------------- 1 | import { Colors } from "../types"; 2 | 3 | /** 4 | * Default Key Colors for generating colored svg. 5 | * base="#00FF00" (Green) 6 | * outline="#0000FF" (Blue) 7 | * watch.background="#FF0000" (Red) 8 | * */ 9 | const defaultKeyColors: Colors = { 10 | base: "#00FF00", 11 | outline: "#0000FF", 12 | watch: { 13 | background: "#FF0000", 14 | }, 15 | }; 16 | 17 | /** 18 | * Customize colors of svg code. 19 | * @param {string} content SVG code. 20 | * @param {Colors} colors Customize colors. 21 | * @param {Colors} [keys] Colors Key, That was written SVG code. 22 | * @returns {string} SVG code with colors. 23 | */ 24 | const colorSvg = ( 25 | content: string, 26 | colors: Colors, 27 | keys: Colors = defaultKeyColors 28 | ): string => { 29 | content = content 30 | .replace(new RegExp(keys.base, "ig"), colors.base) 31 | .replace(new RegExp(keys.outline, "ig"), colors.outline); 32 | 33 | try { 34 | // === trying to replace `watch` color === 35 | 36 | if (!colors.watch?.background) { 37 | throw new Error(""); 38 | } 39 | const { background: b } = colors.watch; 40 | content = content.replace(new RegExp(keys.watch!.background, "ig"), b); // Watch Background 41 | } catch (error) { 42 | // === on error => replace `watch` color as `base` === 43 | 44 | content = content.replace( 45 | new RegExp(keys.watch!.background, "ig"), 46 | colors.base 47 | ); 48 | } 49 | return content; 50 | }; 51 | 52 | export { colorSvg }; 53 | -------------------------------------------------------------------------------- /bitmapper/packages/core/src/SVGHandler/index.ts: -------------------------------------------------------------------------------- 1 | import { colorSvg } from "./colorSvg"; 2 | import { SvgDirectoryParser } from "./SvgDirectoryParser"; 3 | 4 | export { colorSvg, SvgDirectoryParser }; 5 | -------------------------------------------------------------------------------- /bitmapper/packages/core/src/index.ts: -------------------------------------------------------------------------------- 1 | import { BitmapsGenerator } from "./BitmapsGenerator"; 2 | import * as SVGHandler from "./SVGHandler"; 3 | 4 | export { BitmapsGenerator, SVGHandler }; 5 | -------------------------------------------------------------------------------- /bitmapper/packages/core/src/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Hex Colors in string Format. 3 | * 4 | * `Example: `"#FFFFFF" 5 | */ 6 | type HexColor = string; 7 | 8 | /** 9 | * @Colors expect `base`, `outline` & `watch-background` colors in **HexColor** Format. 10 | * @default background is `base` color. 11 | */ 12 | type Colors = { 13 | base: HexColor; 14 | outline: HexColor; 15 | watch?: { 16 | background: HexColor; 17 | }; 18 | }; 19 | 20 | export { Colors }; 21 | -------------------------------------------------------------------------------- /bitmapper/packages/core/src/util/frameNumber.ts: -------------------------------------------------------------------------------- 1 | export const frameNumber = (index: number, padding: number) => { 2 | let result = "" + index; 3 | while (result.length < padding) { 4 | result = "0" + result; 5 | } 6 | return result; 7 | }; 8 | -------------------------------------------------------------------------------- /bitmapper/packages/core/src/util/matchImages.ts: -------------------------------------------------------------------------------- 1 | import Pixelmatch from "pixelmatch"; 2 | import { PNG } from "pngjs"; 3 | 4 | export const matchImages = (img1: Buffer, img2: Buffer): number => { 5 | const { data: img1Data, width, height } = PNG.sync.read(img1); 6 | const { data: imgNData } = PNG.sync.read(img2); 7 | 8 | return Pixelmatch(img1Data, imgNData, null, width, height, { 9 | threshold: 0.1, 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /bitmapper/packages/core/src/util/toHTML.ts: -------------------------------------------------------------------------------- 1 | export const template = ` 2 | 3 | 4 | 5 | 6 | 7 | Render Template 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 | 16 | `; 17 | 18 | export const toHTML = (svgData: string): string => 19 | template.replace("", svgData); 20 | -------------------------------------------------------------------------------- /bitmapper/packages/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "declarationMap": true, 6 | "sourceMap": true, 7 | "composite": true, 8 | "outDir": "dist", 9 | "rootDir": "src" 10 | }, 11 | "include": ["src"] 12 | } 13 | -------------------------------------------------------------------------------- /bitmapper/packages/modern/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bibata-modern", 3 | "version": "1.0.0", 4 | "description": "Rounded edges bibata cursors", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "build": "npx tsc --build", 8 | "render": "yarn build && node dist/index.js" 9 | }, 10 | "author": "Kaiz Khatri", 11 | "license": "GPL-3.0", 12 | "private": true, 13 | "devDependencies": { 14 | "ts-node": "^9.1.1", 15 | "typescript": "^4.1.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /bitmapper/packages/modern/src/config.ts: -------------------------------------------------------------------------------- 1 | import { Colors } from "bibata-core/src/types"; 2 | 3 | interface Config { 4 | themeName: string; 5 | color: Colors; 6 | } 7 | 8 | const white = "#FFFFFF"; 9 | const black = "#000000"; 10 | const darkRed = "#B20000"; 11 | const dodgerBlue = "#5848FF"; 12 | const pink = "#FE009E"; 13 | const turquoise = "#00F0B7"; 14 | 15 | const config: Config[] = [ 16 | { 17 | themeName: "Bibata-Modern-DarkRed", 18 | color: { 19 | base: darkRed, 20 | outline: white, 21 | watch: { 22 | background: black, 23 | }, 24 | }, 25 | }, 26 | { 27 | themeName: "Bibata-Modern-DodgerBlue", 28 | color: { 29 | base: dodgerBlue, 30 | outline: white, 31 | watch: { 32 | background: black, 33 | }, 34 | }, 35 | }, 36 | { 37 | themeName: "Bibata-Modern-Turquoise", 38 | color: { 39 | base: turquoise, 40 | outline: white, 41 | watch: { 42 | background: black, 43 | }, 44 | }, 45 | }, 46 | { 47 | themeName: "Bibata-Modern-Pink", 48 | color: { 49 | base: pink, 50 | outline: white, 51 | watch: { 52 | background: black, 53 | }, 54 | }, 55 | }, 56 | ]; 57 | 58 | export { config }; 59 | -------------------------------------------------------------------------------- /bitmapper/packages/modern/src/index.ts: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | 3 | import { BitmapsGenerator, SVGHandler } from "bibata-core"; 4 | import { config } from "./config"; 5 | 6 | const root = path.resolve(__dirname, "../../../../"); 7 | const svgDir = path.resolve(root, "svg", "modern"); 8 | 9 | const main = async () => { 10 | for (const { themeName, color } of config) { 11 | console.log("Generating bitmaps for", themeName); 12 | 13 | const bitmapsDir = path.resolve(root, "bitmaps", themeName); 14 | const svg = new SVGHandler.SvgDirectoryParser(svgDir); 15 | 16 | const png = new BitmapsGenerator(bitmapsDir); 17 | const browser = await png.getBrowser(); 18 | 19 | for (let { key, content } of svg.getStatic()) { 20 | console.log(" ==> Saving", key, "..."); 21 | 22 | content = SVGHandler.colorSvg(content, color); 23 | await png.generateStatic(browser, content, key); 24 | } 25 | 26 | for (let { key, content } of svg.getAnimated()) { 27 | console.log(" ==> Saving", key, "..."); 28 | 29 | content = SVGHandler.colorSvg(content, color); 30 | await png.generateAnimated(browser, content, key); 31 | } 32 | 33 | await browser.close(); 34 | } 35 | }; 36 | 37 | main(); 38 | -------------------------------------------------------------------------------- /bitmapper/packages/modern/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "references": [{ "path": "../core" }], 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "rootDir": "src", 6 | "outDir": "dist" 7 | }, 8 | "include": ["src"] 9 | } 10 | -------------------------------------------------------------------------------- /bitmapper/packages/original/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bibata-original", 3 | "version": "1.0.0", 4 | "description": "Sharp edges bibata cursors", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "build": "npx tsc --build", 8 | "render": "yarn build && node dist/index.js" 9 | }, 10 | "author": "Kaiz Khatri", 11 | "license": "GPL-3.0", 12 | "private": true, 13 | "devDependencies": { 14 | "ts-node": "^9.1.1", 15 | "typescript": "^4.1.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /bitmapper/packages/original/src/config.ts: -------------------------------------------------------------------------------- 1 | import { Colors } from "bibata-core/src/types"; 2 | 3 | interface Config { 4 | themeName: string; 5 | color: Colors; 6 | } 7 | 8 | const white = "#FFFFFF"; 9 | const black = "#000000"; 10 | const darkRed = "#B20000"; 11 | const dodgerBlue = "#5848FF"; 12 | const pink = "#FE009E"; 13 | const turquoise = "#00F0B7"; 14 | 15 | const config: Config[] = [ 16 | { 17 | themeName: "Bibata-Original-DarkRed", 18 | color: { 19 | base: darkRed, 20 | outline: white, 21 | watch: { 22 | background: black, 23 | }, 24 | }, 25 | }, 26 | { 27 | themeName: "Bibata-Original-DodgerBlue", 28 | color: { 29 | base: dodgerBlue, 30 | outline: white, 31 | watch: { 32 | background: black, 33 | }, 34 | }, 35 | }, 36 | { 37 | themeName: "Bibata-Original-Turquoise", 38 | color: { 39 | base: turquoise, 40 | outline: white, 41 | watch: { 42 | background: black, 43 | }, 44 | }, 45 | }, 46 | { 47 | themeName: "Bibata-Original-Pink", 48 | color: { 49 | base: pink, 50 | outline: white, 51 | watch: { 52 | background: black, 53 | }, 54 | }, 55 | }, 56 | ]; 57 | 58 | export { config }; 59 | -------------------------------------------------------------------------------- /bitmapper/packages/original/src/index.ts: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | 3 | import { BitmapsGenerator, SVGHandler } from "bibata-core"; 4 | import { config } from "./config"; 5 | 6 | const root = path.resolve(__dirname, "../../../../"); 7 | const svgDir = path.resolve(root, "svg", "original"); 8 | 9 | const main = async () => { 10 | for (const { themeName, color } of config) { 11 | console.log("Generating bitmaps for", themeName); 12 | 13 | const bitmapsDir = path.resolve(root, "bitmaps", themeName); 14 | const svg = new SVGHandler.SvgDirectoryParser(svgDir); 15 | 16 | const png = new BitmapsGenerator(bitmapsDir); 17 | const browser = await png.getBrowser(); 18 | 19 | for (let { key, content } of svg.getStatic()) { 20 | console.log(" ==> Saving", key, "..."); 21 | 22 | content = SVGHandler.colorSvg(content, color); 23 | await png.generateStatic(browser, content, key); 24 | } 25 | 26 | for (let { key, content } of svg.getAnimated()) { 27 | console.log(" ==> Saving", key, "..."); 28 | 29 | content = SVGHandler.colorSvg(content, color); 30 | await png.generateAnimated(browser, content, key); 31 | } 32 | 33 | await browser.close(); 34 | } 35 | }; 36 | 37 | main(); 38 | -------------------------------------------------------------------------------- /bitmapper/packages/original/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "references": [{ "path": "../core" }], 3 | "extends": "../../tsconfig.json", 4 | "compilerOptions": { 5 | "rootDir": "src", 6 | "outDir": "dist" 7 | }, 8 | "include": ["src"] 9 | } 10 | -------------------------------------------------------------------------------- /bitmapper/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "commonjs", 5 | "lib": ["es2015", "dom"], 6 | "strict": true, 7 | "typeRoots": ["./node_modules/@types"], 8 | "noUnusedLocals": true, 9 | "noUnusedParameters": true, 10 | "noImplicitReturns": true, 11 | "resolveJsonModule": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "esModuleInterop": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /builder/Makefile: -------------------------------------------------------------------------------- 1 | all: setup build 2 | 3 | bitmaps_dir = "../bitmaps" 4 | 5 | .PHONY: all 6 | 7 | .ONESHELL: 8 | SHELL:=/bin/bash 9 | 10 | THEMES = DarkRed DodgerBlue Pink Turquoise 11 | X_SIZES ?= 22 24 28 32 40 48 56 64 72 80 88 96 12 | WIN_CANVAS_SIZE ?= 32 13 | WIN_SIZE ?= 24 14 | 15 | setup: 16 | @python3 -m pip install clickgen --user 17 | 18 | build: build_modern build_original 19 | 20 | build_modern: build.py 21 | @$(foreach theme,$(THEMES), python3 build.py -p "$(bitmaps_dir)/Bibata-Modern-$(theme)" --xsizes $(X_SIZES) --win-size $(WIN_SIZE) --win-canvas-size $(WIN_CANVAS_SIZE);) 22 | 23 | build_original: build.py 24 | @$(foreach theme,$(THEMES), python3 build.py -p "$(bitmaps_dir)/Bibata-Original-$(theme)" --xsizes $(X_SIZES) --win-size $(WIN_SIZE) --win-canvas-size $(WIN_CANVAS_SIZE);) 25 | 26 | 27 | build_unix: build_modern_unix build_original_unix 28 | 29 | build_modern_unix: build.py 30 | @$(foreach theme,$(THEMES), python3 build.py unix -p "$(bitmaps_dir)/Bibata-Modern-$(theme)" --xsizes $(X_SIZES);) 31 | 32 | build_original_unix: build.py 33 | @$(foreach theme,$(THEMES), python3 build.py unix -p "$(bitmaps_dir)/Bibata-Original-$(theme)" --xsizes $(X_SIZES);) 34 | 35 | 36 | build_windows: build_modern_windows build_original_windows 37 | 38 | build_modern_windows: build.py 39 | @$(foreach theme,$(THEMES), python3 build.py windows -p "$(bitmaps_dir)/Bibata-Modern-$(theme)" --win-size $(WIN_SIZE) --win-canvas-size $(WIN_CANVAS_SIZE);) 40 | 41 | build_original_windows: build.py 42 | @$(foreach theme,$(THEMES), python3 build.py windows -p "$(bitmaps_dir)/Bibata-Original-$(theme)" --win-size $(WIN_SIZE) --win-canvas-size $(WIN_CANVAS_SIZE);) 43 | -------------------------------------------------------------------------------- /builder/build.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import argparse 5 | from pathlib import Path 6 | 7 | from src.configure import get_config 8 | from src.generator import Info, xbuild, wbuild, build 9 | 10 | 11 | parser = argparse.ArgumentParser( 12 | prog="bibata_builder", 13 | description="'Bibata' cursor build python script.", 14 | ) 15 | 16 | # Positional Args. 17 | parser.add_argument( 18 | "platform", 19 | choices=("windows", "unix", "all"), 20 | default="all", 21 | const="all", 22 | nargs="?", 23 | help="Set package type, Which you want to build. (default: '%(default)s')", 24 | ) 25 | 26 | # Optional Args. 27 | parser.add_argument( 28 | "-p", 29 | "--png-dir", 30 | dest="png_dir", 31 | metavar="PNG", 32 | type=str, 33 | default="../bitmaps", 34 | help="To change pngs directory. (default: %(default)s)", 35 | ) 36 | 37 | parser.add_argument( 38 | "-o", 39 | "--out-dir", 40 | dest="out_dir", 41 | metavar="OUT", 42 | type=str, 43 | default="../themes", 44 | help="To change output directory. (default: %(default)s)", 45 | ) 46 | 47 | 48 | parser.add_argument( 49 | "-xs", 50 | "--xsizes", 51 | dest="xsizes", 52 | metavar="INT", 53 | nargs="+", 54 | default=[ 55 | 22, 56 | 24, 57 | 28, 58 | 32, 59 | 40, 60 | 48, 61 | 56, 62 | 64, 63 | 72, 64 | 80, 65 | 88, 66 | 96, 67 | ], 68 | type=int, 69 | help="Set pixel-size for xcursor. (default: %(default)s)", 70 | ) 71 | 72 | 73 | parser.add_argument( 74 | "-ws", 75 | "--win-size", 76 | dest="win_size", 77 | metavar="INT", 78 | default=24, 79 | type=int, 80 | help="Set pixel-size for Windows cursors. (default: %(default)s)", 81 | ) 82 | 83 | 84 | parser.add_argument( 85 | "-wcs", 86 | "--win-canvas-size", 87 | dest="win_canvas_size", 88 | metavar="INT", 89 | default=32, 90 | type=int, 91 | help="Set pixel-size for Windows cursor's canvas. (default: %(default)s)", 92 | ) 93 | 94 | # Preparing build 95 | args = parser.parse_args() 96 | 97 | bitmaps_dir = Path(args.png_dir).absolute() 98 | name = bitmaps_dir.stem 99 | 100 | x_out_dir = Path(args.out_dir) / name 101 | win_out_dir = Path(args.out_dir) / f"{name}-Windows" 102 | 103 | print(f"Getting '{name}' bitmaps ready for build...") 104 | 105 | config = get_config( 106 | bitmaps_dir, 107 | x_sizes=args.xsizes, 108 | win_canvas_size=args.win_canvas_size, 109 | win_size=args.win_size, 110 | ) 111 | 112 | info = Info(name=name, comment=f"{name.replace('-',' ')} Cursors") 113 | 114 | if args.platform == "unix": 115 | xbuild(config, x_out_dir, info) 116 | elif args.platform == "windows": 117 | wbuild(config, win_out_dir, info) 118 | else: 119 | build(config, x_out_dir, win_out_dir, info) 120 | -------------------------------------------------------------------------------- /builder/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ful1e5/Bibata_Extra_Cursor/5643465bf904e2901ece66d4cb2062141c52394d/builder/src/__init__.py -------------------------------------------------------------------------------- /builder/src/configure.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from pathlib import Path 5 | from typing import Any, Dict, Tuple, TypeVar, Union 6 | 7 | from clickgen.util import PNGProvider 8 | 9 | from .constants import WIN_CURSORS_CFG, WIN_DELAY, X_CURSORS_CFG, X_DELAY 10 | 11 | X = TypeVar("X") 12 | 13 | 14 | def to_tuple(x: X) -> Tuple[X, X]: 15 | return (x, x) 16 | 17 | 18 | def get_config(bitmaps_dir: Union[str, Path], **kwargs) -> Dict[str, Any]: 19 | """Return configuration of `Bibata-Extra` pointers. 20 | 21 | :param bitmaps_dir: Path to .png file's directory. 22 | :type bitmaps_dir: ``str`` or ``pathlib.Path`` 23 | 24 | :param **kwargs: 25 | See below 26 | 27 | :Keyword Arguments: 28 | * *x_sizes* (``List[int]``) -- 29 | List of pixel-sizes for xcursors. 30 | * *win_canvas_size* (``int``) -- 31 | Windows cursor's canvas pixel-size. 32 | * *win_size* (``int``) -- 33 | Pixel-size for Windows cursor. 34 | 35 | Example: 36 | 37 | ```python 38 | get_config( 39 | bitmaps_dir="./bitmaps", 40 | x_sizes=[24, 28, 32], 41 | win_canvas_size=32, 42 | win_size=24, 43 | ) 44 | ``` 45 | """ 46 | 47 | w_size = to_tuple(kwargs.pop("win_size")) 48 | w_canvas_size = to_tuple(kwargs.pop("win_canvas_size")) 49 | raw_x_sizes = kwargs.pop("x_sizes") 50 | x_sizes = [to_tuple(size) for size in raw_x_sizes] 51 | config: Dict[str, Any] = {} 52 | 53 | for key, item in X_CURSORS_CFG.items(): 54 | x_hot: int = int(item.get("xhot", 0)) 55 | y_hot: int = int(item.get("yhot", 0)) 56 | hotspot: Tuple[int, int] = (x_hot, y_hot) 57 | 58 | delay: int = int(item.get("delay", X_DELAY)) 59 | pngs = PNGProvider(bitmaps_dir).get(key) 60 | 61 | if not pngs: 62 | raise FileNotFoundError(f"{key} not found in {bitmaps_dir}") 63 | 64 | data = { 65 | "png": pngs, 66 | "x_sizes": x_sizes, 67 | "hotspot": hotspot, 68 | "delay": delay, 69 | } 70 | 71 | win_data = WIN_CURSORS_CFG.get(key) 72 | 73 | if win_data: 74 | win_key: str = str(win_data.get("to")) 75 | 76 | position: str = str(win_data.get("position", "center")) 77 | win_delay: int = int(win_data.get("delay", WIN_DELAY)) 78 | 79 | canvas_size = win_data.get("canvas_size", w_canvas_size) 80 | win_size = win_data.get("size", w_size) 81 | 82 | # Because provided cursor size is bigger than cursor's canvas. 83 | # Also, "position" settings will not effect on cursor because the 84 | # cursor's canvas and cursor sizes are equals. 85 | if (win_size[0] > canvas_size[0]) | (win_size[1] > canvas_size[1]): 86 | canvas_size = win_size 87 | 88 | config[key] = { 89 | **data, 90 | "win_key": win_key, 91 | "position": position, 92 | "canvas_size": canvas_size, 93 | "win_size": win_size, 94 | "win_delay": win_delay, 95 | } 96 | else: 97 | config[key] = data 98 | 99 | return config 100 | -------------------------------------------------------------------------------- /builder/src/constants.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from typing import Dict 5 | 6 | # Info 7 | AUTHOR = "Kaiz Khatri" 8 | URL = "https://github.com/ful1e5/Bibata_Extra_Cursor" 9 | 10 | # XCursor 11 | X_DELAY: int = 13 12 | 13 | # Windows Cursor 14 | WIN_DELAY = 1 15 | 16 | X_CURSORS_CFG: Dict[str, Dict[str, int]] = { 17 | ########## 18 | # Static # 19 | ########## 20 | "bd_double_arrow.png": {"xhot": 98, "yhot": 100}, 21 | "bottom_left_corner.png": {"xhot": 31, "yhot": 172}, 22 | "bottom_right_corner.png": {"xhot": 170, "yhot": 172}, 23 | "bottom_side.png": {"xhot": 100, "yhot": 164}, 24 | "bottom_tee.png": {"xhot": 100, "yhot": 164}, 25 | "center_ptr.png": {"xhot": 98, "yhot": 131}, 26 | "circle.png": {"xhot": 48, "yhot": 25}, 27 | "context-menu.png": {"xhot": 48, "yhot": 25}, 28 | "copy.png": {"xhot": 48, "yhot": 25}, 29 | "cross.png": {"xhot": 98, "yhot": 96}, 30 | "crossed_circle.png": {"xhot": 100, "yhot": 100}, 31 | "crosshair.png": {"xhot": 99, "yhot": 99}, 32 | "dnd_no_drop.png": {"xhot": 86, "yhot": 79}, 33 | "dnd-ask.png": {"xhot": 86, "yhot": 79}, 34 | "dnd-copy.png": {"xhot": 86, "yhot": 79}, 35 | "dnd-link.png": {"xhot": 86, "yhot": 79}, 36 | "dnd-move.png": {"xhot": 86, "yhot": 79}, 37 | "dotbox.png": {"xhot": 100, "yhot": 100}, 38 | "fd_double_arrow.png": {"xhot": 98, "yhot": 100}, 39 | "grabbing.png": {"xhot": 106, "yhot": 79}, 40 | "hand1.png": {"xhot": 113, "yhot": 95}, 41 | "hand2.png": {"xhot": 88, "yhot": 32}, 42 | "left_ptr.png": {"xhot": 53, "yhot": 36}, 43 | "left_side.png": {"xhot": 35, "yhot": 100}, 44 | "left_tee.png": {"xhot": 165, "yhot": 95}, 45 | "link.png": {"xhot": 48, "yhot": 25}, 46 | "ll_angle.png": {"xhot": 34, "yhot": 165}, 47 | "lr_angle.png": {"xhot": 167, "yhot": 164}, 48 | "move.png": {"xhot": 100, "yhot": 100}, 49 | "pencil.png": {"xhot": 37, "yhot": 161}, 50 | "plus.png": {"xhot": 100, "yhot": 100}, 51 | "pointer-move.png": {"xhot": 48, "yhot": 25}, 52 | "question_arrow.png": {"xhot": 102, "yhot": 102}, 53 | "right_ptr.png": {"xhot": 150, "yhot": 29}, 54 | "right_side.png": {"xhot": 163, "yhot": 98}, 55 | "right_tee.png": {"xhot": 30, "yhot": 96}, 56 | "sb_down_arrow.png": {"xhot": 100, "yhot": 126}, 57 | "sb_h_double_arrow.png": {"xhot": 100, "yhot": 100}, 58 | "sb_left_arrow.png": {"xhot": 86, "yhot": 100}, 59 | "sb_right_arrow.png": {"xhot": 113, "yhot": 100}, 60 | "sb_up_arrow.png": {"xhot": 99, "yhot": 86}, 61 | "sb_v_double_arrow.png": {"xhot": 100, "yhot": 100}, 62 | "tcross.png": {"xhot": 98, "yhot": 100}, 63 | "top_left_corner.png": {"xhot": 29, "yhot": 27}, 64 | "top_right_corner.png": {"xhot": 170, "yhot": 28}, 65 | "top_side.png": {"xhot": 98, "yhot": 34}, 66 | "top_tee.png": {"xhot": 98, "yhot": 29}, 67 | "ul_angle.png": {"xhot": 34, "yhot": 35}, 68 | "ur_angle.png": {"xhot": 164, "yhot": 34}, 69 | "vertical-text.png": {"xhot": 100, "yhot": 100}, 70 | "wayland-cursor.png": {"xhot": 100, "yhot": 100}, 71 | "X_cursor.png": {"xhot": 100, "yhot": 100}, 72 | "xterm.png": {"xhot": 100, "yhot": 100}, 73 | "zoom-in.png": {"xhot": 90, "yhot": 89}, 74 | "zoom-out.png": {"xhot": 93, "yhot": 90}, 75 | ############ 76 | # Animated # 77 | ############ 78 | # Note: Animated cursors don't need an extension and frame numbers. 79 | "left_ptr_watch": {"xhot": 50, "yhot": 28}, 80 | "wait": {"xhot": 100, "yhot": 100}, 81 | } 82 | 83 | WIN_CURSORS_CFG: Dict[str, Dict[str, str]] = { 84 | ########## 85 | # Static # 86 | ########## 87 | "right_ptr.png": {"to": "Alternate", "position": "top_left"}, 88 | "cross.png": {"to": "Cross"}, 89 | "left_ptr.png": {"to": "Default", "position": "top_left"}, 90 | "bd_double_arrow.png": {"to": "Diagonal_1"}, 91 | "fd_double_arrow.png": {"to": "Diagonal_2"}, 92 | "pencil.png": {"to": "Handwriting"}, 93 | "question_arrow.png": {"to": "Help", "position.png": "top_left"}, 94 | "sb_h_double_arrow.png": {"to": "Horizontal"}, 95 | "xterm.png": {"to": "IBeam", "position": "top_left"}, 96 | "hand2.png": {"to": "Link", "position": "top_left"}, 97 | "hand1.png": {"to": "Move"}, 98 | "circle.png": {"to": "Unavailiable", "position": "top_left"}, 99 | "sb_v_double_arrow.png": {"to": "Vertical"}, 100 | ############ 101 | # Animated # 102 | ############ 103 | # Note: Animated cursors don't need frame numbers. 104 | "left_ptr_watch": {"to": "Work", "position": "top_left"}, 105 | "wait": {"to": "Busy"}, 106 | } 107 | -------------------------------------------------------------------------------- /builder/src/generator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from pathlib import Path 5 | from typing import Any, Dict, NamedTuple 6 | 7 | from clickgen.builders import WindowsCursor, XCursor 8 | from clickgen.core import CursorAlias 9 | from clickgen.packagers import WindowsPackager, XPackager 10 | 11 | from .constants import AUTHOR, URL 12 | from .symlinks import add_missing_xcursor 13 | 14 | 15 | class Info(NamedTuple): 16 | """Theme basic information. 17 | 18 | :param name: Theme title. 19 | :type name: ``str`` 20 | 21 | :param comment: quick information about theme. 22 | :type comment: ``str`` 23 | """ 24 | 25 | name: str 26 | comment: str 27 | 28 | 29 | def xbuild(config: Dict[str, Dict[str, Any]], x_out_dir: Path, info: Info) -> None: 30 | """Build `Bibata-Extra` cursor theme for only `X11`(UNIX) platform. 31 | 32 | :param config: `Bibata-Extra` configuration. 33 | :type config: ``Dict`` 34 | 35 | :param x_out_dir: Path to the output directory,\ 36 | Where the `X11` cursor theme package will generate.\ 37 | It also creates a directory if not exists. 38 | :type x_out_dir: ``pathlib.Path`` 39 | 40 | :param info: Content theme name & comment. 41 | :type info: Info 42 | """ 43 | 44 | for _, item in config.items(): 45 | with CursorAlias.from_bitmap(item["png"], item["hotspot"]) as alias: 46 | x_cfg = alias.create(item["x_sizes"], item["delay"]) 47 | 48 | print(f"Building '{x_cfg.stem}' XCursor...") 49 | XCursor.create(x_cfg, x_out_dir) 50 | 51 | add_missing_xcursor(x_out_dir / "cursors") 52 | XPackager(x_out_dir, info.name, info.comment) 53 | 54 | 55 | def wbuild(config: Dict[str, Dict[str, Any]], win_out_dir: Path, info: Info) -> None: 56 | """Build `Bibata-Extra` cursor theme for only `Windows` platforms. 57 | 58 | :param config: `Bibata-Extra` configuration. 59 | :type config: ``Dict`` 60 | 61 | :param win_out_dir: Path to the output directory,\ 62 | Where the `Windows` cursor theme package will generate.\ 63 | It also creates a directory if not exists. 64 | :type win_out_dir: ``pathlib.Path`` 65 | 66 | :param info: Content theme name & comment. 67 | :type info: Info 68 | """ 69 | 70 | for _, item in config.items(): 71 | with CursorAlias.from_bitmap(item["png"], item["hotspot"]) as alias: 72 | alias.create(item["x_sizes"], item["delay"]) 73 | 74 | if item.get("win_key"): 75 | win_cfg = alias.reproduce( 76 | item["win_size"], 77 | item["canvas_size"], 78 | item["position"], 79 | delay=item["win_delay"], 80 | ).rename(item["win_key"]) 81 | 82 | print(f"Building '{win_cfg.stem}' Windows Cursor...") 83 | WindowsCursor.create(win_cfg, win_out_dir) 84 | 85 | WindowsPackager(win_out_dir, info.name, info.comment, AUTHOR, URL) 86 | 87 | 88 | def build( 89 | config: Dict[str, Dict[str, Any]], x_out_dir: Path, win_out_dir: Path, info: Info 90 | ) -> None: 91 | """Build `Bibata-Extra` cursor theme for `X11` & `Windows` platforms. 92 | 93 | :param config: `Bibata-Extra` configuration. 94 | :type config: ``Dict`` 95 | 96 | :param x_out_dir: Path to the output directory,\ 97 | Where the `X11` cursor theme package will generate.\ 98 | It also creates a directory if not exists. 99 | :type x_out_dir: ``pathlib.Path`` 100 | 101 | :param win_out_dir: Path to the output directory,\ 102 | Where the `Windows` cursor theme package will generate.\ 103 | It also creates a directory if not exists. 104 | :type win_out_dir: ``pathlib.Path`` 105 | 106 | :param info: Content theme name & comment. 107 | :type info: Info 108 | """ 109 | 110 | for _, item in config.items(): 111 | 112 | with CursorAlias.from_bitmap(item["png"], item["hotspot"]) as alias: 113 | x_cfg = alias.create(item["x_sizes"], item["delay"]) 114 | 115 | print(f"Building '{x_cfg.stem}' XCursor...") 116 | XCursor.create(x_cfg, x_out_dir) 117 | 118 | if item.get("win_key"): 119 | win_cfg = alias.reproduce( 120 | item["win_size"], 121 | item["canvas_size"], 122 | item["position"], 123 | delay=item["win_delay"], 124 | ).rename(item["win_key"]) 125 | 126 | print(f"Building '{win_cfg.stem}' Windows Cursor...") 127 | WindowsCursor.create(win_cfg, win_out_dir) 128 | 129 | add_missing_xcursor(x_out_dir / "cursors") 130 | XPackager(x_out_dir, info.name, info.comment) 131 | 132 | WindowsPackager(win_out_dir, info.name, info.comment, AUTHOR, URL) 133 | -------------------------------------------------------------------------------- /pyrightconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["builder", "svg"], 3 | "exclude": ["**/node_modules", "**/__pycache__"], 4 | 5 | "reportMissingImports": true, 6 | "reportMissingTypeStubs": false, 7 | 8 | "pythonVersion": "3.9", 9 | "pythonPlatform": "Linux", 10 | 11 | "executionEnvironments": [{ "root": "builder" }] 12 | } 13 | -------------------------------------------------------------------------------- /svg/link.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import os 4 | from glob import glob 5 | 6 | ignore_files = [ 7 | # animated 8 | "left_ptr_watch.svg", 9 | # static 10 | "center_ptr.svg", 11 | "circle.svg", 12 | "context-menu.svg", 13 | "copy.svg", 14 | "left_ptr.svg", 15 | "link.svg", 16 | "pointer-move.svg", 17 | "right_ptr.svg", 18 | ] 19 | 20 | 21 | def link_svg_dir(src_dir, dst_dir) -> None: 22 | for src_path in glob(f"{src_dir}/*"): 23 | file_name = os.path.basename(src_path) 24 | if file_name not in ignore_files: 25 | dst = os.path.join(dst_dir, file_name) 26 | if os.path.exists(dst): 27 | print(f"Removing old symlink of '{file_name}'") 28 | os.remove(dst) 29 | print(f"Creating symlink of '{file_name}'") 30 | os.symlink( 31 | os.path.relpath(src_path, f"{dst_dir}/"), 32 | dst, 33 | ) 34 | else: 35 | print(f"Ignoring file '{file_name}'") 36 | 37 | 38 | link_svg_dir("original/static", "modern/static") 39 | link_svg_dir("original/animated", "modern/animated") 40 | -------------------------------------------------------------------------------- /svg/modern/animated/left_ptr_watch.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /svg/modern/animated/wait.svg: -------------------------------------------------------------------------------- 1 | ../../original/animated/wait.svg -------------------------------------------------------------------------------- /svg/modern/static/X_cursor.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/X_cursor.svg -------------------------------------------------------------------------------- /svg/modern/static/bd_double_arrow.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/bd_double_arrow.svg -------------------------------------------------------------------------------- /svg/modern/static/bottom_left_corner.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/bottom_left_corner.svg -------------------------------------------------------------------------------- /svg/modern/static/bottom_right_corner.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/bottom_right_corner.svg -------------------------------------------------------------------------------- /svg/modern/static/bottom_side.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/bottom_side.svg -------------------------------------------------------------------------------- /svg/modern/static/bottom_tee.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/bottom_tee.svg -------------------------------------------------------------------------------- /svg/modern/static/center_ptr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/modern/static/circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /svg/modern/static/context-menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /svg/modern/static/copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /svg/modern/static/cross.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/cross.svg -------------------------------------------------------------------------------- /svg/modern/static/crossed_circle.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/crossed_circle.svg -------------------------------------------------------------------------------- /svg/modern/static/crosshair.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/crosshair.svg -------------------------------------------------------------------------------- /svg/modern/static/dnd-ask.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/dnd-ask.svg -------------------------------------------------------------------------------- /svg/modern/static/dnd-copy.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/dnd-copy.svg -------------------------------------------------------------------------------- /svg/modern/static/dnd-link.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/dnd-link.svg -------------------------------------------------------------------------------- /svg/modern/static/dnd-move.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/dnd-move.svg -------------------------------------------------------------------------------- /svg/modern/static/dnd_no_drop.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/dnd_no_drop.svg -------------------------------------------------------------------------------- /svg/modern/static/dotbox.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/dotbox.svg -------------------------------------------------------------------------------- /svg/modern/static/fd_double_arrow.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/fd_double_arrow.svg -------------------------------------------------------------------------------- /svg/modern/static/grabbing.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/grabbing.svg -------------------------------------------------------------------------------- /svg/modern/static/hand1.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/hand1.svg -------------------------------------------------------------------------------- /svg/modern/static/hand2.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/hand2.svg -------------------------------------------------------------------------------- /svg/modern/static/left_ptr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/modern/static/left_side.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/left_side.svg -------------------------------------------------------------------------------- /svg/modern/static/left_tee.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/left_tee.svg -------------------------------------------------------------------------------- /svg/modern/static/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /svg/modern/static/ll_angle.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/ll_angle.svg -------------------------------------------------------------------------------- /svg/modern/static/lr_angle.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/lr_angle.svg -------------------------------------------------------------------------------- /svg/modern/static/move.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/move.svg -------------------------------------------------------------------------------- /svg/modern/static/pencil.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/pencil.svg -------------------------------------------------------------------------------- /svg/modern/static/plus.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/plus.svg -------------------------------------------------------------------------------- /svg/modern/static/pointer-move.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /svg/modern/static/question_arrow.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/question_arrow.svg -------------------------------------------------------------------------------- /svg/modern/static/right_ptr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/modern/static/right_side.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/right_side.svg -------------------------------------------------------------------------------- /svg/modern/static/right_tee.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/right_tee.svg -------------------------------------------------------------------------------- /svg/modern/static/sb_down_arrow.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/sb_down_arrow.svg -------------------------------------------------------------------------------- /svg/modern/static/sb_h_double_arrow.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/sb_h_double_arrow.svg -------------------------------------------------------------------------------- /svg/modern/static/sb_left_arrow.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/sb_left_arrow.svg -------------------------------------------------------------------------------- /svg/modern/static/sb_right_arrow.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/sb_right_arrow.svg -------------------------------------------------------------------------------- /svg/modern/static/sb_up_arrow.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/sb_up_arrow.svg -------------------------------------------------------------------------------- /svg/modern/static/sb_v_double_arrow.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/sb_v_double_arrow.svg -------------------------------------------------------------------------------- /svg/modern/static/tcross.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/tcross.svg -------------------------------------------------------------------------------- /svg/modern/static/top_left_corner.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/top_left_corner.svg -------------------------------------------------------------------------------- /svg/modern/static/top_right_corner.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/top_right_corner.svg -------------------------------------------------------------------------------- /svg/modern/static/top_side.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/top_side.svg -------------------------------------------------------------------------------- /svg/modern/static/top_tee.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/top_tee.svg -------------------------------------------------------------------------------- /svg/modern/static/ul_angle.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/ul_angle.svg -------------------------------------------------------------------------------- /svg/modern/static/ur_angle.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/ur_angle.svg -------------------------------------------------------------------------------- /svg/modern/static/vertical-text.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/vertical-text.svg -------------------------------------------------------------------------------- /svg/modern/static/wayland-cursor.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/wayland-cursor.svg -------------------------------------------------------------------------------- /svg/modern/static/xterm.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/xterm.svg -------------------------------------------------------------------------------- /svg/modern/static/zoom-in.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/zoom-in.svg -------------------------------------------------------------------------------- /svg/modern/static/zoom-out.svg: -------------------------------------------------------------------------------- 1 | ../../original/static/zoom-out.svg -------------------------------------------------------------------------------- /svg/original/animated/left_ptr_watch.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /svg/original/animated/wait.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /svg/original/static/X_cursor.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/original/static/bd_double_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/original/static/bottom_left_corner.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/bottom_right_corner.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/bottom_side.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /svg/original/static/bottom_tee.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/center_ptr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/original/static/circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /svg/original/static/context-menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /svg/original/static/copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /svg/original/static/cross.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/crossed_circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /svg/original/static/crosshair.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/dnd-ask.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /svg/original/static/dnd-copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /svg/original/static/dnd_no_drop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /svg/original/static/dotbox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/fd_double_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/original/static/grabbing.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/original/static/hand1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/original/static/hand2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/original/static/left_ptr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /svg/original/static/left_side.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /svg/original/static/left_tee.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /svg/original/static/ll_angle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/original/static/lr_angle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/original/static/pencil.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/plus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /svg/original/static/pointer-move.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /svg/original/static/question_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/right_ptr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /svg/original/static/right_side.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /svg/original/static/right_tee.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/sb_down_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/sb_h_double_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/original/static/sb_left_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/sb_right_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/sb_up_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/sb_v_double_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /svg/original/static/tcross.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/top_left_corner.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/top_right_corner.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/top_side.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /svg/original/static/top_tee.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /svg/original/static/ul_angle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/original/static/ur_angle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/original/static/vertical-text.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/original/static/xterm.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /svg/original/static/zoom-in.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /svg/original/static/zoom-out.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | --------------------------------------------------------------------------------