[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[micro.json]\nindent_size = 4\n"
  },
  {
    "path": ".gitignore",
    "content": "secrets.env\n"
  },
  {
    "path": ".oxfmtrc.json",
    "content": "{\n  \"arrowParens\": \"avoid\",\n  \"jsxSingleQuote\": false,\n  \"quoteProps\": \"consistent\",\n  \"semi\": false,\n  \"singleQuote\": true,\n  \"sortImports\": {\n    \"groups\": [\n      \"side_effect\",\n      \"side_effect_style\",\n      \"style\",\n      [\"builtin\", \"external\", \"unknown\"],\n      [\"internal\", \"parent\", \"sibling\", \"index\"]\n    ],\n    \"newlinesBetween\": true,\n    \"order\": \"asc\"\n  },\n  \"trailingComma\": \"none\",\n  \"printWidth\": 80\n}\n"
  },
  {
    "path": "GNOME.md",
    "content": "## GNOME Shell Extensions\n\n- [All-in-One Clipboard](https://extensions.gnome.org/extension/8671/all-in-one-clipboard/)\n- [Alphabetical App Grid](https://extensions.gnome.org/extension/4269/alphabetical-app-grid/)\n- [App Hider](https://extensions.gnome.org/extension/5895/app-hider/)\n- [Auto Power Profile](https://extensions.gnome.org/extension/6583/auto-power-profile/)\n- [Autohide Battery](https://extensions.gnome.org/extension/595/autohide-battery/)\n- [Battery Health Charging](https://extensions.gnome.org/extension/5724/battery-health-charging/)\n- [Battery Power Mode Indicator](https://extensions.gnome.org/extension/9204/battery-power-mode-indicator/)\n- [Battery time](https://extensions.gnome.org/extension/5425/battery-time/)\n- [Battery Usage Wattmeter](https://extensions.gnome.org/extension/6278/battery-usage-wattmeter/)\n- [Bluetooth Battery Monitor](https://extensions.gnome.org/extension/9308/bluetooth-battery-monitor/)\n- [Blur my Shell](https://extensions.gnome.org/extension/3193/blur-my-shell/)\n- [Dim Completed Calendar Events](https://extensions.gnome.org/extension/5979/dim-completed-calendar-events/)\n- [Do Not Disturb While Screen Sharing Or Recording](https://extensions.gnome.org/extension/5985/do-not-disturb-while-screen-sharing-or-recording/)\n- [Double Click Activities to App Grid](https://extensions.gnome.org/extension/9339/double-click-activities-to-app-grid/)\n- [Dynamic Calendar, Clocks and Weather Icons ](https://extensions.gnome.org/extension/8640/dynamic-calendar-clocks-and-weather-icons-reborn/)\n- [Dynamic Music Pill](https://extensions.gnome.org/extension/9334/dynamic-music-pill/)\n- [Folder Search Provider](https://extensions.gnome.org/extension/8227/folder-search-provider/)\n- [Forge](https://extensions.gnome.org/extension/4481/forge/)\n- [Gnome 4x UI Improvements](https://extensions.gnome.org/extension/4158/gnome-40-ui-improvements/)\n- [GSConnect](https://extensions.gnome.org/extension/1319/gsconnect/)\n- [Hide Keyboard Layout](https://extensions.gnome.org/extension/2848/hide-keyboard-layout/)\n- [Home Assistant Extension](https://extensions.gnome.org/extension/4170/home-assistant-extension/)\n- [Launch New Instance](https://extensions.gnome.org/extension/600/launch-new-instance/)\n- [Night Theme Switcher](https://extensions.gnome.org/extension/2236/night-theme-switcher/)\n- [Quick Settings Tweaks](https://extensions.gnome.org/extension/5446/quick-settings-tweaker/)\n- [Right Click Next](https://extensions.gnome.org/extension/7600/right-click-next/)\n- [Screenshot OCR](https://extensions.gnome.org/extension/9338/screenshot-ocr/)\n- [Top Panel Workspace Scroll](https://extensions.gnome.org/extension/701/top-panel-workspace-scroll/)\n- [Tweaks & Extensions in System Menu](https://extensions.gnome.org/extension/1653/tweaks-in-system-menu/)\n- [Weather O'Clock](https://extensions.gnome.org/extension/5470/weather-oclock/)\n"
  },
  {
    "path": "Install.md",
    "content": "## How I install my system\n\n### Preparing\n\nDownload [Fedora image](https://getfedora.org/ru/workstation/)\nand write it to the USB drive:\n\n```sh\nflatpak install flathub io.gitlab.adhami3310.Impression\n```\n\nCopy `.ssh` and `.local/share/gnupg` into `Документы/.Private`.\n\nClean `node_modules`:\n\n```sh\nrm -R ~/Dev/*/node_modules ~/Dev/*/*/node_modules ~/Dev/*/coverage ~/Dev/susedko/fedora-coreos.iso\n```\n\nCopy these files to external SDD:\n\n- `Dev/`\n- `Vídeos/*`\n- `Документы/.Private/`\n\n### BIOS\n\n1. Boot to BIOS and set supervisor password.\n2. Set Game Optimized iGPU.\n3. Temporary enable USB boot.\n\n### Install\n\nStart installer:\n\n1. Select English language.\n2. Use entire disk mode with encryption.\n\nReboot to USB drive again. Mount laptop SSD.\n\nOpen `etc/fstab`.\n\nAdd `noatime,nodiratime` to root & home partitions.\n\nMove `/tmp` and `/var/tmp` to RAM:\n\n```\nvartmp /var/tmp tmpfs defaults,noatime,nodiratime 0 0\nvartmp /tmp     tmpfs defaults,noatime,nodiratime 0 0\n```\n\nReboot to BIOS. Block boot from USB.\n\nReboot to system. Set Russian language, name to `Andrey Sitnik` and login `ai`.\n\nSet laptop name:\n\n```sh\nsudo hostnamectl set-hostname savoia\n```\n\nReboot.\n\nCopy `Dev/` and `Документы/.Private/` from external SDD and open `Install.md` locally.\n\nReduce swap usage by creating `/etc/sysctl.d/99-swappiness.conf` with:\n\n```\nvm.swappiness = 10\n```\n\nFix booting video glitch:\n\n```sh\nsudo grubby --update-kernel=ALL --args=\"plymouth.use-simpledrm=0\"\n```\n\nEnable `Rendimiento`, disable `Ahorro de energía automático`,\n`Suspender automaticámente` in Energía settings.\n\n### System Update\n\nSet `KEYMAP=us` and `XKBLAYOUT=us` in `/etc/vconsole.conf`.\n\nRemove unnecessary packages:\n\n```sh\nsudo dnf remove cheese rhythmbox gnome-boxesd orca gnome-contacts gnome-getting-started-docs nautilus-sendto gnome-shell-extension-* libreoffice-* gnome-characters gnome-maps gnome-photos simple-scan virtualbox-guest-additions gedit gnome-boxes gnome-tour gnome-connections mediawriter eog gnome-system-monitor baobab gnome-log gnome-calculator gnome-weather gnome-text-editor gnome-font-viewer gnome-clocks gnome-calendar evince totem ffmpeg-free snapshot intel-media-driver cups-browsed anaconda malcontent-control loupe\n```\n\nRun Software Center, disable `Fedora Flatpak` and enable Flathub and Chrome.\n\nAdd RPM Fusion (for codecs) and Terra (for Zed):\n\n```sh\nsudo dnf install --nogpgcheck http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm\nsudo dnf install --nogpgcheck --repofrompath 'terra,https://repos.fyralabs.com/terra$releasever' terra-release\n```\n\nUpdate system via Software Center.\n\nInstall software:\n\n```sh\nsudo dnf swap ffmpeg-free ffmpeg --allowerasing\nsudo dnf swap mesa-va-drivers mesa-va-drivers-freeworld\nsudo dnf swap mesa-vdpau-drivers mesa-vdpau-drivers-freeworld\nsudo dnf copr enable atim/starship\nsudo dnf copr enable dusansimic/themes\nsudo dnf copr enable hyperreal/better_fonts\nsudo dnf install xclip micro fuse-encfs zenity borgbackup openssl ffmpegthumbnailer nss-tools mosquitto ydotool amrnb amrwb faac faad2 flac gstreamer1-libav gstreamer1-plugins-bad-freeworld gstreamer-ffmpeg gstreamer-plugins-bad-nonfree gstreamer-plugins-espeak gstreamer-plugins-ugly lame libdca libmad libmatroska x264 x265 xvidcore gstreamer1-plugins-bad-free gstreamer1-plugins-base gstreamer1-plugins-good gstreamer-plugins-bad gstreamer1-plugins-ugly-free mpv ffmpeg xorg-x11-drv-intel intel-media-driver webp-pixbuf-loader heif-pixbuf-loader avif-pixbuf-loader libheif-freeworld ffmpeg-libs libva libva-utils gstreamer1-vaapi mozilla-openh264 libheif-tools unrar p7zip p7zip-plugins speech-dispatcher speech-dispatcher-utils google-chrome-stable nodejs podman git tig ripgrep xkill bat make difftastic nextcloud-client zsh util-linux-user starship sqlite  morewaita-icon-theme nethogs fuse-sshfs logiops libgda libgda-sqlite playerctl cabextract xorg-x11-font-utils tesseract tesseract-devel zed\nsudo rpm -ivh --nodigest --nofiledigest https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm\n```\n\nSet Flatpak languages:\n\n```sh\nflatpak config languages --set \"es;en;ru\"\nsudo flatpak update\n```\n\nInstall applications from Flatpak:\n\n```sh\nflatpak install flathub de.haeckerfelix.Fragments org.telegram.desktop org.nickvision.tubeconverter org.gnome.Loupe com.mattjakeman.ExtensionManager io.gitlab.adhami3310.Converter net.nokyan.Resources org.gnome.Calculator org.gnome.Logs org.gnome.Weather org.gnome.clocks org.gnome.Calendar org.gnome.Epiphany org.inkscape.Inkscape org.gnome.gitlab.YaLTeR.VideoTrimmer org.gnome.World.Iotas app.devsuite.Ptyxis hu.irl.cameractrls org.gnome.Snapshot org.gnome.Papers org.gimp.GIMP be.alexandervanhee.gradia com.github.PintaProject.Pinta com.yubico.yubioath org.gnome.font-viewer\n```\n\nInstall [Zoom](https://zoom.us/download).\n\nRemove default GNOME console.\n\nSet `Ctrl + C` and `Ctrl + V` for copy/paste in new terminal settings.\n\nFix unnecessary folder creation in Zoom:\n\n```sh\nflatpak override --user us.zoom.Zoom --nofilesystem=~/Documents/Zoom\nmkdir -p ~/.local/share/flatpak/exports/share/applications/\ncp /var/lib/flatpak/exports/share/applications/us.zoom.Zoom.desktop ~/.local/share/flatpak/exports/share/applications/\n```\n\nReplace `Exec` to `/home/ai/Dev/environment/bin/zoom @@u %U @@` in `~/.local/share/flatpak/exports/share/applications/us.zoom.Zoom.desktop`.\n\nAdd Autostart and fingers to user settings.\n\nDisable Software auto-update and notifications.\n\nSet [color profile](https://www.notebookcheck.net/uploads/tx_nbc2/BOE0CB4.icm)\nin `Color` settings.\n\nInstall `micro` and its plugins:\n\n```sh\nmicro -plugin install editorconfig\nsudo dnf remove nano\n```\n\nDisable waking up by mouse by creating `/etc/udev/rules.d/logitech-bolt.rules`:\n\n```sh\nACTION==\"add\", SUBSYSTEM==\"usb\", DRIVERS==\"usb\", ATTRS{idVendor}==\"046d\", ATTRS{idProduct}==\"c548\", ATTR{power/wakeup}=\"disabled\"\n```\n\nDisable file system scanning:\n\n```sh\ndconf write /org/freedesktop/tracker/miner/files/crawling-interval -2\n```\n\n### Personal Files\n\nCopy `.ssh` and `.local/share/gnupg`:\n\n```sh\n~/Dev/environment/bin/private\n```\n\nChange permissions:\n\n```sh\nchmod 744 ~/.ssh\nchmod 700 ~/.local/share/gnupg/\nchmod 644 ~/.ssh/* ~/.local/share/gnupg/*\nchmod 700 ~/.local/share/gnupg/private-keys-v1.d\nchmod 600 ~/.ssh/id_* ~/.local/share/gnupg/private-keys-v1.d/*\n```\n\nCopy configs:\n\n```sh\n~/Dev/environment/bin/copy-env system\n```\n\n## Input\n\nSet mouse buttons config at `/etc/logid.cfg`:\n\n```\ndevices: ({\n  name: \"MX Master 3S\";\n\n  smartshift: { on: false; }\n\n  hiresscroll: { hires: false; invert: false; target: false; };\n\n  buttons: (\n    {\n      cid: 0x53;  # Back\n      action = {\n        type: \"Keypress\";\n        keys: [\"KEY_LEFTCTRL\", \"KEY_V\"];\n      };\n    },\n    {\n      cid: 0x56;  # Forward\n      action = {\n        type: \"Keypress\";\n        keys: [\"KEY_LEFTCTRL\", \"KEY_C\"];\n      };\n    }\n  );\n});\n```\n\nAdd `-c /etc/logid.cfg` to `Exec` field of `/usr/lib/systemd/system/logid.service`.\n\nEnable mouse extensions:\n\n```sh\nsudo systemctl enable --now logid\n```\n\nInstall custom universal keyboard layouts:\n\n```sh\nmkdir -p ~/.config/xkb/symbols/ ~/.config/xkb/rules/\nwget -O ~/.config/xkb/symbols/universal_en https://raw.githubusercontent.com/ai/universal-layout/main/universal_en.xkb\nwget -O ~/.config/xkb/symbols/universal_ru https://raw.githubusercontent.com/ai/universal-layout/main/universal_ru.xkb\nwget -O ~/.config/xkb/rules/evdev.xml https://raw.githubusercontent.com/ai/universal-layout/main/evdev.xml\n```\n\nSet keyboard settings:\n\n```sh\ndconf write /org/gnome/desktop/input-sources/xkb-options \"['grp_led:caps', 'lv3:ralt_switch', 'grp:shift_caps_switch']\"\n```\n\n### Terminal\n\nInstall eza:\n\n```sh\ncurl -sL https://github.com/eza-community/eza/releases/latest/download/eza_x86_64-unknown-linux-gnu.tar.gz | tar xz\nchmod +x eza\nmkdir -p ~/.local/bin/\nmv eza ~/.local/bin\n```\n\nInstall atuin:\n\n```sh\ncurl -sL https://github.com/atuinsh/atuin/releases/download/v18.6.1/atuin-x86_64-unknown-linux-gnu.tar.gz | tar xz --strip-components=1 atuin-x86_64-unknown-linux-gnu/atuin\nmv atuin ~/.local/bin\n```\n\nInstall zsh:\n\n```sh\nmkdir -p ~/.local/share/history\nchmod 700 ~/.local/share/history\ngit clone https://github.com/zsh-users/zsh-syntax-highlighting ~/.local/lib/zsh/zsh-syntax-highlighting\ngit clone https://github.com/zsh-users/zsh-autosuggestions ~/.local/lib/zsh/zsh-autosuggestions\ngit clone https://github.com/jimhester/per-directory-history ~/.local/lib/zsh/per-directory-history\nchsh -s /bin/zsh\n```\n\nCreate `/root/.zshrc`:\n\n```sh\neval \"$(starship init zsh)\"\n```\n\nReboot.\n\nSelect `Russian Universal` and `English/Spanish/Catalan Universal` layouts.\n\n```sh\nrm ~/.bash*\n```\n\nOpen backup and copy files from it.\n\n```sh\nmkdir ~/backup\nborg mount \"ai@susedko.local:/var/mnt/vault/ai/backup\" ~/backup\n```\n\nCopy files.\n\n```sh\nborg umount ~/backup\nrmdir ~/backup\n```\n\nStart copying `Vídeos/*` from SDD.\n\n### Text Editors\n\nMove Claude Code:\n\n```bash\nmkdir -p ~/.config/environment.d/\nmkdir -p ~/.local/share/claude\necho \"GNUPGHOME=$HOME/.local/share/gnupg\" >> ~/.config/environment.d/90-clean-home.conf\necho \"NODE_COMPILE_CACHE=$HOME/.cache/node\" >> ~/.config/environment.d/90-clean-home.conf\necho \"NPM_CONFIG_USERCONFIG=$HOME/.config/npmrc\" >> ~/.config/environment.d/90-clean-home.conf\necho \"CLAUDE_CONFIG_DIR=$HOME/.local/share/claude\" >> ~/.config/environment.d/90-clean-home.conf\n```\n\nSign-in into accounts in Zed.\n\nInstall Zed plugins: `ini`, `dockerfile`, `toml`, `svelte`, `make`, `adwaita-pastel`, `material icon theme`, `codebook`, `sql`, `nginx`, `git-firefly`, `pug`, `xml`, `po`, `env`, `oxc`.\n\nOpen Iotas app, log-in into Nextcloud account.\n\n### GNOME Settings\n\nOpen Clock and add `Vladivostok`, `Moscow`, `Lisbon`, and `San Francisco`.\n\nRun Weather app and set current location.\n\nInstall [Lilex](https://lilex.myrt.co).\n\n```sh\nmkdir -p ~/.local/share/fonts\n# Copy variable fonts\nfc-cache -f -v\ngsettings set org.gnome.desktop.interface monospace-font-name \"Lilex 12\"\n```\n\nOpen settings:\n\n- **Appearance:** use standard GNOME wallpaper.\n- **Notifications:** disable Notifications on lock screen.\n- **Search:** keep only Calculator and Settings.\n- **Multitask:** disable Active corners.\n- **Online accounts:** add Google.\n- **Power:** enable Show percentage and disable screen lock.\n- **Mouse:** mouse speed to 75%, touchpad speed to 90%.\n- **Date and time:** enable seconds and week day on top panel.\n- **Privacy** → disable File History.\n\nBoost volume over 100%:\n\n```sh\ngsettings set org.gnome.desktop.sound allow-volume-above-100-percent true\n```\n\nLogin to NextCloud client to `sync.sitnik.es`.\n\nNautilus:\n\n- Enable Sort folders before files.\n- Enable Single click to open items.\n- Enable preview, search, file numbers for remote folders.\n\nDisable GNOME extension version check:\n\n```sh\ngsettings set org.gnome.shell disable-extension-version-validation true\n```\n\nDownload the latest [`framework_tool`](https://github.com/FrameworkComputer/framework-system/actions?query=branch%3Amain), extract and copy to the system:\n\n```sh\nsudo cp ~/Descargas/framework_tool /usr/local/bin\n```\n\nInstall tool for clipboard manager:\n\n```bash\nmkdir -p ~/.local/share/copyous@boerdereinar.dev/\ncurl https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/es/highlight.min.js > ~/.local/share/copyous@boerdereinar.dev/highlight.min.js\n```\n\nInstall extensions from [`GNOME.md`](./GNOME.md).\n\nRestore settings file from backup:\n\n```sh\n~/Dev/environment/bin/restore-gnome-extensions\n```\n\nClean up applications list.\n\nAdd Iceland NordVPN.\n\n[Disable](https://discussion.fedoraproject.org/t/please-enter-passphrase-for-disk-has-returned/150626/5) disk name in password prompt.\n\n### Folders\n\nCreate empty file template:\n\n```sh\nmkdir ~/.local/share/desktop\nmkdir ~/.local/share/templates\ntouch ~/.local/share/templates/Пустой\\ файл\n```\n\nFix folders at `~/.config/user-dirs.dirs`:\n\n```sh\nXDG_DESKTOP_DIR=\"$HOME/.local/share/desktop\"\nXDG_DOWNLOAD_DIR=\"$HOME/Загрузки\"\nXDG_TEMPLATES_DIR=\"$HOME/.local/share/templates\"\nXDG_PUBLICSHARE_DIR=\"$HOME/.local/share/desktop\"\nXDG_DOCUMENTS_DIR=\"$HOME/Документы\"\nXDG_MUSIC_DIR=\"$HOME\"\nXDG_PICTURES_DIR=\"$HOME\"\nXDG_VIDEOS_DIR=\"$HOME/Видео\"\n```\n\nClean bookmarks:\n\n```sh\necho \"\" > ~/.config/gtk-3.0/bookmarks\n```\n\nRemove unnecessary folders:\n\n```sh\nmkdir \"Снимки экрана\"\n```\n\nConnect to server in Files by `sftp://ai@susedko.local/` and add `vault` to Favorites places. Add `Загрузки` and `Снимки экрана` to Favorites places.\n\nLeft only Telegram, Firefox, Nautilus, Terminal, Iotas, System Update, and\nBackup in the dock.\n\nAdd icon theme:\n\n```sh\ngsettings set org.gnome.desktop.interface icon-theme 'MoreWaita'\n```\n\nSet icons:\n\n- `/usr/share/icons/MoreWaita/scalable/places/folder-code.svg`\n  for `~/Dev/`.\n- `/usr/share/icons/Adwaita/scalable/places/folder-pictures.svg`\n  for `~/Capturas de pantalla/`.\n\n## Home Server\n\nAdd server’s certificate to the system:\n\n```sh\nmkdir -p ~/.pki/nssdb\ncertutil -N -d sql:$HOME/.pki/nssdb --empty-password\ncertutil -d sql:$HOME/.pki/nssdb -A -t \"C,,\" -n sitnik -i ~/Dev/susedko/sitniks.crt\nsudo cp ~/Dev/susedko/sitniks.crt /etc/pki/ca-trust/source/anchors/sitniks.pem\nsudo update-ca-trust\n```\n\nAdd service to `~/.config/systemd/user/force-lock.service`:\n\n```ini\n[Unit]\nDescription=Force Lock\n\n[Service]\nExecStart=/home/ai/Dev/environment/bin/force-lock\nRestart=on-failure\nRestartSec=30s\n\n[Install]\nWantedBy=default.target\n```\n\nAdd service to `~/.config/systemd/user/susedko-listener.service`:\n\n```ini\n[Unit]\nDescription=Susedko Listener\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nExecStart=/home/ai/Dev/environment/bin/susedko-listener\nRestart=on-failure\nRestartSec=30s\nStartLimitBurst=5\n\n[Install]\nWantedBy=default.target\n```\n\nAdd service to `/etc/systemd/system/ydotoold.service`:\n\n```ini\n[Unit]\nDescription=ydotool Daemon\n\n[Service]\nExecStart=ydotoold --socket-path=\"/run/.ydotool_socket\" --socket-own=\"1000:1000\"\nRestart=on-failure\nRestartSec=30s\n\n[Install]\nWantedBy=default.target\n```\n\nEnable services:\n\n```sh\nsudo systemctl enable ydotoold.service\nsudo systemctl start ydotoold.service\nsystemctl --user enable susedko-listener.service force-lock.service\nsystemctl --user start susedko-listener.service force-lock.service\n```\n\n### Development Tools\n\nInstall Node.js, TypeScript, and Dev Containers.\n\n```sh\nnpm config set cache \"$HOME/.cache/npm\"\nmkdir -p ~/.local/lib/node/\ntee -a ~/.local/lib/node/package.json << EOM\n{\n  \"dependencies\": {\n    \"@devcontainers/cli\": \">=0.80.1\"\n  }\n}\nEOM\ncd ~/.local/lib/node && npm install && cd\n\nmkdir -p ~/.local/share/multiocular\nmkdir -p ~/.local/share/history\nchmod 700 ~/.local/share/history\npodman volume create shell-history\npodman volume create pnpm-store\n\n~/Dev/environment/bin/build-devcontainer\ncd ~/Dev/nanostores\ndevup\n# Find container ID\npodman exec -it --user root $container_id zsh\nmkdir /home/ai/.local/share/pnpm/store/v11\nchown ai:ai /home/ai/.local/share/pnpm/store/v11\nchown ai:ai /home/ai/.local/share/history/histfile\n```\n\nFix Dev Container with Podman in Zed:\n\n```sh\nsudo ln -s $(which podman) /usr/local/bin/docker\n```\n\nInstall Keybase:\n\n```sh\nsudo dnf install https://prerelease.keybase.io/keybase_amd64.rpm\nrun_keybase\n```\n\nDisable autostart in Keybase settings and revoke old laptop.\n\n## LanguageTool Server\n\nPrepare [ngrams](https://languagetool.org/download/ngram-data/):\n\n```sh\nmkdir -p ~/.local/share/ngrams\ncd ~/.local/share/ngrams\nwget https://languagetool.org/download/ngram-data/ngrams-en-20150817.zip\nwget https://languagetool.org/download/ngram-data/ngrams-es-20150915.zip\nwget https://languagetool.org/download/ngram-data/untested/ngram-ru-20150914.zip\nunzip ngrams-en-20150817.zip\nunzip ngrams-es-20150915.zip\nunzip ngram-ru-20150914.zip\nrm ngram*.zip\n```\n\n```sh\nmkdir -p ~/.config/systemd/user/\n```\n\nCreate service unit `~/.config/systemd/user/languagetool.service`:\n\n```ini\n[Unit]\nDescription=LanguageTool Server\n\n[Service]\nExecStart=podman run --rm --replace --name languagetool \\\n  -p 8081:8010 \\\n  -e langtool_languageModel=/ngrams \\\n  -e Java_Xms=512m -e Java_Xmx=2g \\\n  -v /home/ai/.local/share/fasttext:/fasttext:Z \\\n  -v /home/ai/.local/share/ngrams:/ngrams:Z \\\n  docker.io/erikvl87/languagetool:latest\n\n[Install]\nWantedBy=default.target\n```\n\nInstall LanguageTool:\n\n```sh\n~/Dev/environment/bin/update-languagetool\n```\n\nEnable service.\n\n```sh\nsystemctl --user daemon-reload\nsystemctl --user enable --now languagetool.service\nsystemctl --user start --now languagetool.service\n```\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright 2013 Andrey Sitnik <andrey@sitnik.es>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "My home configs, scripts and [installation process](./Install.md).\n\nSee also [my keyboard layout](https://github.com/ai/universal-layout).\n\n### Configs\n\n- [GNOME Shell extensions](./GNOME.md)\n- [`.gitconfig`](./gitconfig)\n"
  },
  {
    "path": "batconfig",
    "content": "--plain\n"
  },
  {
    "path": "bin/backup",
    "content": "#!/bin/sh\n\nTITLE='\\033[0;32m\\033[1m'\nGRAY='\\033[0;90m'\nNC='\\033[0m'\n\nhour=$(date +\"%H\")\nif [[ hour -lt 9 || hour -ge 22 ]]; then\n  echo -e \"${TITLE}Подготовка кровати ко сну${GRAY}\"\n  ~/Dev/environment/bin/susedko script/turn_on script.heat_bedroom\n  echo -e \"${NC}\\n\"\nfi\n\necho -e \"${TITLE}Сохранение расширений GNOME${GRAY}\"\n~/Dev/environment/bin/backup-gnome-extensions\necho -e \"${NC}\\n\"\n\necho -e \"${TITLE}Сохранение домашнего сервера${GRAY}\"\ncd ~/Dev/susedko\nmake ha_backup\ncd\necho -e \"${NC}\\n\"\n\necho -e \"${TITLE}Сохранение файлов${GRAY}\"\nexport BORG_REPO=ai@susedko.local:/var/mnt/vault/ai/backup\nSERVICE_NAME=\"BorgBackup\"\nUSERNAME=\"backup\"\nBORG_PASSPHRASE=$(secret-tool lookup service \"BorgBackup\" username \"ai\")\nif [ -z \"$BORG_PASSPHRASE\" ]; then\n  read -sp \"Пароль от бэкапа: \" BORG_PASSPHRASE\n  echo \"$BORG_PASSPHRASE\" | secret-tool store --label=\"Password for backup\" service \"BorgBackup\" username \"ai\"\nfi\nexport BORG_PASSPHRASE\nborg create                                                \\\n    --verbose                                              \\\n    --filter AME                                           \\\n    --list                                                 \\\n    --stats                                                \\\n    --show-rc                                              \\\n    --progress                                             \\\n    --compression lz4                                      \\\n    --exclude-caches                                       \\\n    --exclude '*.iso'                                      \\\n    --exclude '**/node_modules'                            \\\n    --exclude '**/.config/mozilla/**/lock'                 \\\n    --exclude '**/.config/mozilla/**/crashes'              \\\n    --exclude '**/.config/mozilla/**/bookmarkbackups'      \\\n    --exclude '**/.config/mozilla/**/datareporting/archived' \\\n    --exclude '**/.config/mozilla/**/weave/logs'           \\\n    --exclude '**/.config/mozilla/**/cache'                \\\n    --exclude '**/.config/mozilla/firefox/firefox-mpris'   \\\n    --exclude '**/.config/mozilla/firefox/Crash Reports'   \\\n    --exclude '**/.var/app/**/cache'                       \\\n    --exclude '**/.var/app/**/Cache'                       \\\n    --exclude '**/.var/app/**/media_cache'                 \\\n    --exclude '**/.var/app/**/temp_data'                   \\\n    --exclude '**/.var/app/**/cache_*'                     \\\n    --exclude '**/.var/app/org.gnome.Epiphany'             \\\n    --exclude '**/.var/app/org.inkscape.Inkscape'          \\\n    --exclude '**/.var/app/io.missioncenter.MissionCenter' \\\n    --exclude '**/.var/app/com.belmoussaoui.Decoder'       \\\n    --exclude '**/.var/app/us.zoom.Zoom/.zoom/data/Emojis' \\\n    --exclude '**/.ld.so'                                  \\\n    --exclude '**/*.log'                                   \\\n    --exclude '**/sitnik.es/dist'                          \\\n    ::'{hostname}-{now}'                                   \\\n    ~/Dev/susedko                                          \\\n    ~/Dev/environment                                      \\\n    ~/Dev/sitnik.es                                        \\\n    ~/.ssh                                                 \\\n    ~/.local/share/gnupg                                   \\\n    ~/Документы/.Private                                   \\\n    ~/.config/mozilla                                             \\\n    ~/.config/gsconnect                                    \\\n    ~/.local/share/gnome-shell-extensions-settings         \\\n    ~/.var/app\nborg prune                         \\\n    --list                         \\\n    --show-rc                      \\\n    --keep-last 14\nborg compact\nunset BORG_PASSPHRASE\necho -e \"${NC}\\n\"\n\necho -e \"${TITLE}Синхронизация видео${GRAY}\"\nrsync -a --delete --progress \\\n  --no-perms --no-owner --no-group \\\n  /home/ai/Видео/Эротика/ ai@susedko.local:/var/mnt/vault/ai/Selected\n\nexit ${global_exit}\n"
  },
  {
    "path": "bin/backup-gnome-extensions",
    "content": "#!/bin/bash\n\nbackup_dir=\"$HOME/.local/share/gnome-shell-extensions-settings\"\nrm -r \"$backup_dir\"\nmkdir -p \"$backup_dir\"\n\nextensions=$(gsettings get org.gnome.shell enabled-extensions | tr -d \"[],'\")\n\nfor extension in $extensions; do\n  base_name=$(echo \"$extension\" | sed 's/@.*//')\n  output_file=\"$backup_dir/${extension}.ini\"\n  settings=$(dconf dump \"/org/gnome/shell/extensions/$base_name/\")\n  if [ -n \"$settings\" ]; then\n    echo \"$settings\" > \"$output_file\"\n    echo \"Настройки $extension сохранены\"\n  fi\ndone\n"
  },
  {
    "path": "bin/build-devcontainer",
    "content": "#!/bin/bash\n\n~/Dev/environment/bin/copy-env\n\npodman build -t localhost/ai-opensource \\\n  -f /home/ai/Dev/environment/devcontainer/Dockerfile \\\n  /home/ai/Dev/environment\n"
  },
  {
    "path": "bin/clear",
    "content": "#!/bin/sh\n\necho \"Было $(df -h / | tail -1 | awk '{print $4}')\"\necho\n\npodman rmi --all --force\npnpm store prune\nyarn cache clean\nnpm cache clean -f\nrm -Rf ~/.local/share/Trash/\n\necho\necho \"Стало $(df -h / | tail -1 | awk '{print $4}')\"\n"
  },
  {
    "path": "bin/clear-weather-city",
    "content": "#!/bin/sh\n\ngsettings reset org.gnome.Weather locations\n"
  },
  {
    "path": "bin/copy-env",
    "content": "#!/bin/sh\n# Copy config and scripts to or from repo\n\nif [ \"$1\" == \"system\" ]; then\n  rm ~/.local/share/applications/*.{desktop,svg} -f\n  cp ~/Dev/environment/icons/* ~/.local/share/applications/\n  mkdir -p ~/.config/bat/\n  mkdir -p ~/.config/mpv/\n  mkdir -p ~/.config/git/\n  mkdir -p ~/.config/micro/\n  mkdir -p ~/.config/zed/\n  rm -f ~/.zshrc\n  ln ~/Dev/environment/zshrc ~/.zshrc\n  cp ~/Dev/environment/.oxfmtrc.json ~/.oxfmtrc.json\n  cp ~/Dev/environment/zed.json ~/.config/zed/settings.json\n  cp ~/Dev/environment/zed-keys.json ~/.config/zed/keymap.json\n  cp ~/Dev/environment/mpv.conf ~/.config/mpv/mpv.conf\n  cp ~/Dev/environment/ripgreprc ~/.config/ripgreprc\n  cp ~/Dev/environment/sshconfig ~/.ssh/config\n  cp ~/Dev/environment/batconfig ~/.config/bat/config\n  cp ~/Dev/environment/gitconfig ~/.config/git/config\n  cp ~/Dev/environment/gitignore ~/.config/git/ignore\n  cp ~/Dev/environment/starship.toml ~/.config/starship.toml\n  cp ~/Dev/environment/mimeapps.list ~/.config/mimeapps.list\n  cp ~/Dev/environment/mpv-input.conf ~/.config/mpv/input.conf\n  cp ~/Dev/environment/micro.json ~/.config/micro/settings.json\nelse\n  rm ~/Dev/environment/icons/*.{svg,desktop} -f\n  cp ~/.oxfmtrc.json ~/Dev/environment/.oxfmtrc.json\n  cp ~/.ssh/config ~/Dev/environment/sshconfig\n  cp ~/.config/ripgreprc ~/Dev/environment/ripgreprc\n  cp ~/.config/git/config ~/Dev/environment/gitconfig\n  cp ~/.config/git/ignore ~/Dev/environment/gitignore\n  cp ~/.config/bat/config ~/Dev/environment/batconfig\n  cp ~/.config/mpv/mpv.conf ~/Dev/environment/mpv.conf\n  cp ~/.config/starship.toml ~/Dev/environment/starship.toml\n  cp ~/.config/mpv/input.conf ~/Dev/environment/mpv-input.conf\n  cp ~/.config/mimeapps.list ~/Dev/environment/mimeapps.list\n  cp ~/.config/micro/settings.json ~/Dev/environment/micro.json\n  cp ~/.local/share/applications/*.{svg,desktop} ~/Dev/environment/icons/\n  cp ~/.config/zed/settings.json ~/Dev/environment/zed.json\n  cp ~/.config/zed/keymap.json ~/Dev/environment/zed-keys.json\n  rm ~/Dev/environment/icons/chrome-* -f\n  rm ~/Dev/environment/icons/userapp-* -f\n  rm ~/Dev/environment/icons/org.gnome.Shell.Extensions.* -f\n  ~/Dev/environment/bin/update-extension-lists\nfi\n"
  },
  {
    "path": "bin/dev",
    "content": "#!/bin/bash\n\nset -e\n\nfunction get_container_runtime() {\n  if command -v podman &> /dev/null; then\n    echo \"podman\"\n  elif command -v docker &> /dev/null; then\n    echo \"docker\"\n  else\n    echo \"Error: Neither podman nor docker found\" >&2\n    return 1\n  fi\n}\n\nfunction devcontainer_root() {\n  local dir=$PWD\n  while [ \"$dir\" != \"/\" ]; do\n    if [[ -f \"$dir/.devcontainer.json\" ]] || [[ -d \"$dir/.devcontainer\" ]]; then\n      echo $dir\n      return\n    fi\n    dir=$(dirname \"$dir\")\n  done\n  echo \"No .devcontainer.json or .devcontainer/ found\" >&2\n  return 1\n}\n\nfunction devcontainer_config() {\n  if [[ -f \"$1/.devcontainer/podman/devcontainer.json\" ]]; then\n    echo \"$1/.devcontainer/podman/devcontainer.json\"\n  elif [[ -f \"$1/.devcontainer/devcontainer.json\" ]]; then\n    echo \"$1/.devcontainer/devcontainer.json\"\n  else\n    echo \"$1/.devcontainer.json\"\n  fi\n}\n\nfunction get_container_id() {\n  local runtime=$(get_container_runtime)\n  $runtime ps -q --filter label=devcontainer.local_folder=$root\n}\n\nfunction get_username() {\n  local username=\"\"\n  if [ -f \"$root/.devcontainer/Dockerfile\" ]; then\n    username=$(\n      awk -v IGNORECASE=1 '/^\\s*USER\\s+/{u=$2} END{print u}' \"$root/.devcontainer/Dockerfile\"\n    )\n  fi\n  echo \"${username:-ai}\"\n}\n\nif [ \"$1\" = \"--isolate\" ]; then\n  cp ~/Dev/environment/devcontainer/devcontainer.json .devcontainer.json\n  if [ -d .git ]; then\n    sed -i '/devcontainer/d' .git/info/exclude\n    echo '.devcontainer.json' >> .git/info/exclude\n  fi\n  exit\nfi\n\nroot=$(devcontainer_root)\nif [ \"$root\" = \"\" ]; then\n  echo \"No .devcontainer.json or .devcontainer/ found\" >&2\n  return 1\nfi\n\nif [ \"$1\" = \"--up\" ]; then\n  runtime=$(get_container_runtime)\n  devcontainer_args=(\n    \"--docker-path\" \"$runtime\"\n    \"--mount\" \"type=bind,source=${SSH_AUTH_SOCK},target=/run/user/1000/gcr/ssh\"\n    \"--dotfiles-repository\" \"https://github.com/ai/environment.git\"\n    \"--dotfiles-install-command\" \"devcontainer/install-dotfiles\"\n    \"--workspace-folder\" \"$root\"\n    \"--config\" \"$(devcontainer_config $root)\"\n  )\n  if [ -d /home/ai/.local/share/multiocular ]; then\n    devcontainer_args+=(\n      \"--mount\" \"type=bind,source=/home/ai/.local/share/multiocular,target=/home/$(get_username)/.local/share/multiocular\"\n    )\n  fi\n  if [ -d /home/ai/.local/share/claude ]; then\n    devcontainer_args+=(\n      \"--mount\" \"type=bind,source=/home/ai/.local/share/claude,target=/home/$(get_username)/.local/share/claude\"\n      \"--mount\" \"type=bind,source=/home/ai/.local/share/claude,target=/home/$(get_username)/.claude\"\n    )\n  fi\n  if [ -d /home/ai/.local/share/zed ]; then\n    devcontainer_args+=(\n      \"--mount\" \"type=bind,source=/home/ai/.local/share/zed,target=/home/$(get_username)/.local/share/zed\"\n      \"--mount\" \"type=bind,source=/home/ai/.config/zed,target=/home/$(get_username)/.config/zed\"\n      \"--mount\" \"type=bind,source=/home/ai/.local/share/zed_server,target=/home/$(get_username)/.zed_server\"\n    )\n  fi\n  devcontainer up \"${devcontainer_args[@]}\"\n\nelif [ \"$1\" = \"--down\" ]; then\n  runtime=$(get_container_runtime)\n  container_id=$(get_container_id)\n  if [ \"$container_id\" == \"\" ]; then\n    echo \"Container is not running\"\n  else\n    $runtime kill $container_id\n  fi\n\nelif [ \"$1\" = \"--rebuild\" ]; then\n  ~/Dev/environment/bin/dev --up\n  container_id=$(~/Dev/environment/bin/dev --down)\n  runtime=$(get_container_runtime)\n  $runtime container rm $container_id\n  search_pattern=\"vsc-$(basename \"$root\")-[0-9a-f]\\+-uid\"\n  image_id=$($runtime image ls --format \"{{.Repository}}:{{.Tag}}\" | grep \"$search_pattern\" | awk '{print $1}')\n  if [ \"$image_id\" != \"\" ]; then\n    $runtime image rm --force $image_id\n  fi\n  ~/Dev/environment/bin/dev --up\n\nelif [ \"$1\" = \"--port\" ]; then\n  if [[ \"$2\" =~ ^[0-9]+$ ]]; then\n    # $2 is a number, use it as port\n    port=\"$2\"\n    shift 2\n    args=\"$*\"\n  else\n    # No port specified or $2 is not a number, generate random port\n    while true; do\n      port=$(shuf -i 1024-9999 -n 1)\n      if ! ss -tuln | grep -q \":${port}\\s\"; then\n        break\n      fi\n    done\n    shift 1\n    args=\"$* --port $port\"\n  fi\n\n  runtime=$(get_container_runtime)\n  container_args=(\n    \"--rm\"\n    \"-w\" \"/workspaces/$(basename $root)\"\n    \"-p\" \"${port}:${port}\"\n    \"--mount\" \"type=bind,source=$root,target=/workspaces/$(basename $root)\"\n    \"--security-opt\" \"label=disable\"\n    \"--userns=keep-id\"\n    \"--ulimit=host\"\n    \"--cap-add=NET_RAW\"\n  )\n\n  if [ -d \"/home/ai/.local/share/multiocular\" ]; then\n    container_args+=(\n      \"--mount\" \"type=bind,source=/home/ai/.local/share/multiocular,target=/home/$(get_username)/.local/share/multiocular\"\n    )\n  fi\n  if [[ \"$args\" == pnpm\\ multiocular* ]] && [ -f ~/Dev/multiocular/.env ]; then\n    container_args+=(\"--env-file\")\n    container_args+=(\"/home/ai/Dev/multiocular/.env\")\n  fi\n\n  $runtime run \"${container_args[@]}\" -it localhost/ai-opensource $args\n\nelse\n  runtime=$(get_container_runtime)\n  container_id=$(get_container_id)\n  if [ \"$container_id\" == \"\" ]; then\n    ~/Dev/environment/bin/dev --up\n    container_id=$(get_container_id)\n  fi\n  subdir=\"\"\n  if [ \"$PWD\" != \"$root\" ]; then\n    subdir=\"${PWD#$root/}\"\n  fi\n  workdir=\"/workspaces/$(basename $root)/$subdir\"\n  if [ -z \"$1\" ]; then\n    $runtime exec -w $workdir -it $container_id zsh\n  else\n    $runtime exec -w $workdir -it $container_id zsh -ic \"$*\"\n  fi\nfi\n"
  },
  {
    "path": "bin/force-lock",
    "content": "#!/bin/bash\nIDLE_TIME=240000\nLANG=en\n\nlog() { echo \"$(date '+%H:%M:%S') $*\"; }\n\nwhile true; do\n  CURRENT_IDLE=$(gdbus call --session \\\n    --dest org.gnome.Mutter.IdleMonitor \\\n    --object-path /org/gnome/Mutter/IdleMonitor/Core \\\n    --method org.gnome.Mutter.IdleMonitor.GetIdletime \\\n    | awk '{print $2}' | tr -d ',)')\n\n  if [ \"$CURRENT_IDLE\" -ge \"$IDLE_TIME\" ]; then\n    IS_ACTIVE=$(gdbus call --session \\\n      --dest org.gnome.ScreenSaver \\\n      --object-path /org/gnome/ScreenSaver \\\n      --method org.gnome.ScreenSaver.GetActive)\n\n    if echo \"$IS_ACTIVE\" | grep -qPo \"false\"; then\n      LOCK_DISABLED=\"\"\n\n      for player in $(playerctl --list-all); do\n        URL=$(playerctl --player=\"$player\" metadata xesam:url 2>/dev/null)\n        IS_YOUTUBE=$(echo \"$URL\" | grep -q \"youtube.com/watch\" && echo true)\n        STATUS=$(playerctl --player=\"$player\" status 2>/dev/null)\n        if [ \"$IS_YOUTUBE\" = \"true\" ] && [ \"$STATUS\" = \"Playing\" ]; then\n          log \"YouTube playing, skipping lock\"\n          LOCK_DISABLED=\"true\"\n          break\n        fi\n      done\n\n      if pactl list sink-inputs | grep -qi \"application\\.name = \\\"mpv\\\"\"; then\n        log \"mpv playing, skipping lock\"\n        LOCK_DISABLED=\"true\"\n      fi\n\n      if pactl list source-outputs | grep -q \"Source Output #\"; then\n        log \"Ongoing call, skipping lock\"\n        LOCK_DISABLED=\"true\"\n      fi\n\n      if [ -z \"$LOCK_DISABLED\" ]; then\n        log \"Locking session\"\n        loginctl lock-session\n      fi\n    fi\n  fi\n  sleep 60\ndone\n"
  },
  {
    "path": "bin/porn",
    "content": "#!/bin/sh\n# Run movies from specific category\n\nif [[ \"$1\" == \"--new\" ]]; then\n  mkdir -p ~/.susedko_new\n  sshfs ai@susedko.local:/var/mnt/vault/ai/New/ ~/.susedko_new\n  mpv --shuffle --fullscreen --playlist=<(\n      find ~/.susedko_new -type f \\\n          ! -name '*.part' \\\n          ! -name '*.png' \\\n          ! -name '*.jpg' \\\n          ! -name '*.jpeg'\n  )\n  fusermount -u ~/.susedko_new\n  rmdir ~/.susedko_new\nelse\n  find /home/ai/Видео/Эротика -type f -print0 | tr '\\0' '\\n' | mpv --shuffle --fullscreen --playlist=-\nfi\n"
  },
  {
    "path": "bin/private",
    "content": "#!/bin/sh\n# Private encrypted folder\n\nSTORE=$HOME/Документы/.Private\nLINK=$HOME/Private\n\nif [ -e \"$LINK\" ]; then\n  # Lock\n  fusermount -u \"$LINK\"\n  rm -R \"$LINK\"\nelse\n  # Unlock\n  mkdir \"$LINK\"\n  encfs \"$STORE\" \"$LINK\" --extpass \"zenity --password\"\n  nautilus \"$LINK\"\nfi\n"
  },
  {
    "path": "bin/restore-gnome-extensions",
    "content": "#!/bin/bash\n\nbackup_dir=\"$HOME/.local/share/gnome-shell-extensions-settings\"\n\nif [ ! -d \"$backup_dir\" ]; then\n  echo \"Settings directory $backup_dir not found. Exiting.\"\n  exit 1\nfi\n\nextensions=$(gsettings get org.gnome.shell enabled-extensions | tr -d \"[],'\")\n\nfor settings in \"$backup_dir\"/*.ini; do\n  extension=$(basename \"$settings\" .ini)\n  base_name=$(echo \"$extension\" | sed 's/@.*//')\n  if [[ $extensions == *\"$extension\"* ]]; then\n    dconf load \"/org/gnome/shell/extensions/$base_name/\" < \"$settings\"\n    echo \"Настройки $extension востановлены\"\n  else\n    echo \"Расширение $extension не установлено или не включено, пропускаем\"\n  fi\ndone\n"
  },
  {
    "path": "bin/susedko",
    "content": "#!/bin/bash\n\nif nmcli -t -f TYPE,STATE device | grep -q \"^ethernet:connected\"; then\n  home_ip=$(timeout 1 getent hosts home.local | awk '{ print $1 }')\n  if [[ \"$home_ip\" == \"192.168.50.125\" ]]; then\n    source ~/Dev/environment/secrets.env\n    curl -s \\\n      -H \"Authorization: Bearer $HA_TOKEN\" \\\n      -H \"Content-Type: application/json\" \\\n      -d \"{\\\"entity_id\\\": \\\"$2\\\"}\" \\\n      \"https://home.local/api/services/$1\"\n    echo \"\"\n  fi\nfi\n"
  },
  {
    "path": "bin/susedko-listener",
    "content": "#!/bin/bash\n\nsource ~/Dev/susedko/secrets.env\nMQTT_BROKER=\"192.168.50.125\"\n\nmosquitto_sub -h \"$MQTT_BROKER\" -t ai_laptop -u home -P \"$HOME_PASSWORD\" | while read -r payload\ndo\n  if nmcli -t -f TYPE,STATE device | grep -q \"^ethernet:connected\"; then\n    case \"$payload\" in\n      \"LOCK\")\n        loginctl lock-session\n        ;;\n      \"WAKE\")\n        was_locked=$(dbus-send --session --dest=org.gnome.Shell --print-reply /org/gnome/Shell org.gnome.Shell.GetScreenShieldLock)\n        if echo \"$lock_status\" | grep -q \"boolean true\"; then\n          YDOTOOL_SOCKET=/run/.ydotool_socket ydotool key 28:1 28:0\n        fi\n        ;;\n      *)\n        echo \"Unknown command: $payload\"\n        ;;\n    esac\n  fi\ndone\n"
  },
  {
    "path": "bin/update",
    "content": "#!/bin/zsh\n\nset -e\n\nTITLE='\\033[0;32m\\033[1m'\nGRAY='\\033[0;90m'\nNC='\\033[0m'\n\necho -e \"${TITLE}Обновление системы${NC}\"\npkexec dnf update --refresh -y\n\necho -e \"\\n${TITLE}Обновление приложений из Flatpak${NC}\"\nflatpak update -y\n\necho -e \"\\n${TITLE}Обновление Dev Container${NC}\"\ncd ~/.local/lib/node\nnpm update\n~/Dev/environment/bin/update-dockerfile\n\necho -e \"\\n${TITLE}Обновление темы Firefox${GRAY}\"\ncd ~/.config/mozilla/firefox/iesxdh6c.default-release/chrome/firefox-gnome-theme\ngit pull origin master\n\necho -e \"\\n${TITLE}Обновление расширений GNOME${GRAY}\"\ngdbus call --session --dest org.gnome.Shell.Extensions \\\n     --object-path /org/gnome/Shell/Extensions \\\n     --method org.gnome.Shell.Extensions.CheckForUpdates\n\necho -e \"\\n${TITLE}Готово${NC}\"\nread\n"
  },
  {
    "path": "bin/update-devcontainer-configs",
    "content": "#!/bin/bash\n\nfor dir in ~/Dev/*/; do\n  target_file=\"${dir}.devcontainer.json\"\n  if [[ -f \"$target_file\" ]]; then\n    if grep -q \"localhost/ai-opensource\" \"$target_file\"; then\n      echo \"Replaced in $dir\"\n      ~/Dev/environment/bin/dev --isolate\n    fi\n  fi\ndone\npodman image rm --all --force\n"
  },
  {
    "path": "bin/update-dockerfile",
    "content": "#!/bin/zsh\n\nDOCKERFILE_PATH=\"/home/ai/Dev/environment/devcontainer/Dockerfile\"\n\nlatest_node=$(curl -s \"https://nodejs.org/dist/index.json\" | jq -r '.[0].version' | sed 's/v//')\nlatest_pnpm=$(curl -s \"https://api.github.com/repos/pnpm/pnpm/releases/latest\" | jq -r '.tag_name' | sed 's/v//')\n\ncurrent_node=$(grep -oP 'NODE_VERSION=\\K[^ \\\\]+' \"$DOCKERFILE_PATH\")\ncurrent_pnpm=$(grep -oP 'PNPM_VERSION=\\K[^ \\\\]+' \"$DOCKERFILE_PATH\")\n\nupdate_needed=false\n\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nGRAY='\\033[0;90m'\nNC='\\033[0m'\n\nif [[ \"$current_node\" != \"$latest_node\" ]] && [[ -n \"$latest_node\" ]]; then\n  echo -e \"Обновление Node.js: ${RED}$current_node${NC} → ${GREEN}${latest_node}${NC}\"\n  sed -i \"s/NODE_VERSION=$current_node/NODE_VERSION=$latest_node/\" \"$DOCKERFILE_PATH\"\n  update_needed=true\nfi\n\nif [[ \"$current_pnpm\" != \"$latest_pnpm\" ]] && [[ -n \"$latest_pnpm\" ]] && [[ \"$latest_pnpm\" != \"null\" ]]; then\n  echo -e \"Обновление pnpm: ${RED}$current_pnpm${NC} to ${GREEN}${latest_pnpm}${NC}\"\n  sed -i \"s/PNPM_VERSION=$current_pnpm/PNPM_VERSION=$latest_pnpm/\" \"$DOCKERFILE_PATH\"\n  update_needed=true\nfi\n\nif [ \"$update_needed\" = true ]; then\n  echo -e \"Удаляем все старые образы\"\n  podman rmi --all --force\n  echo -e \"Перезапускаем LanguageTool\"\n  systemctl restart --user languagetool.service\n  echo -e \"${NC}Создаём новый базовый образ Dev Container${GRAY}\"\n  ~/Dev/environment/bin/build-devcontainer\nelse\n  echo -e \"${GRAY}Нет обновлений для Dev Container${NC}\"\nfi\n"
  },
  {
    "path": "bin/update-extension-lists",
    "content": "#!/usr/bin/env node\n\nlet { readFile, writeFile } = require('fs/promises')\nlet { join } = require('path')\nlet { promisify } = require('util')\nlet { exec } = require('child_process')\n\nexec = promisify(exec)\n\nfunction gray(str) {\n  return `\\x1b[90m${str}\\x1b[39m`\n}\n\nasync function updateGnome() {\n  let listFile = join(__dirname, '..', 'GNOME.md')\n  let [gnome, docs] = await Promise.all([\n    exec(`gnome-extensions list`),\n    readFile(listFile)\n  ])\n  let meta = await Promise.all(\n    gnome.stdout\n      .trim()\n      .split('\\n')\n      .map(async name => exec(`LANG=en gnome-extensions show ${name}`))\n  )\n  let details = await Promise.all(\n    meta\n      .map(result => {\n        let uuid = result.stdout.split('\\n')[0]\n        let enabled = result.stdout.includes('State: ACTIVE')\n        let name = result.stdout.match(/Name: (.*)/)[1]\n        let hasRepo = result.stdout.match(/URL: (.*)/)\n        return { uuid, name, enabled, hasRepo }\n      })\n      .filter(({ enabled, hasRepo, name }) => {\n        if (!hasRepo) {\n          console.log(gray(`Игнорируем ${name}`))\n        }\n        return hasRepo\n      })\n      .map(async ({ name, uuid }) => {\n        let response = await fetch(\n          `https://extensions.gnome.org/extension-query/?` +\n            `sort=relevance&` +\n            `page=1&` +\n            `shell_version=all&` +\n            `search=${encodeURIComponent(name)}`\n        )\n        if (!response.ok) {\n          process.stderr.write(`Response ${response.status} for ${name}`)\n          process.stderr.write(gray(`\\n${await response.text()}\\n`))\n          response = await fetch(\n            `https://extensions.gnome.org/extension-query/?` +\n              `sort=relevance&` +\n              `page=1&` +\n              `shell_version=all&` +\n              `search=${encodeURIComponent(name)}`)\n          if (!response.ok) process.exit(1)\n        }\n        let json = await response.json()\n        let extension = json.extensions.find(i => i.uuid === uuid)\n        if (!extension) {\n          throw new Error(`Расширение не найдено: ${name} (${uuid})`)\n        }\n        return {\n          name: extension.name,\n          url: `https://extensions.gnome.org${extension.link}`\n        }\n      })\n  )\n  let extensions = details\n    .map(({ name, url }) => ({ url, name: name.replace(/\\[.*\\]\\s*/, '') }))\n    .sort((a, b) => a.name.localeCompare(b.name))\n    .map(({ name, url }) => `- [${name}](${url})`)\n    .join('\\n')\n  let cleaned = docs\n    .toString()\n    .split('\\n')\n    .filter(line => line && !line.startsWith('-'))\n    .join('\\n')\n  await writeFile(listFile, cleaned + '\\n\\n' + extensions + '\\n')\n}\n\nupdateGnome()\n"
  },
  {
    "path": "bin/zed-isolate",
    "content": "#!/bin/bash\n\nset -e\n\nLOG_FILE=\"/var/run/user/1000/zed-isolate.log\"\n\nshow_error_log() {\n  if [ -f \"$LOG_FILE\" ]; then\n    zenity --text-info \\\n        --title=\"Dev Container Error\" \\\n        --font=\"Lilex Regular 12\" \\\n        --width=800 \\\n        --height=600 \\\n        --filename=\"$LOG_FILE\" 2>/dev/null\n  fi\n  exit 1\n}\n\ntrap show_error_log ERR\n\nexec > \"$LOG_FILE\" 2>&1\n\nif [ \"$1\" != \"\" ]; then\n  cd \"$1\"\nfi\n\nif [ -f .devcontainer.json ]; then\n  config=\"$(pwd)/.devcontainer.json\"\nfi\nif [ -f .devcontainer/devcontainer.json ]; then\n  config=\"$(pwd)/.devcontainer/devcontainer.json\"\nfi\nif [ \"$config\" == \"\" ]; then\n  echo \"Dev Container is disabled because of lack of Dev Container config\"\n  zed --new ./\n  exit 0\nfi\n\nexport PATH=\"/home/ai/.local/lib/node/node_modules/.bin/:$PATH\"\n\necho \"Starting Dev Container\"\n~/Dev/environment/bin/dev --up | \\\n  zenity --progress --text=\"Starting\" --title=\"Dev Container\" --pulsate --auto-close --no-cancel\n\ncontainer_id=$(podman ps -q --filter label=devcontainer.local_folder=$(pwd))\n\nif [ \"$container_id\" == \"\" ]; then\n  echo \"ERROR: Running container was not found\"\n  show_error_log\n  exit 1\nfi\n\nzed --new --dev-container . --wait\n\n~/Dev/environment/bin/dev --down\n"
  },
  {
    "path": "bin/zoom",
    "content": "#!/bin/zsh\n\nsource ~/Dev/environment/secrets.env\n\ncall_scene() {\n  curl -s -S -f \\\n    -H \"Authorization: Bearer $HA_TOKEN\" \\\n    -H \"Content-Type: application/json\" \\\n    -d \"{\\\"entity_id\\\": \\\"$1\\\"}\" \\\n    \"https://home.local/api/services/scene/turn_on\" || true\n}\n\ncall_scene \"scene.andrey_calling\"\n\nzoom \"$@\"\n\ncall_scene \"scene.andrey_working_night\"\n"
  },
  {
    "path": "devcontainer/Dockerfile",
    "content": "FROM registry.fedoraproject.org/fedora:44\n\nENV NODE_VERSION=25.9.0 \\\n  PNPM_VERSION=11.0.0 \\\n  NODE_24=24.15.0 \\\n  NODE_22=22.22.2 \\\n  DIFFT_VERSION=0.68.0 \\\n  BAT_VERSION=0.26.1 \\\n  RG_VERSION=15.1.0 \\\n  ATUIN_VERSION=18.16.0 \\\n  STARSHIP_VERSION=1.25.0 \\\n  PNPM_COMPETITION_VERSION=0.5.5\n\nADD https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz /node.tar.xz\nADD https://nodejs.org/dist/v${NODE_24}/node-v${NODE_24}-linux-x64.tar.gz /node24.tar.xz\nADD https://nodejs.org/dist/v${NODE_22}/node-v${NODE_22}-linux-x64.tar.gz /node22.tar.xz\nADD https://github.com/pnpm/pnpm/releases/download/v$PNPM_VERSION/pnpm-linux-x64.tar.gz /pnpm.tar.gz\nADD https://github.com/eza-community/eza/releases/latest/download/eza_x86_64-unknown-linux-musl.tar.gz /eza.tar.gz\nADD https://github.com/Wilfred/difftastic/releases/download/$DIFFT_VERSION/difft-x86_64-unknown-linux-musl.tar.gz /difft.tar.gz\nADD https://github.com/sharkdp/bat/releases/download/v$BAT_VERSION/bat-v$BAT_VERSION-x86_64-unknown-linux-musl.tar.gz /bat.tar.gz\nADD https://github.com/BurntSushi/ripgrep/releases/download/$RG_VERSION/ripgrep-$RG_VERSION-x86_64-unknown-linux-musl.tar.gz /rg.tar.gz\nADD https://github.com/atuinsh/atuin/releases/download/v$ATUIN_VERSION/atuin-x86_64-unknown-linux-musl.tar.gz /atuin.tar.gz\nADD https://github.com/starship/starship/releases/download/v$STARSHIP_VERSION/starship-x86_64-unknown-linux-musl.tar.gz /starship.tar.gz\nADD https://github.com/g-plane/pnpm-shell-completion/releases/download/v$PNPM_COMPETITION_VERSION/pnpm-shell-completion_x86_64-unknown-linux-musl.tar.gz /pnpm-completion.tar.gz\n\nRUN dnf install -yq zsh micro git tig make awk psmisc procps-ng curl \\\n  bind-utils iputils iproute libatomic nss dbus-libs atk at-spi2-atk cups-libs \\\n  libdrm libXcomposite libXdamage libXrandr mesa-libgbm pango alsa-lib \\\n  && dnf clean all \\\n  && rm -rf /var/cache/dnf\n\nRUN mkdir /usr/local/share/pnpm \\\n  && tar -xz -f /pnpm.tar.gz -C /usr/local/share/pnpm \\\n  && ln -s /usr/local/share/pnpm/pnpm /usr/local/bin/pnpm \\\n  && rm /pnpm.tar.gz \\\n  \\\n  && tar -xz -f /node.tar.xz -C /usr/local --remove-files --strip-components=1 \\\n  --exclude='*.md' --exclude='LICENSE' \\\n  --exclude='share' --exclude='bin/corepack' \\\n  && rm /node.tar.xz \\\n  \\\n  && tar -xzf /node24.tar.xz -O \"node-v$NODE_24-linux-x64/bin/node\" > /usr/local/bin/node24 \\\n  && tar -xzf /node22.tar.xz -O \"node-v$NODE_22-linux-x64/bin/node\" > /usr/local/bin/node22 \\\n  && chmod a+rx /usr/local/bin/node24 \\\n  && chmod a+rx /usr/local/bin/node22 \\\n  \\\n  && tar -xz -f /eza.tar.gz \\\n  && mv eza /usr/local/bin/eza \\\n  && chmod +x /usr/local/bin/eza \\\n  && rm /eza.tar.gz \\\n  \\\n  && tar -xz -f /difft.tar.gz \\\n  && mv difft /usr/local/bin/difft \\\n  && chmod +x /usr/local/bin/difft \\\n  && rm /difft.tar.gz \\\n  \\\n  && tar -xz -f /bat.tar.gz --strip-components=1 bat-v$BAT_VERSION-x86_64-unknown-linux-musl/bat \\\n  && mv bat /usr/local/bin/bat \\\n  && chmod +x /usr/local/bin/bat \\\n  && rm /bat.tar.gz \\\n  \\\n  && tar -xz -f /rg.tar.gz --strip-components=1 ripgrep-$RG_VERSION-x86_64-unknown-linux-musl/rg \\\n  && mv rg /usr/local/bin/rg \\\n  && chmod +x /usr/local/bin/rg \\\n  && rm /rg.tar.gz \\\n  \\\n  && tar -xz -f /atuin.tar.gz --strip-components=1 atuin-x86_64-unknown-linux-musl/atuin \\\n  && mv atuin /usr/local/bin/atuin \\\n  && chmod +x /usr/local/bin/atuin \\\n  && rm /atuin.tar.gz \\\n  \\\n  && tar -xz -f /starship.tar.gz \\\n  && mv starship /usr/local/bin/starship \\\n  && chmod +x /usr/local/bin/starship \\\n  && rm /starship.tar.gz \\\n  \\\n  && mkdir -p /usr/local/lib/zsh \\\n  && git clone -q https://github.com/zsh-users/zsh-syntax-highlighting /usr/local/lib/zsh/zsh-syntax-highlighting \\\n  && git clone https://github.com/zsh-users/zsh-autosuggestions /usr/local/lib/zsh/zsh-autosuggestions \\\n  && git clone https://github.com/jimhester/per-directory-history /usr/local/lib/zsh/per-directory-history \\\n  && mkdir -p /usr/local/lib/zsh/pnpm-shell-completion \\\n  && tar -xz -f /pnpm-completion.tar.gz -C /usr/local/lib/zsh/pnpm-shell-completion pnpm-shell-completion pnpm-shell-completion.plugin.zsh \\\n  && chmod a+x /usr/local/lib/zsh/pnpm-shell-completion/pnpm-shell-completion \\\n  && rm /pnpm-completion.tar.gz \\\n  \\\n  && useradd -s /bin/zsh ai\n\nRUN echo '{\"arrowParens\":\"avoid\",\"jsxSingleQuote\":false,\"quoteProps\":\"consistent\",\"semi\":false,\"singleQuote\":true,\"sortImports\":{\"groups\":[\"side_effect\",\"side_effect_style\",\"style\",[\"builtin\",\"external\",\"unknown\"],[\"internal\",\"parent\",\"sibling\",\"index\"]],\"newlinesBetween\":true,\"order\":\"asc\"},\"trailingComma\":\"none\",\"printWidth\":80}' > /.oxfmtrc.json\n\nUSER ai\n\nRUN micro -plugin install editorconfig \\\n  && mkdir -p /home/ai/.local/share/pnpm/\n\nVOLUME /home/ai/.local/share/pnpm/store\nVOLUME /home/ai/.shell-history\n"
  },
  {
    "path": "devcontainer/devcontainer.json",
    "content": "{\n  \"image\": \"localhost/ai-opensource:latest\",\n  \"mounts\": [\n    {\n      \"source\": \"pnpm-store\",\n      \"target\": \"/home/ai/.local/share/pnpm/store\",\n      \"type\": \"volume\",\n    },\n    {\n      \"source\": \"shell-history\",\n      \"target\": \"/home/ai/.local/share/history/\",\n      \"type\": \"volume\",\n    },\n  ],\n  \"runArgs\": [\"--net=bridge\"],\n}\n"
  },
  {
    "path": "devcontainer/install-dotfiles",
    "content": "#!/bin/sh\n\nMICRO_VERSION=\"2.0.15\"\nDIFFT_VERSION=\"0.68.0\"\nBAT_VERSION=\"0.26.1\"\nRG_VERSION=\"15.1.0\"\nATUIN_VERSION=\"18.13.3\"\nSTARSHIP_VERSION=\"1.24.2\"\nPNPM_COMPETITION_VERSION=\"0.5.5\"\n\nARCH=$(uname -m)\necho \"Detected architecture: $ARCH\"\ncase \"$ARCH\" in\n  x86_64)\n    ARCH_SUFFIX=\"x86_64-unknown-linux-musl\"\n    ;;\n  aarch64)\n    ARCH_SUFFIX=\"aarch64-unknown-linux-gnu\"\n    ;;\n  *)\n    echo \"Unsupported architecture: $ARCH\"\n    exit 1\n    ;;\nesac\n\nmkdir -p ~/.config/micro\nmkdir -p ~/.config/bat\nmkdir -p ~/.config/git\nmkdir -p ~/.config/pnpm\n\ncp -f ~/dotfiles/zshrc ~/.zshrc\ncp -f ~/dotfiles/gitconfig ~/.config/git/config\ncp -f ~/dotfiles/ripgreprc ~/.config/ripgreprc\ncp -f ~/dotfiles/micro.json ~/.config/micro/settings.json\ncp -f ~/dotfiles/batconfig ~/.config/bat/config\ncp -f ~/dotfiles/gitignore ~/.config/git/ignore\ncp -f ~/dotfiles/starship.toml ~/.config/starship.toml\ncp -f ~/dotfiles/pnpm-config.yaml ~/.config/pnpm/config.yaml\nsed -i '/^\\s*\\$username\\\\/d;/^\\s*\\$hostname\\\\/d' ~/.config/starship.toml\n\ngit config set core.hooksPath \".git/hooks\"\n\nmkdir -p ~/.ssh\nchmod 700 ~/.ssh\necho \"github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl\" > ~/.ssh/known_hosts\necho \"github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=\" > ~/.ssh/known_hosts\necho \"github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=\" > ~/.ssh/known_hosts\nchmod 600 ~/.ssh/known_hosts\n\nmkdir -p ~/.local/share/history/\ntouch ~/.local/share/history/histfile\nmkdir -p ~/.local/bin\n\ncmd_exists() {\n  command -v \"$1\" >/dev/null 2>&1\n}\n\nmiss_lib() {\n  [ ! -d ~/.local/lib/$1 ] && [ ! -d /usr/local/lib/$1 ]\n}\n\nif ! cmd_exists micro; then\n  if [ \"$ARCH\" = \"x86_64\" ]; then\n    MICRO_ARCH=\"linux64-static\"\n  else\n    MICRO_ARCH=\"linux-arm64\"\n  fi\n  curl -sL https://github.com/zyedidia/micro/releases/download/v$MICRO_VERSION/micro-$MICRO_VERSION-$MICRO_ARCH.tar.gz | tar xz\n  mv micro-$MICRO_VERSION/micro ~/.local/bin\n  chmod +x ~/.local/bin/micro\n  rm -rf micro-$MICRO_VERSION\nfi\n\nif [ ! -d ~/.config/micro/plug/editorconfig ]; then\n  if cmd_exists micro; then\n    micro -plugin install editorconfig\n  elif [ -f ~/.local/bin/micro ]; then\n    ~/.local/bin/micro -plugin install editorconfig\n  fi\nfi\n\nif ! cmd_exists eza; then\n  curl -sL https://github.com/eza-community/eza/releases/latest/download/eza_$ARCH_SUFFIX.tar.gz | tar xz\n  chmod +x eza\n  mv eza ~/.local/bin\nfi\n\nif ! cmd_exists difft; then\n  curl -sL https://github.com/Wilfred/difftastic/releases/download/$DIFFT_VERSION/difft-$ARCH_SUFFIX.tar.gz | tar xz\n  chmod +x difft\n  mv difft ~/.local/bin\nfi\n\nif ! cmd_exists bat; then\n  curl -sL https://github.com/sharkdp/bat/releases/download/v$BAT_VERSION/bat-v$BAT_VERSION-$ARCH_SUFFIX.tar.gz | tar xz --strip-components=1 bat-v$BAT_VERSION-$ARCH_SUFFIX/bat\n  chmod +x bat\n  mv bat ~/.local/bin\nfi\n\nif ! cmd_exists rg; then\n  curl -sL https://github.com/BurntSushi/ripgrep/releases/download/$RG_VERSION/ripgrep-$RG_VERSION-$ARCH_SUFFIX.tar.gz | tar xz --strip-components=1 ripgrep-$RG_VERSION-$ARCH_SUFFIX/rg\n  chmod +x rg\n  mv rg ~/.local/bin\nfi\n\nif ! cmd_exists atuin; then\n  curl -sL https://github.com/atuinsh/atuin/releases/download/v$ATUIN_VERSION/atuin-$ARCH_SUFFIX.tar.gz | tar xz --strip-components=1 atuin-$ARCH_SUFFIX/atuin\n  chmod +x atuin\n  mv atuin ~/.local/bin\nfi\n\nif [ ! -f ~/.local/bin/starship ] && [ ! -f /usr/local/bin/starship ]; then\n  if [ \"$ARCH\" = \"x86_64\" ]; then\n    MICRO_ARCH=\"$ARCH_SUFFIX\"\n  else\n    MICRO_ARCH=\"aarch64-unknown-linux-musl\"\n  fi\n  curl -sL https://github.com/starship/starship/releases/download/v$STARSHIP_VERSION/starship-$MICRO_ARCH.tar.gz | tar xz\n  chmod +x starship\n  mv starship ~/.local/bin\nfi\n\nmkdir -p ~/.local/lib/zsh\nif cmd_exists git && cmd_exists zsh; then\n  if miss_lib zsh/zsh-syntax-highlighting; then\n    git clone -q https://github.com/zsh-users/zsh-syntax-highlighting \\\n      ~/.local/lib/zsh/zsh-syntax-highlighting\n  fi\n\n  if miss_lib zsh/zsh-autosuggestions; then\n    git clone https://github.com/zsh-users/zsh-autosuggestions \\\n      ~/.local/lib/zsh/zsh-autosuggestions\n  fi\n\n  if miss_lib zsh/per-directory-history; then\n    git clone https://github.com/jimhester/per-directory-history \\\n      ~/.local/lib/zsh/per-directory-history\n  fi\n\n  if miss_lib zsh/pnpm-shell-completion; then\n    mkdir -p ~/.local/lib/zsh/pnpm-shell-completion\n    curl -sSL https://github.com/g-plane/pnpm-shell-completion/releases/download/v$PNPM_COMPETITION_VERSION/pnpm-shell-completion_$ARCH_SUFFIX.tar.gz > ~/pnpm-completion.tar.gz\n    tar -xzf ~/pnpm-completion.tar.gz \\\n      -C ~/.local/lib/zsh/pnpm-shell-completion \\\n      pnpm-shell-completion pnpm-shell-completion.plugin.zsh\n    chmod a+x ~/.local/lib/zsh/pnpm-shell-completion/pnpm-shell-completion\n    rm ~/pnpm-completion.tar.gz\n  fi\nfi\n"
  },
  {
    "path": "gitconfig",
    "content": "[user]\n  name  = Andrey Sitnik\n  email = andrey@sitnik.es\n  signingKey = key::ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHfKri8pwCoINL3A88gGpZDjt3jyfxrIoYfQ8gaY3AoQ andrey@sitnik.es\n[alias]\n  current-branch = \"!git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \\\\(.*\\\\)/\\\\1/'\"\n  a  = \"!git add . && git s\"\n  ch = \"!echo 'Stop using git checkout' && false\"\n  c  = commit -S -m\n  s  = status --short --branch\n  d  = diff\n  l  = \"!git pull origin $(git current-branch) --rebase\"\n  h  = \"!git push origin $(git current-branch)\"\n  lh = \"!git l && git h\"\n  r  = \"!git rm $(git ls-files --deleted) && git status\"\n  hf = push --force-with-lease\n  sw = switch\n[color]\n  diff   = auto\n  status = auto\n  branch = auto\n[branch]\n  autosetuprebase = always\n[core]\n  autocrlf = input\n  editor = micro\n[init]\n  defaultBranch = main\n[gpg]\n  format = ssh\n[commit]\n  gpgsign = true\n[push]\n  default = current\n  followtags = true\n[rerere]\n  enabled = true\n[diff]\n  external = difft\n  algorithm = histogram\n  colorMoved = true\n  indentHeuristic = true\n"
  },
  {
    "path": "gitignore",
    "content": ".pnpm-*.log\n.npm-release/\n.zed\n.eslintcache\n.claude\n"
  },
  {
    "path": "hooks-trap/applypatch-msg",
    "content": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" ]; then\n  if [ -x \"$project_hooks/applypatch-msg\" ]; then\n    /home/ai/Dev/environment/bin/dev CI=1 $project_hooks/applypatch-msg\n  fi\nfi\n"
  },
  {
    "path": "hooks-trap/commit-msg",
    "content": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" ]; then\n  if [ -x \"$project_hooks/commit-msg\" ]; then\n    /home/ai/Dev/environment/bin/dev CI=1 $project_hooks/commit-msg\n  fi\nfi\n"
  },
  {
    "path": "hooks-trap/post-applypatch",
    "content": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" ]; then\n  if [ -x \"$project_hooks/post-applypatch\" ]; then\n    /home/ai/Dev/environment/bin/dev CI=1 $project_hooks/post-applypatch\n  fi\nfi\n"
  },
  {
    "path": "hooks-trap/post-checkout",
    "content": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" ]; then\n  if [ -x \"$project_hooks/post-checkout\" ]; then\n    /home/ai/Dev/environment/bin/dev CI=1 $project_hooks/post-checkout\n  fi\nfi\n"
  },
  {
    "path": "hooks-trap/post-commit",
    "content": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" ]; then\n  if [ -x \"$project_hooks/post-commit\" ]; then\n    /home/ai/Dev/environment/bin/dev CI=1 $project_hooks/post-commit\n  fi\nfi\n"
  },
  {
    "path": "hooks-trap/post-merge",
    "content": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" ]; then\n  if [ -x \"$project_hooks/post-merge\" ]; then\n    /home/ai/Dev/environment/bin/dev CI=1 $project_hooks/post-merge\n  fi\nfi\n"
  },
  {
    "path": "hooks-trap/post-rewrite",
    "content": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" ]; then\n  if [ -x \"$project_hooks/post-rewrite\" ]; then\n    /home/ai/Dev/environment/bin/dev CI=1 $project_hooks/post-rewrite\n  fi\nfi\n"
  },
  {
    "path": "hooks-trap/pre-applypatch",
    "content": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" ]; then\n  if [ -x \"$project_hooks/pre-applypatch\" ]; then\n    /home/ai/Dev/environment/bin/dev CI=1 $project_hooks/pre-applypatch\n  fi\nfi\n"
  },
  {
    "path": "hooks-trap/pre-auto-gc",
    "content": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" ]; then\n  if [ -x \"$project_hooks/pre-auto-gc\" ]; then\n    /home/ai/Dev/environment/bin/dev CI=1 $project_hooks/pre-auto-gc\n  fi\nfi\n"
  },
  {
    "path": "hooks-trap/pre-commit",
    "content": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" ]; then\n  if [ -x \"$project_hooks/pre-commit\" ]; then\n    /home/ai/Dev/environment/bin/dev CI=1 $project_hooks/pre-commit\n  fi\nfi\n"
  },
  {
    "path": "hooks-trap/pre-merge-commit",
    "content": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" ]; then\n  if [ -x \"$project_hooks/pre-merge-commit\" ]; then\n    /home/ai/Dev/environment/bin/dev CI=1 $project_hooks/pre-merge-commit\n  fi\nfi\n"
  },
  {
    "path": "hooks-trap/pre-push",
    "content": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" ]; then\n  if [ -x \"$project_hooks/pre-push\" ]; then\n    /home/ai/Dev/environment/bin/dev CI=1 $project_hooks/pre-push\n  fi\nfi\n"
  },
  {
    "path": "hooks-trap/pre-rebase",
    "content": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" ]; then\n  if [ -x \"$project_hooks/pre-rebase\" ]; then\n    /home/ai/Dev/environment/bin/dev CI=1 $project_hooks/pre-rebase\n  fi\nfi\n"
  },
  {
    "path": "hooks-trap/prepare-commit-msg",
    "content": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" ]; then\n  if [ -x \"$project_hooks/prepare-commit-msg\" ]; then\n    /home/ai/Dev/environment/bin/dev CI=1 $project_hooks/prepare-commit-msg\n  fi\nfi\n"
  },
  {
    "path": "icons/Zoom.desktop",
    "content": "[Desktop Entry]\nName=Zoom\nComment=Zoom Video Conference\nExec=/home/ai/Dev/environment/bin/zoom @@u %U @@\nIcon=Zoom\nTerminal=false\nType=Application\nEncoding=UTF-8\nCategories=Network;Application;\nStartupWMClass=zoom\nMimeType=x-scheme-handler/zoommtg;x-scheme-handler/zoomus;x-scheme-handler/tel;x-scheme-handler/callto;x-scheme-handler/zoomphonecall;x-scheme-handler/zoomphonesms;x-scheme-handler/zoomcontactcentercall;application/x-zoom\nX-KDE-Protocols=zoommtg;zoomus;tel;callto;zoomphonecall;zoomphonesms;zoomcontactcentercall;\nName[en_US]=Zoom\n"
  },
  {
    "path": "icons/backup.desktop",
    "content": "[Desktop Entry]\nType=Application\nName=Резервное копирование\nComment=Backup\nIcon=/home/ai/.local/share/applications/backup.svg\nExec=flatpak run app.devsuite.Ptyxis -- /home/ai/Dev/environment/bin/backup\nPrefersNonDefaultGPU=false\nHidden=false\nNoDisplay=false\nStartupNotify=false\nTerminal=false\n"
  },
  {
    "path": "icons/com.mattjakeman.ExtensionManager.desktop",
    "content": "[Desktop Entry]\nName=Расширения\nExec=/usr/bin/flatpak run --branch=stable --arch=x86_64 --command=extension-manager --file-forwarding com.mattjakeman.ExtensionManager @@u %U @@\nIcon=com.mattjakeman.ExtensionManager\nTerminal=false\nType=Application\nCategories=GTK;Utility\nOnlyShowIn=GNOME;\nStartupNotify=true\nMimeType=x-scheme-handler/gnome-extensions;\nComment=Управление расширениями GNOME Shell\nKeywords=extension;manager;shell;менеджер;расширение;\nX-Flatpak=com.mattjakeman.ExtensionManager\nPrefersNonDefaultGPU=false\nHidden=false\nNoDisplay=false\n"
  },
  {
    "path": "icons/com.nextcloud.desktopclient.nextcloud.desktop",
    "content": "[Desktop Entry]\nCategories=Utility;X-SuSE-SyncUtility;\nType=Application\nExec=nextcloud %u\nName=Nextcloud\nComment=Настольный клиент синхронизации Nextcloud\nGenericName=Folder Sync\nIcon=Nextcloud\nKeywords=Nextcloud;syncing;file;sharing;\nX-GNOME-Autostart-Delay=3\nMimeType=application/vnd.nextcloud;x-scheme-handler/nc;\nSingleMainWindow=true\nActions=Quit;\nImplements=org.freedesktop.CloudProviders\nPrefersNonDefaultGPU=false\nHidden=false\nNoDisplay=false\nStartupNotify=false\nTerminal=false\n\n[org.freedesktop.CloudProviders]\nBusName=com.nextcloudgmbh.Nextcloud\nObjectPath=/com/nextcloudgmbh/Nextcloud\n\n[Desktop Action Quit]\nExec=nextcloud --quit\nName=Quit Nextcloud\nIcon=nextcloud\nName[ru]=Quit Nextcloud\nName[ru_RU]=Quit Nextcloud\nName[ru_RU.UTF-8]=Quit Nextcloud\n"
  },
  {
    "path": "icons/hu.irl.cameractrls.desktop",
    "content": "[Desktop Entry]\nType=Application\nVersion=1.0\nName=Настройки камеры\nComment=Camera controls for Linux\nExec=/usr/bin/flatpak run --branch=stable --arch=x86_64 --command=cameractrlsgtk.py hu.irl.cameractrls\nIcon=hu.irl.cameractrls\nTerminal=false\nCategories=Settings;AudioVideo;Video;Office;Utility;GNOME;GTK;\nKeywords=picture;photos;camera;webcam;\nX-Flatpak=hu.irl.cameractrls\nPrefersNonDefaultGPU=false\nHidden=false\nNoDisplay=false\nStartupNotify=false\n"
  },
  {
    "path": "icons/porn.desktop",
    "content": "[Desktop Entry]\nType=Application\nName=Эротика\nComment=Play porn movies\nIcon=strawberry\nExec=/home/ai/Dev/environment/bin/porn\nActions=New;\nName[ru]=Эротика\nName[ru_RU]=Эротика\nName[ru_RU.UTF-8]=Эротика\nComment[ru]=Play porn movies\nComment[ru_RU]=Play porn movies\nComment[ru_RU.UTF-8]=Play porn movies\nPrefersNonDefaultGPU=false\nHidden=false\nNoDisplay=false\nStartupNotify=false\nTerminal=false\n\n[Desktop Action New]\nName=Новое\nExec=/home/ai/Dev/environment/bin/porn --new\n"
  },
  {
    "path": "icons/private.desktop",
    "content": "[Desktop Entry]\nType=Application\nName=Личная папка\nComment=Decrypt safe storage\nIcon=/home/ai/.local/share/applications/private.svg\nExec=/home/ai/Dev/environment/bin/private\n"
  },
  {
    "path": "icons/update.desktop",
    "content": "[Desktop Entry]\nType=Application\nName=Обновление системы\nComment=Update RPM, Flatpak, and Mozilla Theme\nIcon=org.fedoraproject.AnacondaInstaller\nExec=flatpak run app.devsuite.Ptyxis -- /home/ai/Dev/environment/bin/update\n"
  },
  {
    "path": "icons/zed-isolate.desktop",
    "content": "[Desktop Entry]\nType=Application\nName=Zed Dev Container\nIcon=zed\nExec=/home/ai/Dev/environment/bin/zed-isolate %U\nMimeType=inode/directory;\nCategories=Utility;TextEditor;Development;IDE;\n"
  },
  {
    "path": "micro.json",
    "content": "{\n    \"colorscheme\": \"simple\",\n    \"mkparents\": true\n}\n"
  },
  {
    "path": "mimeapps.list",
    "content": "[Added Associations]\nx-scheme-handler/sms=org.gnome.Shell.Extensions.GSConnect.desktop;\nx-scheme-handler/tel=org.gnome.Shell.Extensions.GSConnect.desktop;\nimage/jpeg=org.gimp.GIMP.desktop;org.gnome.Loupe.desktop;\nimage/avif=org.gnome.eog.desktop;org.gimp.GIMP.desktop;org.gnome.Loupe.desktop;\nimage/webp=org.gnome.eog.desktop;\nimage/svg+xml=zed.desktop;\napplication/x-bittorrent=io.github.TransmissionRemoteGtk.desktop;\nimage/png=org.gimp.GIMP.desktop;org.gnome.Loupe.desktop;\nimage/heif=org.gimp.GIMP.desktop;org.gnome.Loupe.desktop;\ntext/vnd.trolltech.linguist=mpv.desktop;zed.desktop;\nfont/ttf=org.gnome.font-viewer.desktop;\nx-scheme-handler/http=org.mozilla.firefox.desktop;\ntext/html=org.mozilla.firefox.desktop;\napplication/xhtml+xml=org.mozilla.firefox.desktop;\nx-scheme-handler/https=org.mozilla.firefox.desktop;\naudio/aac=mpv.desktop;\naudio/x-aac=mpv.desktop;\naudio/vnd.dolby.heaac.1=mpv.desktop;\naudio/vnd.dolby.heaac.2=mpv.desktop;\naudio/aiff=mpv.desktop;\naudio/x-aiff=mpv.desktop;\naudio/m4a=mpv.desktop;\naudio/x-m4a=mpv.desktop;\naudio/mp1=mpv.desktop;\naudio/x-mp1=mpv.desktop;\naudio/mp2=mpv.desktop;\naudio/x-mp2=mpv.desktop;\naudio/mp3=mpv.desktop;\naudio/x-mp3=mpv.desktop;\naudio/mpeg=mpv.desktop;\naudio/mpeg2=mpv.desktop;\naudio/mpeg3=mpv.desktop;\naudio/mpegurl=mpv.desktop;\naudio/x-mpegurl=mpv.desktop;\naudio/mpg=mpv.desktop;\naudio/x-mpg=mpv.desktop;\naudio/rn-mpeg=mpv.desktop;\naudio/musepack=mpv.desktop;\naudio/x-musepack=mpv.desktop;\naudio/ogg=mpv.desktop;\naudio/scpls=mpv.desktop;\naudio/x-scpls=mpv.desktop;\naudio/vnd.rn-realaudio=mpv.desktop;\naudio/wav=mpv.desktop;\naudio/x-pn-wav=mpv.desktop;\naudio/x-pn-windows-pcm=mpv.desktop;\naudio/x-realaudio=mpv.desktop;\naudio/x-pn-realaudio=mpv.desktop;org.gnome.Totem.desktop;\naudio/x-ms-wma=mpv.desktop;\naudio/x-pls=mpv.desktop;\naudio/x-wav=mpv.desktop;\naudio/x-ms-asf=mpv.desktop;\naudio/x-matroska=mpv.desktop;\naudio/webm=mpv.desktop;\naudio/vorbis=mpv.desktop;\naudio/x-vorbis=mpv.desktop;\naudio/x-shorten=mpv.desktop;\naudio/x-ape=mpv.desktop;\naudio/x-wavpack=mpv.desktop;\naudio/x-tta=mpv.desktop;\naudio/AMR=mpv.desktop;\naudio/ac3=mpv.desktop;\naudio/eac3=mpv.desktop;\naudio/amr-wb=mpv.desktop;\naudio/flac=mpv.desktop;\naudio/mp4=mpv.desktop;\naudio/x-pn-au=mpv.desktop;\naudio/3gpp=mpv.desktop;\naudio/3gpp2=mpv.desktop;\naudio/dv=mpv.desktop;\naudio/opus=mpv.desktop;\naudio/vnd.dts=mpv.desktop;\naudio/vnd.dts.hd=mpv.desktop;\naudio/x-adpcm=mpv.desktop;\naudio/m3u=mpv.desktop;\naudio/x-vorbis+ogg=org.gnome.Totem.desktop;\nvideo/x-mpeg2=mpv.desktop;\nvideo/x-mpeg3=mpv.desktop;\nvideo/mp4v-es=mpv.desktop;\nvideo/x-m4v=mpv.desktop;\nvideo/divx=mpv.desktop;\nvideo/vnd.divx=mpv.desktop;\nvideo/msvideo=mpv.desktop;\nvideo/ogg=mpv.desktop;\nvideo/vnd.rn-realvideo=mpv.desktop;\nvideo/x-ms-afs=mpv.desktop;\nvideo/x-ms-asf=mpv.desktop;\nvideo/x-ms-wmx=mpv.desktop;\nvideo/x-ms-wvxvideo=mpv.desktop;\nvideo/x-avi=mpv.desktop;\nvideo/avi=mpv.desktop;\nvideo/x-flic=mpv.desktop;\nvideo/fli=mpv.desktop;\nvideo/x-flc=mpv.desktop;\nvideo/flv=mpv.desktop;\nvideo/x-theora=mpv.desktop;\nvideo/x-theora+ogg=mpv.desktop;\nvideo/mkv=mpv.desktop;\nvideo/x-ogm=mpv.desktop;\nvideo/vnd.mpegurl=mpv.desktop;\nvideo/3gp=mpv.desktop;\nvideo/3gpp2=mpv.desktop;\nvideo/dv=mpv.desktop;\napplication/xml=zed.desktop;\napplication/zip=org.gnome.Nautilus.desktop;\napplication/pdf=org.gnome.Papers.desktop;\nx-scheme-handler/gnome-extensions=com.mattjakeman.ExtensionManager.desktop;\napplication/vnd.nextcloud=com.nextcloud.desktopclient.nextcloud.desktop;\nx-scheme-handler/nc=com.nextcloud.desktopclient.nextcloud.desktop;\ntext/x-opml+xml=zed.desktop;\napplication/atom+xml=zed.desktop;\napplication/rss+xml=zed.desktop;\n\n[Default Applications]\nvideo/x-matroska=mpv.desktop\nvideo/mp4=mpv.desktop\nvideo/x-ms-wmv=mpv.desktop\nvideo/x-msvideo=mpv.desktop\nvideo/x-flv=mpv.desktop\nvideo/mpeg=mpv.desktop\nvideo/mp2t=mpv.desktop\nvideo/webm=mpv.desktop\nvideo/quicktime=mpv.desktop\napplication/x-bittorrent=io.github.TransmissionRemoteGtk.desktop\ntext/vnd.trolltech.linguist=zed.desktop\nimage/jpeg=org.gnome.Loupe.desktop\nimage/avif=org.gnome.Loupe.desktop\nimage/png=org.gnome.Loupe.desktop\nimage/heif=org.gnome.Loupe.desktop\nfont/ttf=org.gnome.font-viewer.desktop\nvideo/3gpp=mpv.desktop\nx-scheme-handler/http=org.mozilla.firefox.desktop\ntext/html=org.mozilla.firefox.desktop\napplication/xhtml+xml=org.mozilla.firefox.desktop\nx-scheme-handler/https=org.mozilla.firefox.desktop\naudio/x-vorbis+ogg=org.gnome.Totem.desktop\naudio/aac=mpv.desktop\naudio/x-aac=mpv.desktop\naudio/vnd.dolby.heaac.1=mpv.desktop\naudio/vnd.dolby.heaac.2=mpv.desktop\naudio/aiff=mpv.desktop\naudio/x-aiff=mpv.desktop\naudio/m4a=mpv.desktop\naudio/x-m4a=mpv.desktop\naudio/mp1=mpv.desktop\naudio/x-mp1=mpv.desktop\naudio/mp2=mpv.desktop\naudio/x-mp2=mpv.desktop\naudio/mp3=mpv.desktop\naudio/x-mp3=mpv.desktop\naudio/mpeg=mpv.desktop\naudio/mpeg2=mpv.desktop\naudio/mpeg3=mpv.desktop\naudio/mpegurl=mpv.desktop\naudio/x-mpegurl=mpv.desktop\naudio/mpg=mpv.desktop\naudio/x-mpg=mpv.desktop\naudio/rn-mpeg=mpv.desktop\naudio/musepack=mpv.desktop\naudio/x-musepack=mpv.desktop\naudio/ogg=mpv.desktop\naudio/scpls=mpv.desktop\naudio/x-scpls=mpv.desktop\naudio/vnd.rn-realaudio=mpv.desktop\naudio/wav=mpv.desktop\naudio/x-pn-wav=mpv.desktop\naudio/x-pn-windows-pcm=mpv.desktop\naudio/x-realaudio=mpv.desktop\naudio/x-pn-realaudio=org.gnome.Totem.desktop\naudio/x-ms-wma=mpv.desktop\naudio/x-pls=mpv.desktop\naudio/x-wav=mpv.desktop\naudio/x-ms-asf=mpv.desktop\naudio/x-matroska=mpv.desktop\naudio/webm=mpv.desktop\naudio/vorbis=mpv.desktop\naudio/x-vorbis=mpv.desktop\naudio/x-shorten=mpv.desktop\naudio/x-ape=mpv.desktop\naudio/x-wavpack=mpv.desktop\naudio/x-tta=mpv.desktop\naudio/AMR=mpv.desktop\naudio/ac3=mpv.desktop\naudio/eac3=mpv.desktop\naudio/amr-wb=mpv.desktop\naudio/flac=mpv.desktop\naudio/mp4=mpv.desktop\naudio/x-pn-au=mpv.desktop\naudio/3gpp=mpv.desktop\naudio/3gpp2=mpv.desktop\naudio/dv=mpv.desktop\naudio/opus=mpv.desktop\naudio/vnd.dts=mpv.desktop\naudio/vnd.dts.hd=mpv.desktop\naudio/x-adpcm=mpv.desktop\naudio/m3u=mpv.desktop\nvideo/x-ogm+ogg=mpv.desktop\nvideo/x-mpeg2=mpv.desktop\nvideo/x-mpeg3=mpv.desktop\nvideo/mp4v-es=mpv.desktop\nvideo/x-m4v=mpv.desktop\nvideo/divx=mpv.desktop\nvideo/vnd.divx=mpv.desktop\nvideo/msvideo=mpv.desktop\nvideo/ogg=mpv.desktop\nvideo/vnd.rn-realvideo=mpv.desktop\nvideo/x-ms-afs=mpv.desktop\nvideo/x-ms-asf=mpv.desktop\nvideo/x-ms-wmx=mpv.desktop\nvideo/x-ms-wvxvideo=mpv.desktop\nvideo/x-avi=mpv.desktop\nvideo/avi=mpv.desktop\nvideo/x-flic=mpv.desktop\nvideo/fli=mpv.desktop\nvideo/x-flc=mpv.desktop\nvideo/flv=mpv.desktop\nvideo/x-theora=mpv.desktop\nvideo/x-theora+ogg=mpv.desktop\nvideo/mkv=mpv.desktop\nvideo/x-ogm=mpv.desktop\nvideo/vnd.mpegurl=mpv.desktop\nvideo/3gp=mpv.desktop\nvideo/3gpp2=mpv.desktop\nvideo/dv=mpv.desktop\napplication/xml=zed.desktop\napplication/pdf=org.gnome.Papers.desktop\ntext/x-opml+xml=zed.desktop\napplication/atom+xml=zed.desktop\napplication/rss+xml=zed.desktop\n"
  },
  {
    "path": "mpv-input.conf",
    "content": "й quit\nа cycle fullscreen\nMOUSE_BTN3 ignore\nMOUSE_BTN4 ignore\n"
  },
  {
    "path": "mpv.conf",
    "content": "slang=ru\nalang=jpn,ja,eng,en\n"
  },
  {
    "path": "pnpm-config.yaml",
    "content": "blockExoticSubdeps: true\nminimumReleaseAge: 1440\nstoreDir: ~/.local/share/pnpm/store\ntrustPolicy: true\ntrustPolicyIgnoreAfter: true\n"
  },
  {
    "path": "ripgreprc",
    "content": "--smart-case\n--glob=!.git/\n--glob=!.yarn/\n--hidden\n--no-heading\n"
  },
  {
    "path": "sshconfig",
    "content": "Host *\n    ForwardAgent no\n\nHost github.com\n    HostName github.com\n    User git\n    IdentityFile ~/.ssh/id_ed25519\n\nHost susedko.local\n    HostName susedko.local\n    User ai\n    IdentityFile ~/.ssh/id_ed25519\n\nHost 127.0.0.1\n    StrictHostKeyChecking no\n    UserKnownHostsFile=/dev/null\n\nHost *\n  AddKeysToAgent yes\n  IdentityFile ~/.ssh/id_ed25519\n  IdentityFile ~/.ssh/id_ed25519_ru\n\nGSSAPIAuthentication no\nTCPKeepAlive yes\nServerAliveInterval 3\n"
  },
  {
    "path": "starship.toml",
    "content": "format = \"\"\"\n$username\\\n$hostname\\\n$container\\\n$shlvl\\\n$directory\\\n$git_branch\\\n$git_commit\\\n$git_state\\\n$git_metrics\\\n$git_status\\\n$sudo\\\n$cmd_duration\\\n$line_break\\\n$jobs\\\n$status\\\n$shell\\\n$character\"\"\"\n\n[container]\nformat = '[$symbol]($style) '\n"
  },
  {
    "path": "zed-keys.json",
    "content": "[\n  {\n    \"bindings\": {\n      \"ctrl-q\": null\n    }\n  },\n  {\n    \"context\": \"Terminal\",\n    \"bindings\": {\n      \"ctrl-s\": [\"terminal::SendKeystroke\", \"ctrl-s\"],\n      \"ctrl-c\": \"terminal::Copy\",\n      \"ctrl-v\": \"terminal::Paste\"\n    }\n  }\n]\n"
  },
  {
    "path": "zed.json",
    "content": "{\n  \"outline_panel\": {\n    \"dock\": \"left\"\n  },\n  \"collaboration_panel\": {\n    \"dock\": \"left\"\n  },\n  \"git_panel\": {\n    \"dock\": \"left\"\n  },\n  \"project_panel\": {\n    \"dock\": \"left\"\n  },\n  \"diff_view_style\": \"unified\",\n  \"agent_servers\": {\n    \"claude-acp\": {\n      \"default_config_options\": {\n        \"mode\": \"bypassPermissions\"\n      },\n      \"type\": \"registry\"\n    }\n  },\n  \"colorize_brackets\": true,\n  \"indent_guides\": {\n    \"coloring\": \"indent_aware\",\n    \"background_coloring\": \"disabled\"\n  },\n  \"prettier\": {\n    \"allowed\": true\n  },\n  \"use_podman\": true,\n  \"show_completions_on_input\": true,\n  \"buffer_font_family\": \"Lilex\",\n  \"agent\": {\n    \"dock\": \"right\",\n    \"tool_permissions\": {\n      \"default\": \"allow\"\n    },\n    \"default_profile\": \"write\",\n    \"notify_when_agent_waiting\": \"primary_screen\",\n    \"play_sound_when_agent_done\": \"always\",\n    \"model_parameters\": [],\n    \"default_model\": {\n      \"effort\": \"high\",\n      \"enable_thinking\": true,\n      \"provider\": \"zed.dev\",\n      \"model\": \"claude-sonnet-4-6\"\n    }\n  },\n  \"edit_predictions\": {\n    \"provider\": \"zed\",\n    \"mode\": \"subtle\",\n    \"copilot\": {\n      \"proxy\": null,\n      \"proxy_no_verify\": null\n    }\n  },\n  \"icon_theme\": \"Material Icon Theme\",\n  \"terminal\": {\n    \"dock\": \"right\"\n  },\n  \"soft_wrap\": \"preferred_line_length\",\n  \"preferred_line_length\": 80,\n  \"wrap_guides\": [80],\n  \"ui_font_size\": 16,\n  \"buffer_font_size\": 16,\n  \"theme\": {\n    \"mode\": \"system\",\n    \"light\": \"Adwaita Pastel Light\",\n    \"dark\": \"Adwaita Pastel Dark\"\n  },\n  \"git\": {\n    \"inline_blame\": {\n      \"enabled\": false\n    }\n  },\n  \"file_types\": {\n    \"XML\": [\"svg\"],\n    \"YAML\": [\"**/*.bu\"],\n    \"JSON\": [\"**/*.webmanifest\"]\n  },\n  \"lsp\": {\n    \"oxfmt\": {\n      \"initialization_options\": {\n        \"settings\": {\n          \"fmt.configPath\": null\n        }\n      }\n    },\n    \"oxlint\": {\n      \"initialization_options\": {\n        \"settings\": {\n          \"configPath\": null,\n          \"fixKind\": \"safe_fix\",\n          \"run\": \"onType\",\n          \"unusedDisableDirectives\": \"deny\"\n        }\n      }\n    }\n  },\n  \"languages\": {\n    \"JavaScript\": {\n      \"format_on_save\": \"on\",\n      \"prettier\": {\n        \"allowed\": false\n      },\n      \"language_servers\": [\"!eslint\", \"!tailwindcss-language-server\", \"...\"],\n      \"formatter\": [\n        {\n          \"language_server\": {\n            \"name\": \"oxfmt\"\n          }\n        }\n      ]\n    },\n    \"Svelte\": {\n      \"code_actions_on_format\": {\n        \"source.fixAll.eslint\": true\n      },\n      \"language_servers\": [\"!tailwindcss-language-server\", \"...\"]\n    },\n    \"TypeScript\": {\n      \"format_on_save\": \"on\",\n      \"prettier\": {\n        \"allowed\": false\n      },\n      \"language_servers\": [\"!eslint\", \"!tailwindcss-language-server\", \"...\"],\n      \"formatter\": [\n        {\n          \"language_server\": {\n            \"name\": \"oxfmt\"\n          }\n        }\n      ]\n    },\n    \"HTML\": {\n      \"format_on_save\": \"on\",\n      \"prettier\": {\n        \"allowed\": false\n      },\n      \"language_servers\": [\"!tailwindcss-language-server\", \"...\"],\n      \"formatter\": [\n        {\n          \"language_server\": {\n            \"name\": \"oxfmt\"\n          }\n        }\n      ]\n    },\n    \"CSS\": {\n      \"format_on_save\": \"on\",\n      \"prettier\": {\n        \"allowed\": false\n      },\n      \"formatter\": [\n        {\n          \"language_server\": {\n            \"name\": \"oxfmt\"\n          }\n        }\n      ]\n    },\n    \"JSON\": {\n      \"format_on_save\": \"on\",\n      \"prettier\": {\n        \"allowed\": false\n      },\n      \"formatter\": [\n        {\n          \"language_server\": {\n            \"name\": \"oxfmt\"\n          }\n        }\n      ]\n    },\n    \"JSONC\": {\n      \"format_on_save\": \"on\",\n      \"prettier\": {\n        \"allowed\": false\n      },\n      \"formatter\": [\n        {\n          \"language_server\": {\n            \"name\": \"oxfmt\"\n          }\n        }\n      ]\n    },\n    \"YAML\": {\n      \"format_on_save\": \"on\",\n      \"prettier\": {\n        \"allowed\": false\n      },\n      \"formatter\": [\n        {\n          \"language_server\": {\n            \"name\": \"oxfmt\"\n          }\n        }\n      ]\n    },\n    \"Markdown\": {\n      \"format_on_save\": \"on\",\n      \"prettier\": {\n        \"allowed\": false\n      },\n      \"formatter\": [\n        {\n          \"language_server\": {\n            \"name\": \"oxfmt\"\n          }\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "zshrc",
    "content": "# History\nHISTSIZE=10000\nSAVEHIST=10000\nHISTFILE=~/.local/share/history/histfile\nsetopt appendhistory\nsetopt inc_append_history\nsetopt hist_ignore_all_dups\n\n# Colors\nautoload -U colors && colors\n\n# Key bindings\nbindkey -e\nbindkey ';5D' backward-word # Ctrl+Left\nbindkey ';5C' forward-word  # Ctrl+Right\nstty intr ^X                # Replace Ctrl+C to Ctrl+X\nstty susp undef             # Disable Ctrl + Z\n\n# Force keeping home folder clean\nexport XDG_CACHE_HOME=\"$HOME/.cache\"\nexport XDG_CONFIG_HOME=\"$HOME/.config\"\nexport XDG_DATA_HOME=\"$HOME/.local/share\"\nexport GNUPGHOME=\"$XDG_DATA_HOME/gnupg\"\nexport NODE_COMPILE_CACHE=\"$XDG_CACHE_HOME/node\"\nexport NPM_CONFIG_USERCONFIG=\"$XDG_CONFIG_HOME/npmrc\"\nexport RIPGREP_CONFIG_PATH=\"$XDG_CONFIG_HOME/ripgreprc\"\nexport CLAUDE_CONFIG_DIR=\"$XDG_DATA_HOME/claude\"\n\n# Completion\nzstyle :compinstall filename \"$HOME/.zshrc\"\nautoload -Uz compinit\ncompinit -i -d \"$XDG_CACHE_HOME/zcompcache\"\n\n# Zsh plugins\nexport HISTORY_BASE=\"$XDG_CACHE_HOME/zsh_directory_history\"\nfor plugin in \\\n  zsh-syntax-highlighting/zsh-syntax-highlighting.zsh \\\n  zsh-autosuggestions/zsh-autosuggestions.zsh \\\n  per-directory-history/per-directory-history.zsh \\\n  pnpm-shell-completion/pnpm-shell-completion.plugin.zsh\ndo\n  for dir in ~/.local/lib/zsh /usr/local/lib/zsh; do\n    if [[ -f $dir/$plugin ]]; then\n      source $dir/$plugin\n      break\n    fi\n  done\ndone\n\n# Local binaries\nexport PATH=\"$HOME/.local/bin:$PATH\"\n\n# Prompt\nif command -v starship > /dev/null 2>&1; then\n  eval \"$(starship init zsh)\"\nelif [ -f ~/.local/bin/starship ]; then\n  eval \"$(~/.local/bin/starship init zsh)\"\nfi\n\n# History\nif [ -f ~/.local/bin/atuin ]; then\n  eval \"$(~/.local/bin/atuin init zsh --disable-up-arrow)\"\nfi\n\n# Rip Grep\n\n# Console editor\nexport EDITOR=micro\n\n# Fix Bat in light console\nexport BAT_THEME=ansi\n\n# Release function\nrelease() {\n  local VERSION=$(grep -oP '(?<=\"version\": \")[^\"]*' package.json)\n\n  if [ -z \"$VERSION\" ]; then\n    echo \"Version not found in package.json\"\n    return 1\n  fi\n\n  git add .\n  git commit -m \"Release $VERSION version\"\n  git tag -s \"$VERSION\" -m \"$VERSION\"\n  git push\n}\n\n# Aliases\nalias g='git'\nalias ..='cd ..'\nalias l='ls --all'\nalias ll='ls --long --all --git'\n\nif command -v bat > /dev/null 2>&1; then\n  alias cat='bat'\nfi\nif command -v eza > /dev/null 2>&1; then\n  alias ls='eza'\nfi\n\nalias r='dev node --run'\nalias t='dev node --run test'\nalias pm='dev pnpm'\nalias pnx='dev pnpm dlx'\nalias pui='pnpm update --interactive --latest -r --include-workspace-root'\nalias pu='pnpm update -r --include-workspace-root'\nalias pui1='pnpm update --interactive --latest'\nalias pu1='pnpm update'\n\nif [ -n \"$container\" ]; then\n  if [ -d \"$HOME/.local/share/pnpm\" ]; then\n    export PNPM_HOME=\"$HOME/.local/share/pnpm\"\n    export PATH=\"$PNPM_HOME/bin/:$PATH\"\n  fi\n  alias dev='command'\n\n  if [ -z \"$SSH_AUTH_SOCK\" ] && [ -S \"/run/user/1000/gcr/ssh\" ]; then\n    export SSH_AUTH_SOCK=\"/run/user/1000/gcr/ssh\"\n  fi\nelse\n  export PATH=\"/home/ai/.local/lib/node/node_modules/.bin/:$PATH\"\n\n  alias dev='/home/ai/Dev/environment/bin/dev'\n  alias devup='dev --up'\n  alias devdown='dev --down'\n  alias pnpm='dev pnpm'\n  alias node='dev node'\n  alias multiocular='dev --port pnpm multiocular'\n\n  # Run git hooks inside Dev Container\n  export GIT_CONFIG_PARAMETERS=\"'core.hooksPath=/home/ai/Dev/environment/hooks-trap'\"\n\n  # Fast way to Dev projects\n  if [ -d ~/Dev ]; then\n    cdpath=(. ~/Dev)\n  fi\n\n  # Zed\n  alias e='~/Dev/environment/bin/zed-isolate .'\n\n  # Development\n  alias p='dev pnpm clean-publish --temp-dir .npm-release --without-publish \\\n    && cd .npm-release \\\n    && npm publish --access public \\\n    && cd .. \\\n    && rm -R  .npm-release'\nfi\n"
  }
]