From 1422c0adbd4289fe9c76741d5622ce73ffb52303 Mon Sep 17 00:00:00 2001 From: ShibaKabu <132909895+shibadogcap@users.noreply.github.com> Date: Sat, 17 Aug 2024 16:22:26 +0900 Subject: [PATCH 1/2] improve Japanese Translation --- src/apps/settings/i18n/translations/ja.yml | 249 +++++++++++---------- src/apps/toolbar/i18n/translations/ja.yml | 26 +-- src/apps/update/i18n/translations/ja.yml | 8 +- 3 files changed, 143 insertions(+), 140 deletions(-) diff --git a/src/apps/settings/i18n/translations/ja.yml b/src/apps/settings/i18n/translations/ja.yml index c64d111a..3d63df2c 100644 --- a/src/apps/settings/i18n/translations/ja.yml +++ b/src/apps/settings/i18n/translations/ja.yml @@ -2,189 +2,192 @@ sides: left: 左 right: 右 top: 上 - bottom: 底 + bottom: 下 header: labels: - developer: 開発者 - info: 情報 - general: 一般的な - shortcuts: ショートカット + developer: 開発者向け + info: このアプリについて + general: 全般 + shortcuts: ショートカットキー seelen_wm: ウィンドウマネージャー - specific_apps: 特定のアプリ + specific_apps: アプリごとの設定 monitors: モニター - seelen_weg: ドック/タスクバー - seelen_bar: 派手なツールバー + seelen_weg: ドック(タスクバー) + seelen_bar: ツールバー start: - title: いらっしゃいませ! + title: ようこそ! message: >- - Windows 11エクスペリエンスを強化するために、組み込まれたタイル張りWindowsマネージャーを備えた究極のデスクトップ環境であるSeelen - UIへようこそ! 直感的なインターフェイスと高度な機能を使用して、効率とマルチタスクの新しい時代を探ります。 - message_accent: スタイルで生産性を最適化してください! + SeelenUIにようこそ! + 組み込みのタイル型ウィンドウマネージャーを備えた究極のデスクトップ環境で、あなたのWindows 11での体験を向上させます! + 直感的なインターフェースと高度な機能で効率的なマルチタスクの新時代を探求しましょう。 + message_accent: あなた好みのスタイリングで生産性を最適化! general: theme: - author: 著者 + author: 製作者 description: 説明 - add: テーマを追加します + add: テーマを追加 tags: タグ added: テーマはすでに追加されています - enabled: テーマを有効にしました + enabled: テーマが有効になっています label: テーマ情報 - placeholder: テーマを選択します + placeholder: テーマを選択 available: 利用可能 - selected: 選択しました - startup: 起動時に実行? + selected: 選択済み + startup: 起動時に実行する language: 言語 icon_pack: label: アイコンパック - accent_color: アクセントの色 + wallpaper: + select: 壁紙を選択 + accent_color: アクセントカラー toolbar: placeholder: description: 説明 - author: 著者 - select: ツールバー構造 - height: 身長 - enable: 派手なツールバーを有効にします + author: 製作者 + select: ツールバーのテーマ + height: 高さ + enable: ツールバーを有効にする wm: border: - offset: ボーダーオフセット - enable: ウィンドウの境界線を有効にします - width: 境界幅 - author: 著者 + offset: 境界線の余白 + enable: ウィンドウの境界線を描画する + width: 線幅 + author: 製作者 layout: レイアウト description: 説明 - enable: ウィンドウマネージャーを有効にします - workspace_offset: ワークスペースオフセット(マージン) + enable: ウィンドウマネージャーを有効にする + workspace_offset: ワークスペース全体の間隔(マージン) disabled_windows10: ウィンドウマネージャーはWindows 10では利用できません。 - space_between_containers: コンテナ間のスペース - resize_delta: デルタのサイズ(%) - workspace_padding: ワークスペースパディング + space_between_containers: ウィンドウ間の間隔 + resize_delta: リサイズ時の変化率(%) + workspace_padding: ワークスペースの全体の間隔 weg: items: - size: アイテムサイズ - zoom_size: ズームされたサイズ(テーマに使用) - visible_separators: 目に見えるセパレーター + size: アイテムのサイズ + zoom_size: ズームされたときのサイズ(一部のテーマで使用) + visible_separators: セパレーターを表示する label: アイテム gap: アイテム間のスペース - width: 幅 - margin: マージン - gap: ギャップ - padding: パディング - label: ドック/タスクバー - auto_hide: 自動隠し - dock_side: ドック側 - enable: ドック/タスクバーを有効にします + width: ドックの幅 + margin: ドックの隙間 + gap: ずれ + padding: 余白 + label: ドック(タスクバー) + auto_hide: 自動的に隠す + dock_side: ドックの位置 + enable: ドック(タスクバー)を有効にする devtools: - load: 負荷 + load: ロード data_folder: データフォルダー app_folders: アプリフォルダー - enable: 開発者ツールを有効にします + enable: 開発者ツールを有効にする settings_file: 設定ファイル install_folder: インストールフォルダー - custom_config_file: カスタム構成ファイルをロードします + custom_config_file: カスタム構成ファイルをロードする apps_configurations: app: options: - float: 浮く - force: 力管理 + float: フロート + force: 強制 pinned: ピン留め - unmanage: 無人 + unmanage: 管理しない category_placeholder: なし monitor_placeholder: なし workspace: ワークスペース - ok_edit: アップデート + ok_edit: 適用 category: カテゴリー monitor: モニター - ok_create: 作成する + ok_create: 作成 bindings: バインディング(両方のオプションが必要です) - ok_readonly: 新しいとして編集します + ok_readonly: 新規設定を作成 workspace_placeholder: なし - title_edit: 編集{{name}} - title_readonly: 表示{{name}} + title_edit: 「{{name}}」を編集する + title_readonly: 「{{name}}」を表示しています name: 名前 title_create: '{{name}}を作成する' - options_label: 追加オプション + options_label: オプション identifier: id: 識別子 - and: そして + and: かつ or: または - negation: マッチングを否定します - remove: ブロックを削除します - matching_strategy: マッチング戦略 - add_block: ブロックを追加します - kind: 識別します + negation: マッチングを否定する + remove: ブロックを削除 + matching_strategy: マッチングの方法 + add_block: ブロックを追加 + kind: 識別方法 search: 検索 - export: 輸出 + export: エクスポート delete: 消去 - import: 輸入 - new: 新しい - swap: スワップ + import: インポート + new: 新規 + swap: 入れ替え confirm_delete: この構成を削除したいですか? - confirm_delete_title: 削除を確認します + confirm_delete_title: 削除の確認 bundled_msg: >- これらのバンドルされた構成は編集可能ではなく、カスタマイズなしで最高の体験を提供するように設計されています。 最も一般的なアプリケーションを自動的に構成します。 bundled_title: Seelenにバンドルされたアプリの構成 extras: - discord: 不和 + discord: Discord version: バージョン - github: github - relaunch: リニューアル - links: 公式リンク - exit: 終了/終了 + github: GitHub + relaunch: 再起動 + links: リンク + exit: 終了 shortcuts: labels: - reserve_left: 左に予備 - switch_workspace_5: ワークスペースに切り替えます5 - send_to_workspace_1: ワークスペースに送信1 - restore_sizes: サイズを復元します - send_to_workspace_3: ワークスペースに送信3 - move_to_workspace_2: ワークスペース2に移動します - send_to_workspace_2: Workspace 2に送信します - reserve_stack: 予備スタック - move_to_workspace_0: ワークスペース0に移動します - switch_workspace_2: ワークスペースに切り替えます2 - increase_height: 高さを増やします - switch_workspace_3: ワークスペースに切り替えます3 - focus_top: フォーカストップ - send_to_workspace_9: ワークスペースに送信します9 - send_to_workspace_0: ワークスペースに送信します0 - move_to_workspace_4: ワークスペース4に移動します - send_to_workspace_5: ワークスペースに送信5 - move_to_workspace_6: ワークスペース6に移動します - decrease_height: 高さを減らします - switch_workspace_7: ワークスペースに切り替えます7 - reserve_bottom: 底を予約します - focus_right: 焦点を合わせてください - switch_workspace_1: ワークスペースに切り替えます1 - reserve_right: 右に予約します - switch_workspace_8: ワークスペースに切り替えます8 - switch_workspace_0: ワークスペースに切り替えます0 - send_to_workspace_8: ワークスペースに送信8 - move_to_workspace_8: ワークスペース8に移動します - switch_workspace_6: ワークスペースに切り替えます6 - send_to_workspace_4: ワークスペースに送信する4 - reserve_float: 予備のフロート - focus_latest: 最新の焦点 - decrease_width: 幅を減らします - reserve_top: トップを予約します - move_to_workspace_1: ワークスペース1に移動します - switch_workspace_4: ワークスペースに切り替えます4 - move_to_workspace_7: ワークスペース7に移動します - switch_workspace_9: ワークスペースに切り替えます9 - focus_bottom: フォーカスボトム - move_to_workspace_9: ワークスペース9に移動します - move_to_workspace_3: ワークスペース3に移動します - send_to_workspace_6: ワークスペースに送信6 - increase_width: 幅を増やします - move_to_workspace_5: ワークスペース5に移動します - focus_left: フォーカスを左にします - send_to_workspace_7: ワークスペースに送信7 - enable: 統合ショートカット(AHK)を有効にする - enable_tooltip: Seelen Core APIを使用して独自のショートカットを実装する場合は無効にします + reserve_left: 左側を予約 + switch_workspace_5: ワークスペース5に切り替え + send_to_workspace_1: ワークスペース1に送信 + restore_sizes: サイズを復元 + send_to_workspace_3: ワークスペース3に送信 + move_to_workspace_2: ワークスペース2に移動 + send_to_workspace_2: ワークスペース2に送信 + reserve_stack: スタックを予約 + move_to_workspace_0: ワークスペース0に移動 + switch_workspace_2: ワークスペース2に切り替え + increase_height: 高さを増やす + switch_workspace_3: ワークスペース3に切り替え + focus_top: 上にフォーカス + send_to_workspace_9: ワークスペース9に送信 + send_to_workspace_0: ワークスペース0に送信 + move_to_workspace_4: ワークスペース4に移動 + send_to_workspace_5: ワークスペース5に送信 + move_to_workspace_6: ワークスペース6に移動 + decrease_height: 高さを減らす + switch_workspace_7: ワークスペース7に切り替え + reserve_bottom: 下側を予約 + focus_right: 右にフォーカス + switch_workspace_1: ワークスペース1に切り替え + reserve_right: 右側を予約 + switch_workspace_8: ワークスペース8に切り替え + switch_workspace_0: ワークスペース0に切り替え + send_to_workspace_8: ワークスペース8に送信 + move_to_workspace_8: ワークスペース8に移動 + switch_workspace_6: ワークスペース6に切り替え + send_to_workspace_4: ワークスペース4に送信 + reserve_float: フロートを予約 + focus_latest: 最新のウィンドウにフォーカス + decrease_width: 幅を減らす + reserve_top: 上側を予約 + move_to_workspace_1: ワークスペース1に移動 + switch_workspace_4: ワークスペース4に切り替え + move_to_workspace_7: ワークスペース7に移動 + switch_workspace_9: ワークスペース9に切り替え + focus_bottom: 下にフォーカス + move_to_workspace_9: ワークスペース9に移動 + move_to_workspace_3: ワークスペース3に移動 + send_to_workspace_6: ワークスペース6に送信 + increase_width: 幅を増やす + move_to_workspace_5: ワークスペース5に移動 + focus_left: 左にフォーカス + send_to_workspace_7: ワークスペース7に送信 + enable: AutoHotkeyを使用した統合ショートカットを有効にする + enable_tooltip: Seelen Core APIを使用して独自のショートカットを実装する場合は無効にしてください delete: 消去 -loading: 読み込み... -inProgress: 進行中... -quit: やめる -open: 開ける +loading: 読み込み中... +inProgress: 近日実装予定... +quit: 終了 +open: 開く save: 保存 cancel: キャンセル diff --git a/src/apps/toolbar/i18n/translations/ja.yml b/src/apps/toolbar/i18n/translations/ja.yml index 54fc9335..90a6b63a 100644 --- a/src/apps/toolbar/i18n/translations/ja.yml +++ b/src/apps/toolbar/i18n/translations/ja.yml @@ -2,33 +2,33 @@ media: device: comunications: コミュニケーション multimedia: マルチメディア - output_device: 出力機器 + output_device: 出力デバイス master_volume: マスターボリューム input_device: 入力デバイス players: メディアプレーヤー network: placeholder: password: パスワード - connect: 接続する - not_found: ネットワークは見つかりません - hidden: 隠されたネットワーク - more: より多くのネットワーク設定 - disconnect: 切断します + connect: 接続 + not_found: ネットワークが見つかりません + hidden: 隠れたネットワーク + more: 詳しい設定 + disconnect: 切断 settings: restart: 再起動 log_out: ログアウト - app_settings: アプリ設定 + app_settings: SeelenUIの設定 shutdown: シャットダウン - sleep: 寝る + sleep: スリープ title: 設定 placeholder: battery_remaining: % 残り - settings: クイック設定 - open_system_tray: システムトレイを開きます + settings: 設定 + open_system_tray: システムトレイを開く volume: 音量 - ethernet_connected: インターネット・アクセス - bluetooth_devices: Bluetooth&Devices + ethernet_connected: インターネットアクセス + bluetooth_devices: Bluetoothとデバイス smart_charge: '- スマートチャージ' - open_user_folder: ユーザーフォルダーを開きます + open_user_folder: ユーザーフォルダーを開く ethernet_disconnected: インターネットアクセスはありません notifications: 通知 diff --git a/src/apps/update/i18n/translations/ja.yml b/src/apps/update/i18n/translations/ja.yml index 94249c7f..254ce003 100644 --- a/src/apps/update/i18n/translations/ja.yml +++ b/src/apps/update/i18n/translations/ja.yml @@ -1,10 +1,10 @@ update: - cancel: 後で + cancel: キャンセル version: バージョン date: 日付 title: 更新が利用可能です! page: GitHubリリースページ - installing: インストール... + installing: インストール中... extra_info: 完全なChangelogを読むには、Changelogページにアクセスしてください - download: 更新&インストール - downloading: ダウンロード... + download: ダウンロード + downloading: ダウンロード中... From 183deb532c7e00e9b57511b2196420c1d05b9a60 Mon Sep 17 00:00:00 2001 From: ShibaKabu <132909895+shibadogcap@users.noreply.github.com> Date: Sat, 17 Aug 2024 18:02:55 +0900 Subject: [PATCH 2/2] add GPG --- .commitlintrc.yml | 58 +- .github/ISSUE_TEMPLATE/bug_report.md | 48 +- .github/ISSUE_TEMPLATE/feature_request.md | 40 +- .github/ISSUE_TEMPLATE/translation.md | 54 +- .github/workflows/ci.yml | 114 +- .github/workflows/msix.yml | 146 +- .github/workflows/release.yml | 412 +- .github/workflows/web_deployment.yml | 170 +- .gitignore | 22 +- CLA.md | 38 +- CONTRIBUTING | 58 +- Cargo.lock | 13664 +++++------ Cargo.toml | 236 +- LICENSE | 206 +- capabilities/migrated.json | 144 +- changelog.md | 1144 +- documentation/images/logo.svg | 28 +- documentation/privacy policy.md | 150 +- documentation/project.md | 66 +- documentation/schemas/layout.schema.json | 548 +- documentation/schemas/placeholder.schema.json | 694 +- documentation/schemas/settings.schema.json | 1344 +- documentation/schemas/theme.schema.json | 280 +- documentation/themes.md | 106 +- documentation/toolbar.md | 110 +- documentation/window_manager.md | 38 +- eslint.config.js | 192 +- jest.config.js | 8 +- lefthook.yml | 52 +- nodemon.json | 28 +- package-lock.json | 19154 ++++++++-------- package.json | 164 +- readme.md | 216 +- rust-toolchain.toml | 2 +- scripts/SubmitToStore.ps1 | 74 +- scripts/UpdateTauri.ts | 62 +- scripts/build.rs | 6 +- scripts/build.ts | 64 +- scripts/bundle.msix.ts | 104 +- scripts/createJsonSchemas.ts | 58 +- scripts/postversion.ts | 30 +- scripts/submission.json | 14 +- scripts/translate.ts | 110 +- src/apps/seelen_wm/index.html | 20 +- src/apps/seelen_wm/index.tsx | 92 +- src/apps/seelen_wm/modules/layout/app.ts | 1010 +- src/apps/seelen_wm/modules/layout/domain.ts | 40 +- .../layout/infra/containers/fallback.tsx | 72 +- .../modules/layout/infra/containers/leaf.tsx | 116 +- .../layout/infra/containers/reserved.tsx | 46 +- .../seelen_wm/modules/layout/infra/index.css | 214 +- .../seelen_wm/modules/layout/infra/index.tsx | 110 +- .../seelen_wm/modules/shared/store/app.ts | 398 +- .../seelen_wm/modules/shared/store/domain.ts | 114 +- .../seelen_wm/modules/shared/store/infra.ts | 238 +- src/apps/seelen_wm/styles/colors.css | 1198 +- src/apps/seelen_wm/styles/global.css | 44 +- src/apps/seelen_wm/styles/variables.css | 30 +- src/apps/seelenweg-hitbox/index.css | 22 +- src/apps/seelenweg-hitbox/index.html | 16 +- src/apps/seelenweg-hitbox/index.tsx | 112 +- src/apps/seelenweg/app.tsx | 92 +- .../BackgroundByLayers/infra.module.css | 36 +- .../components/BackgroundByLayers/infra.tsx | 84 +- src/apps/seelenweg/components/Error/index.tsx | 64 +- .../components/TooltipWrap/infra.tsx | 32 +- .../seelenweg/components/WithContextMenu.tsx | 82 +- src/apps/seelenweg/events.ts | 182 +- src/apps/seelenweg/i18n/index.ts | 196 +- src/apps/seelenweg/i18n/translations/af.yml | 38 +- src/apps/seelenweg/i18n/translations/am.yml | 38 +- src/apps/seelenweg/i18n/translations/ar.yml | 38 +- src/apps/seelenweg/i18n/translations/az.yml | 38 +- src/apps/seelenweg/i18n/translations/bg.yml | 38 +- src/apps/seelenweg/i18n/translations/bn.yml | 38 +- src/apps/seelenweg/i18n/translations/bs.yml | 38 +- src/apps/seelenweg/i18n/translations/ca.yml | 38 +- src/apps/seelenweg/i18n/translations/cs.yml | 38 +- src/apps/seelenweg/i18n/translations/cy.yml | 38 +- src/apps/seelenweg/i18n/translations/da.yml | 38 +- src/apps/seelenweg/i18n/translations/de.yml | 38 +- src/apps/seelenweg/i18n/translations/el.yml | 38 +- src/apps/seelenweg/i18n/translations/en.yml | 36 +- src/apps/seelenweg/i18n/translations/es.yml | 38 +- src/apps/seelenweg/i18n/translations/et.yml | 38 +- src/apps/seelenweg/i18n/translations/eu.yml | 38 +- src/apps/seelenweg/i18n/translations/fa.yml | 38 +- src/apps/seelenweg/i18n/translations/fi.yml | 38 +- src/apps/seelenweg/i18n/translations/fr.yml | 38 +- src/apps/seelenweg/i18n/translations/gu.yml | 38 +- src/apps/seelenweg/i18n/translations/he.yml | 38 +- src/apps/seelenweg/i18n/translations/hi.yml | 38 +- src/apps/seelenweg/i18n/translations/hr.yml | 38 +- src/apps/seelenweg/i18n/translations/hu.yml | 38 +- src/apps/seelenweg/i18n/translations/hy.yml | 38 +- src/apps/seelenweg/i18n/translations/id.yml | 38 +- src/apps/seelenweg/i18n/translations/is.yml | 38 +- src/apps/seelenweg/i18n/translations/it.yml | 38 +- src/apps/seelenweg/i18n/translations/ja.yml | 38 +- src/apps/seelenweg/i18n/translations/ka.yml | 38 +- src/apps/seelenweg/i18n/translations/km.yml | 38 +- src/apps/seelenweg/i18n/translations/ko.yml | 38 +- src/apps/seelenweg/i18n/translations/ku.yml | 38 +- src/apps/seelenweg/i18n/translations/lb.yml | 38 +- src/apps/seelenweg/i18n/translations/lo.yml | 38 +- src/apps/seelenweg/i18n/translations/lt.yml | 38 +- src/apps/seelenweg/i18n/translations/lv.yml | 38 +- src/apps/seelenweg/i18n/translations/mk.yml | 38 +- src/apps/seelenweg/i18n/translations/mn.yml | 38 +- src/apps/seelenweg/i18n/translations/ms.yml | 38 +- src/apps/seelenweg/i18n/translations/mt.yml | 38 +- src/apps/seelenweg/i18n/translations/ne.yml | 38 +- src/apps/seelenweg/i18n/translations/nl.yml | 38 +- src/apps/seelenweg/i18n/translations/no.yml | 38 +- src/apps/seelenweg/i18n/translations/pa.yml | 38 +- src/apps/seelenweg/i18n/translations/pl.yml | 38 +- src/apps/seelenweg/i18n/translations/ps.yml | 38 +- src/apps/seelenweg/i18n/translations/pt.yml | 38 +- src/apps/seelenweg/i18n/translations/ro.yml | 38 +- src/apps/seelenweg/i18n/translations/ru.yml | 38 +- src/apps/seelenweg/i18n/translations/si.yml | 38 +- src/apps/seelenweg/i18n/translations/sk.yml | 38 +- src/apps/seelenweg/i18n/translations/so.yml | 38 +- src/apps/seelenweg/i18n/translations/sr.yml | 38 +- src/apps/seelenweg/i18n/translations/sv.yml | 38 +- src/apps/seelenweg/i18n/translations/sw.yml | 38 +- src/apps/seelenweg/i18n/translations/ta.yml | 38 +- src/apps/seelenweg/i18n/translations/te.yml | 38 +- src/apps/seelenweg/i18n/translations/tg.yml | 38 +- src/apps/seelenweg/i18n/translations/th.yml | 38 +- src/apps/seelenweg/i18n/translations/tl.yml | 38 +- src/apps/seelenweg/i18n/translations/tr.yml | 38 +- src/apps/seelenweg/i18n/translations/uk.yml | 38 +- src/apps/seelenweg/i18n/translations/ur.yml | 38 +- src/apps/seelenweg/i18n/translations/uz.yml | 38 +- src/apps/seelenweg/i18n/translations/vi.yml | 38 +- src/apps/seelenweg/i18n/translations/yo.yml | 38 +- src/apps/seelenweg/i18n/translations/zh.yml | 38 +- src/apps/seelenweg/i18n/translations/zu.yml | 38 +- src/apps/seelenweg/index.html | 26 +- src/apps/seelenweg/index.tsx | 78 +- src/apps/seelenweg/modules/bar/app.ts | 24 +- src/apps/seelenweg/modules/bar/index.css | 52 +- src/apps/seelenweg/modules/bar/index.tsx | 356 +- src/apps/seelenweg/modules/bar/menu.tsx | 284 +- .../seelenweg/modules/item/app/PinnedApp.ts | 56 +- .../seelenweg/modules/item/app/TemporalApp.ts | 64 +- .../modules/item/infra/DraggableItem.tsx | 70 +- .../modules/item/infra/MediaSession.css | 120 +- .../modules/item/infra/MediaSession.tsx | 194 +- .../seelenweg/modules/item/infra/Menu.tsx | 74 +- .../modules/item/infra/StartMenu.tsx | 134 +- .../modules/item/infra/UserApplication.tsx | 190 +- .../item/infra/UserApplicationPreview.tsx | 142 +- .../seelenweg/modules/shared/hooks/infra.ts | 46 +- .../seelenweg/modules/shared/store/app.ts | 448 +- .../seelenweg/modules/shared/store/domain.ts | 168 +- .../seelenweg/modules/shared/store/infra.ts | 378 +- .../modules/shared/store/storeApi.ts | 114 +- .../seelenweg/modules/shared/utils/app.ts | 50 +- .../seelenweg/modules/shared/utils/infra.ts | 236 +- src/apps/seelenweg/styles/colors.css | 1198 +- src/apps/seelenweg/styles/global.css | 478 +- src/apps/seelenweg/styles/reset.css | 270 +- src/apps/seelenweg/styles/variables.css | 32 +- src/apps/settings/app.tsx | 136 +- .../components/SettingsBox/index.module.css | 144 +- .../settings/components/SettingsBox/index.tsx | 112 +- .../components/header/index.module.css | 26 +- src/apps/settings/components/header/index.tsx | 126 +- .../components/monitor/index.module.css | 56 +- .../settings/components/monitor/index.tsx | 68 +- .../components/navigation/index.module.css | 140 +- .../settings/components/navigation/index.tsx | 136 +- .../settings/components/navigation/routes.tsx | 68 +- src/apps/settings/i18n/index.ts | 196 +- src/apps/settings/i18n/translations/af.yml | 390 +- src/apps/settings/i18n/translations/am.yml | 380 +- src/apps/settings/i18n/translations/ar.yml | 382 +- src/apps/settings/i18n/translations/az.yml | 390 +- src/apps/settings/i18n/translations/bg.yml | 390 +- src/apps/settings/i18n/translations/bn.yml | 390 +- src/apps/settings/i18n/translations/bs.yml | 390 +- src/apps/settings/i18n/translations/ca.yml | 390 +- src/apps/settings/i18n/translations/cs.yml | 386 +- src/apps/settings/i18n/translations/cy.yml | 390 +- src/apps/settings/i18n/translations/da.yml | 390 +- src/apps/settings/i18n/translations/de.yml | 390 +- src/apps/settings/i18n/translations/el.yml | 390 +- src/apps/settings/i18n/translations/en.yml | 386 +- src/apps/settings/i18n/translations/es.yml | 390 +- src/apps/settings/i18n/translations/et.yml | 386 +- src/apps/settings/i18n/translations/eu.yml | 386 +- src/apps/settings/i18n/translations/fa.yml | 388 +- src/apps/settings/i18n/translations/fi.yml | 390 +- src/apps/settings/i18n/translations/fr.yml | 382 +- src/apps/settings/i18n/translations/gu.yml | 390 +- src/apps/settings/i18n/translations/he.yml | 382 +- src/apps/settings/i18n/translations/hi.yml | 390 +- src/apps/settings/i18n/translations/hr.yml | 390 +- src/apps/settings/i18n/translations/hu.yml | 390 +- src/apps/settings/i18n/translations/hy.yml | 390 +- src/apps/settings/i18n/translations/id.yml | 390 +- src/apps/settings/i18n/translations/is.yml | 386 +- src/apps/settings/i18n/translations/it.yml | 390 +- src/apps/settings/i18n/translations/ja.yml | 386 +- src/apps/settings/i18n/translations/ka.yml | 390 +- src/apps/settings/i18n/translations/km.yml | 386 +- src/apps/settings/i18n/translations/ko.yml | 380 +- src/apps/settings/i18n/translations/ku.yml | 388 +- src/apps/settings/i18n/translations/lb.yml | 386 +- src/apps/settings/i18n/translations/lo.yml | 388 +- src/apps/settings/i18n/translations/lt.yml | 386 +- src/apps/settings/i18n/translations/lv.yml | 386 +- src/apps/settings/i18n/translations/mk.yml | 390 +- src/apps/settings/i18n/translations/mn.yml | 384 +- src/apps/settings/i18n/translations/ms.yml | 390 +- src/apps/settings/i18n/translations/mt.yml | 386 +- src/apps/settings/i18n/translations/ne.yml | 388 +- src/apps/settings/i18n/translations/nl.yml | 390 +- src/apps/settings/i18n/translations/no.yml | 390 +- src/apps/settings/i18n/translations/pa.yml | 390 +- src/apps/settings/i18n/translations/pl.yml | 386 +- src/apps/settings/i18n/translations/ps.yml | 384 +- src/apps/settings/i18n/translations/pt.yml | 386 +- src/apps/settings/i18n/translations/ro.yml | 390 +- src/apps/settings/i18n/translations/ru.yml | 392 +- src/apps/settings/i18n/translations/si.yml | 386 +- src/apps/settings/i18n/translations/sk.yml | 386 +- src/apps/settings/i18n/translations/so.yml | 388 +- src/apps/settings/i18n/translations/sr.yml | 390 +- src/apps/settings/i18n/translations/sv.yml | 390 +- src/apps/settings/i18n/translations/sw.yml | 382 +- src/apps/settings/i18n/translations/ta.yml | 390 +- src/apps/settings/i18n/translations/te.yml | 390 +- src/apps/settings/i18n/translations/tg.yml | 384 +- src/apps/settings/i18n/translations/th.yml | 382 +- src/apps/settings/i18n/translations/tl.yml | 392 +- src/apps/settings/i18n/translations/tr.yml | 390 +- src/apps/settings/i18n/translations/uk.yml | 386 +- src/apps/settings/i18n/translations/ur.yml | 388 +- src/apps/settings/i18n/translations/uz.yml | 390 +- src/apps/settings/i18n/translations/vi.yml | 386 +- src/apps/settings/i18n/translations/yo.yml | 382 +- src/apps/settings/i18n/translations/zh.yml | 376 +- src/apps/settings/i18n/translations/zu.yml | 390 +- src/apps/settings/index.html | 68 +- src/apps/settings/index.tsx | 68 +- .../modules/StartUser/index.module.css | 40 +- src/apps/settings/modules/StartUser/infra.tsx | 70 +- .../modules/WindowManager/border/app.ts | 30 +- .../modules/WindowManager/border/infra.tsx | 98 +- .../modules/WindowManager/main/app.ts | 50 +- .../main/infra/GlobalPaddings.tsx | 138 +- .../WindowManager/main/infra/Others.tsx | 62 +- .../WindowManager/main/infra/index.tsx | 188 +- .../modules/appsConfigurations/app/filters.ts | 46 +- .../modules/appsConfigurations/app/reducer.ts | 90 +- .../modules/appsConfigurations/domain.ts | 124 +- .../appsConfigurations/infra/EditModal.tsx | 326 +- .../infra/Identifier.module.css | 12 +- .../appsConfigurations/infra/Identifier.tsx | 272 +- .../appsConfigurations/infra/index.module.css | 120 +- .../appsConfigurations/infra/infra.tsx | 512 +- src/apps/settings/modules/developer/app.ts | 36 +- src/apps/settings/modules/developer/infra.tsx | 138 +- src/apps/settings/modules/fancyToolbar/app.ts | 30 +- .../settings/modules/fancyToolbar/infra.tsx | 166 +- .../settings/modules/general/main/domain.ts | 34 +- .../modules/general/main/infra/Colors.tsx | 80 +- .../modules/general/main/infra/Themes.tsx | 196 +- .../modules/general/main/infra/Wallpaper.tsx | 92 +- .../general/main/infra/index.module.css | 128 +- .../modules/general/main/infra/index.tsx | 128 +- .../modules/information/infra.module.css | 26 +- .../modules/information/infrastructure.tsx | 148 +- .../modules/monitors/layouts/domain.ts | 24 +- .../modules/monitors/layouts/infra.module.css | 32 +- .../modules/monitors/layouts/infra.tsx | 474 +- .../settings/modules/monitors/main/app.ts | 122 +- .../modules/monitors/main/infra.module.css | 138 +- .../settings/modules/monitors/main/infra.tsx | 232 +- .../modules/monitors/main/infra_advanced.tsx | 238 +- .../modules/monitors/workspace/app.ts | 36 +- .../monitors/workspace/infra.module.css | 10 +- .../modules/monitors/workspace/infra.tsx | 112 +- src/apps/settings/modules/seelenweg/app.ts | 30 +- src/apps/settings/modules/seelenweg/infra.tsx | 220 +- .../settings/modules/shared/config/infra.ts | 16 +- .../modules/shared/store/app/StateBridge.ts | 174 +- .../modules/shared/store/app/reducer.ts | 250 +- .../modules/shared/store/app/selectors.ts | 36 +- .../settings/modules/shared/store/domain.ts | 66 +- .../settings/modules/shared/store/infra.ts | 236 +- .../settings/modules/shared/store/storeApi.ts | 440 +- .../settings/modules/shared/tauri/infra.ts | 46 +- src/apps/settings/modules/shared/utils/app.ts | 156 +- .../settings/modules/shared/utils/app/Rect.ts | 38 +- .../settings/modules/shared/utils/domain.ts | 14 +- .../settings/modules/shared/utils/infra.ts | 24 +- src/apps/settings/modules/shortcuts/app.ts | 172 +- src/apps/settings/modules/shortcuts/domain.ts | 6 +- .../modules/shortcuts/infrastructure.tsx | 126 +- src/apps/settings/styles/colors.css | 1198 +- src/apps/settings/styles/global.css | 254 +- src/apps/settings/styles/reset.css | 166 +- src/apps/settings/styles/variables.css | 24 +- src/apps/shared/ConsoleWrapper.ts | 134 +- src/apps/shared/StateBuilder.ts | 200 +- src/apps/shared/Timing.ts | 88 +- .../shared/components/Icon/index.module.css | 12 +- src/apps/shared/components/Icon/index.tsx | 200 +- .../OverflowTooltip/index.module.css | 10 +- .../components/OverflowTooltip/index.tsx | 54 +- src/apps/shared/events.ts | 12 +- src/apps/shared/index.ts | 164 +- src/apps/shared/interfaces/common.ts | 4 +- src/apps/shared/lang.ts | 152 +- src/apps/shared/redux.ts | 42 +- src/apps/shared/schemas/AppsConfigurations.ts | 132 +- src/apps/shared/schemas/FancyToolbar.ts | 18 +- src/apps/shared/schemas/Layout.ts | 184 +- src/apps/shared/schemas/Monitors.ts | 44 +- src/apps/shared/schemas/Placeholders.ts | 336 +- src/apps/shared/schemas/SeelenWegItems.ts | 112 +- src/apps/shared/schemas/Seelenweg.ts | 90 +- src/apps/shared/schemas/Settings.ts | 220 +- src/apps/shared/schemas/Theme.ts | 30 +- src/apps/shared/schemas/WindowManager.ts | 92 +- src/apps/shared/schemas/index.test.ts | 118 +- src/apps/shared/schemas/index.ts | 176 +- src/apps/shared/styles.ts | 80 +- src/apps/toolbar-hitbox/index.css | 22 +- src/apps/toolbar-hitbox/index.html | 16 +- src/apps/toolbar-hitbox/index.tsx | 88 +- src/apps/toolbar/app.tsx | 106 +- .../toolbar/components/Error/index.module.css | 14 +- src/apps/toolbar/components/Error/index.tsx | 18 +- src/apps/toolbar/events.ts | 96 +- src/apps/toolbar/i18n/index.ts | 196 +- src/apps/toolbar/i18n/translations/af.yml | 68 +- src/apps/toolbar/i18n/translations/am.yml | 68 +- src/apps/toolbar/i18n/translations/ar.yml | 68 +- src/apps/toolbar/i18n/translations/az.yml | 68 +- src/apps/toolbar/i18n/translations/bg.yml | 68 +- src/apps/toolbar/i18n/translations/bn.yml | 68 +- src/apps/toolbar/i18n/translations/bs.yml | 68 +- src/apps/toolbar/i18n/translations/ca.yml | 68 +- src/apps/toolbar/i18n/translations/cs.yml | 68 +- src/apps/toolbar/i18n/translations/cy.yml | 68 +- src/apps/toolbar/i18n/translations/da.yml | 68 +- src/apps/toolbar/i18n/translations/de.yml | 68 +- src/apps/toolbar/i18n/translations/el.yml | 68 +- src/apps/toolbar/i18n/translations/en.yml | 70 +- src/apps/toolbar/i18n/translations/es.yml | 68 +- src/apps/toolbar/i18n/translations/et.yml | 68 +- src/apps/toolbar/i18n/translations/eu.yml | 68 +- src/apps/toolbar/i18n/translations/fa.yml | 68 +- src/apps/toolbar/i18n/translations/fi.yml | 68 +- src/apps/toolbar/i18n/translations/fr.yml | 68 +- src/apps/toolbar/i18n/translations/gu.yml | 68 +- src/apps/toolbar/i18n/translations/he.yml | 68 +- src/apps/toolbar/i18n/translations/hi.yml | 68 +- src/apps/toolbar/i18n/translations/hr.yml | 68 +- src/apps/toolbar/i18n/translations/hu.yml | 68 +- src/apps/toolbar/i18n/translations/hy.yml | 68 +- src/apps/toolbar/i18n/translations/id.yml | 68 +- src/apps/toolbar/i18n/translations/is.yml | 68 +- src/apps/toolbar/i18n/translations/it.yml | 68 +- src/apps/toolbar/i18n/translations/ja.yml | 68 +- src/apps/toolbar/i18n/translations/ka.yml | 68 +- src/apps/toolbar/i18n/translations/km.yml | 68 +- src/apps/toolbar/i18n/translations/ko.yml | 68 +- src/apps/toolbar/i18n/translations/ku.yml | 68 +- src/apps/toolbar/i18n/translations/lb.yml | 68 +- src/apps/toolbar/i18n/translations/lo.yml | 68 +- src/apps/toolbar/i18n/translations/lt.yml | 68 +- src/apps/toolbar/i18n/translations/lv.yml | 68 +- src/apps/toolbar/i18n/translations/mk.yml | 68 +- src/apps/toolbar/i18n/translations/mn.yml | 68 +- src/apps/toolbar/i18n/translations/ms.yml | 68 +- src/apps/toolbar/i18n/translations/mt.yml | 68 +- src/apps/toolbar/i18n/translations/ne.yml | 68 +- src/apps/toolbar/i18n/translations/nl.yml | 68 +- src/apps/toolbar/i18n/translations/no.yml | 68 +- src/apps/toolbar/i18n/translations/pa.yml | 68 +- src/apps/toolbar/i18n/translations/pl.yml | 68 +- src/apps/toolbar/i18n/translations/ps.yml | 68 +- src/apps/toolbar/i18n/translations/pt.yml | 68 +- src/apps/toolbar/i18n/translations/ro.yml | 68 +- src/apps/toolbar/i18n/translations/ru.yml | 68 +- src/apps/toolbar/i18n/translations/si.yml | 68 +- src/apps/toolbar/i18n/translations/sk.yml | 68 +- src/apps/toolbar/i18n/translations/so.yml | 68 +- src/apps/toolbar/i18n/translations/sr.yml | 68 +- src/apps/toolbar/i18n/translations/sv.yml | 68 +- src/apps/toolbar/i18n/translations/sw.yml | 68 +- src/apps/toolbar/i18n/translations/ta.yml | 68 +- src/apps/toolbar/i18n/translations/te.yml | 68 +- src/apps/toolbar/i18n/translations/tg.yml | 68 +- src/apps/toolbar/i18n/translations/th.yml | 68 +- src/apps/toolbar/i18n/translations/tl.yml | 68 +- src/apps/toolbar/i18n/translations/tr.yml | 68 +- src/apps/toolbar/i18n/translations/uk.yml | 68 +- src/apps/toolbar/i18n/translations/ur.yml | 68 +- src/apps/toolbar/i18n/translations/uz.yml | 68 +- src/apps/toolbar/i18n/translations/vi.yml | 68 +- src/apps/toolbar/i18n/translations/yo.yml | 68 +- src/apps/toolbar/i18n/translations/zh.yml | 68 +- src/apps/toolbar/i18n/translations/zu.yml | 68 +- src/apps/toolbar/index.html | 20 +- src/apps/toolbar/index.tsx | 78 +- src/apps/toolbar/modules/Date/infra.tsx | 56 +- src/apps/toolbar/modules/Device/infra.tsx | 22 +- .../modules/Notifications/infra/Module.tsx | 84 +- .../Notifications/infra/Notifications.tsx | 198 +- src/apps/toolbar/modules/Power/infra.tsx | 72 +- src/apps/toolbar/modules/Settings/infra.tsx | 316 +- src/apps/toolbar/modules/Tray/index.tsx | 142 +- src/apps/toolbar/modules/Workspaces/index.tsx | 132 +- src/apps/toolbar/modules/item/app.ts | 178 +- src/apps/toolbar/modules/item/infra.tsx | 462 +- src/apps/toolbar/modules/main/application.ts | 80 +- src/apps/toolbar/modules/main/infra.tsx | 212 +- src/apps/toolbar/modules/media/application.ts | 86 +- .../modules/media/infra/MediaControls.tsx | 520 +- .../toolbar/modules/media/infra/Module.tsx | 68 +- .../toolbar/modules/media/infra/index.css | 102 +- src/apps/toolbar/modules/network/domain.ts | 32 +- .../toolbar/modules/network/infra/Module.tsx | 94 +- .../modules/network/infra/WlanSelector.tsx | 168 +- .../network/infra/WlanSelectorEntry.tsx | 282 +- .../toolbar/modules/shared/hooks/infra.ts | 72 +- src/apps/toolbar/modules/shared/store/app.ts | 154 +- .../toolbar/modules/shared/store/domain.ts | 214 +- .../toolbar/modules/shared/store/infra.ts | 308 +- src/apps/toolbar/modules/shared/utils/app.ts | 28 +- .../toolbar/modules/shared/utils/domain.ts | 2 +- .../toolbar/modules/shared/utils/infra.ts | 48 +- src/apps/toolbar/styles/colors.css | 1198 +- src/apps/toolbar/styles/global.css | 446 +- src/apps/toolbar/styles/reset.css | 268 +- src/apps/toolbar/styles/variables.css | 14 +- src/apps/update/app.tsx | 86 +- src/apps/update/i18n/index.ts | 196 +- src/apps/update/i18n/translations/af.yml | 24 +- src/apps/update/i18n/translations/am.yml | 20 +- src/apps/update/i18n/translations/ar.yml | 20 +- src/apps/update/i18n/translations/az.yml | 24 +- src/apps/update/i18n/translations/bg.yml | 20 +- src/apps/update/i18n/translations/bn.yml | 20 +- src/apps/update/i18n/translations/bs.yml | 20 +- src/apps/update/i18n/translations/ca.yml | 20 +- src/apps/update/i18n/translations/cs.yml | 20 +- src/apps/update/i18n/translations/cy.yml | 20 +- src/apps/update/i18n/translations/da.yml | 20 +- src/apps/update/i18n/translations/de.yml | 24 +- src/apps/update/i18n/translations/el.yml | 20 +- src/apps/update/i18n/translations/en.yml | 20 +- src/apps/update/i18n/translations/es.yml | 24 +- src/apps/update/i18n/translations/et.yml | 20 +- src/apps/update/i18n/translations/eu.yml | 24 +- src/apps/update/i18n/translations/fa.yml | 20 +- src/apps/update/i18n/translations/fi.yml | 20 +- src/apps/update/i18n/translations/fr.yml | 24 +- src/apps/update/i18n/translations/gu.yml | 20 +- src/apps/update/i18n/translations/he.yml | 20 +- src/apps/update/i18n/translations/hi.yml | 20 +- src/apps/update/i18n/translations/hr.yml | 20 +- src/apps/update/i18n/translations/hu.yml | 24 +- src/apps/update/i18n/translations/hy.yml | 24 +- src/apps/update/i18n/translations/id.yml | 20 +- src/apps/update/i18n/translations/is.yml | 20 +- src/apps/update/i18n/translations/it.yml | 20 +- src/apps/update/i18n/translations/ja.yml | 20 +- src/apps/update/i18n/translations/ka.yml | 24 +- src/apps/update/i18n/translations/km.yml | 20 +- src/apps/update/i18n/translations/ko.yml | 20 +- src/apps/update/i18n/translations/ku.yml | 20 +- src/apps/update/i18n/translations/lb.yml | 20 +- src/apps/update/i18n/translations/lo.yml | 20 +- src/apps/update/i18n/translations/lt.yml | 20 +- src/apps/update/i18n/translations/lv.yml | 20 +- src/apps/update/i18n/translations/mk.yml | 24 +- src/apps/update/i18n/translations/mn.yml | 24 +- src/apps/update/i18n/translations/ms.yml | 20 +- src/apps/update/i18n/translations/mt.yml | 20 +- src/apps/update/i18n/translations/ne.yml | 20 +- src/apps/update/i18n/translations/nl.yml | 20 +- src/apps/update/i18n/translations/no.yml | 20 +- src/apps/update/i18n/translations/pa.yml | 20 +- src/apps/update/i18n/translations/pl.yml | 20 +- src/apps/update/i18n/translations/ps.yml | 20 +- src/apps/update/i18n/translations/pt.yml | 20 +- src/apps/update/i18n/translations/ro.yml | 20 +- src/apps/update/i18n/translations/ru.yml | 24 +- src/apps/update/i18n/translations/si.yml | 20 +- src/apps/update/i18n/translations/sk.yml | 20 +- src/apps/update/i18n/translations/so.yml | 20 +- src/apps/update/i18n/translations/sr.yml | 20 +- src/apps/update/i18n/translations/sv.yml | 20 +- src/apps/update/i18n/translations/sw.yml | 24 +- src/apps/update/i18n/translations/ta.yml | 20 +- src/apps/update/i18n/translations/te.yml | 20 +- src/apps/update/i18n/translations/tg.yml | 20 +- src/apps/update/i18n/translations/th.yml | 20 +- src/apps/update/i18n/translations/tl.yml | 24 +- src/apps/update/i18n/translations/tr.yml | 20 +- src/apps/update/i18n/translations/uk.yml | 20 +- src/apps/update/i18n/translations/ur.yml | 20 +- src/apps/update/i18n/translations/uz.yml | 24 +- src/apps/update/i18n/translations/vi.yml | 20 +- src/apps/update/i18n/translations/yo.yml | 20 +- src/apps/update/i18n/translations/zh.yml | 20 +- src/apps/update/i18n/translations/zu.yml | 20 +- src/apps/update/index.html | 26 +- src/apps/update/index.tsx | 56 +- src/apps/update/styles/colors.css | 1198 +- src/apps/update/styles/global.css | 162 +- src/apps/update/styles/reset.css | 166 +- src/apps/update/update.tsx | 168 +- src/background/error_handler.rs | 232 +- src/background/exposed.rs | 442 +- src/background/hook.rs | 612 +- src/background/main.rs | 320 +- src/background/modules/cli/application.rs | 410 +- src/background/modules/cli/domain.rs | 36 +- src/background/modules/cli/mod.rs | 148 +- src/background/modules/input/domain.rs | 128 +- src/background/modules/input/mod.rs | 1610 +- src/background/modules/media/application.rs | 1482 +- src/background/modules/media/domain.rs | 540 +- .../modules/media/infrastructure.rs | 216 +- src/background/modules/media/mod.rs | 6 +- src/background/modules/mod.rs | 20 +- src/background/modules/monitors/mod.rs | 384 +- .../modules/network/application/mod.rs | 326 +- .../network/application/profile.template.xml | 50 +- .../modules/network/application/profiles.ps1 | 40 +- .../modules/network/application/scanner.rs | 514 +- src/background/modules/network/domain/mod.rs | 338 +- .../modules/network/domain/types.rs | 470 +- .../modules/network/infrastructure.rs | 264 +- src/background/modules/network/mod.rs | 6 +- .../modules/notifications/application.rs | 454 +- .../modules/notifications/infrastructure.rs | 92 +- src/background/modules/notifications/mod.rs | 4 +- src/background/modules/power/domain.rs | 170 +- .../modules/power/infrastructure.rs | 354 +- src/background/modules/power/mod.rs | 4 +- .../modules/system_settings/application.rs | 220 +- .../modules/system_settings/domain.rs | 32 +- .../modules/system_settings/infrastructure.rs | 70 +- src/background/modules/system_settings/mod.rs | 6 +- src/background/modules/tray/application.rs | 532 +- src/background/modules/tray/domain.rs | 38 +- src/background/modules/tray/infrastructure.rs | 98 +- src/background/modules/tray/mod.rs | 6 +- src/background/modules/uwp/load_uwp_apps.ps1 | 116 +- src/background/modules/uwp/mod.rs | 348 +- src/background/monitor.rs | 262 +- src/background/plugins.rs | 124 +- src/background/schedule.ps1 | 68 +- src/background/seelen.rs | 824 +- src/background/seelen_bar/cli.rs | 66 +- src/background/seelen_bar/hook.rs | 92 +- src/background/seelen_bar/mod.rs | 458 +- src/background/seelen_shell/mod.rs | 24 +- src/background/seelen_weg/handler.rs | 166 +- src/background/seelen_weg/hook.rs | 258 +- src/background/seelen_weg/icon_extractor.rs | 410 +- src/background/seelen_weg/mod.rs | 920 +- src/background/seelen_wm/cli.rs | 322 +- src/background/seelen_wm/handler.rs | 142 +- src/background/seelen_wm/hook.rs | 240 +- src/background/seelen_wm/mod.rs | 704 +- .../state/application/apps_config.rs | 268 +- src/background/state/application/mod.rs | 814 +- src/background/state/domain/mod.rs | 254 +- src/background/state/domain/settings.rs | 722 +- src/background/state/infrastructure.rs | 110 +- src/background/state/mod.rs | 84 +- src/background/system/brightness.rs | 126 +- src/background/system/mod.rs | 120 +- src/background/tray.rs | 170 +- src/background/utils/ahk/mocks/seelen.ahk | 38 +- src/background/utils/ahk/mocks/seelen.lib.ahk | 144 +- src/background/utils/ahk/mocks/seelen.wm.ahk | 322 +- src/background/utils/ahk/mod.rs | 316 +- src/background/utils/constants.rs | 74 +- src/background/utils/mod.rs | 312 +- src/background/utils/pwsh.rs | 128 +- src/background/utils/rect.rs | 84 +- src/background/utils/virtual_desktop.rs | 224 +- src/background/windows_api/app_bar.rs | 188 +- src/background/windows_api/com.rs | 130 +- src/background/windows_api/iterator.rs | 192 +- src/background/windows_api/mod.rs | 1384 +- src/background/winevent.rs | 742 +- src/globals.d.ts | 24 +- src/shared.interfaces.ts | 58 +- static/apps_templates/adobe.yml | 12 +- static/apps_templates/browser.yml | 12 +- static/apps_templates/core.yml | 26 +- static/apps_templates/development.yml | 12 +- static/apps_templates/gaming.yml | 38 +- static/apps_templates/uncategorized.yml | 1190 +- static/icons/icon.svg | 28 +- static/layouts/BSP.json | 86 +- static/layouts/Grid.json | 146 +- static/layouts/Tall.json | 68 +- static/layouts/Wide.json | 68 +- static/placeholders/default.yml | 216 +- static/placeholders/default_alter.yml | 224 +- static/themes/bubbles.yml | 64 +- static/themes/default/theme.toolbar.css | 832 +- static/themes/default/theme.weg.css | 308 +- static/themes/default/theme.wm.css | 56 +- static/themes/default/theme.yml | 20 +- static/themes/rainbow.yml | 68 +- tauri.conf.json | 174 +- templates/installer.nsi | 1758 +- tsconfig.json | 60 +- 623 files changed, 68111 insertions(+), 68111 deletions(-) diff --git a/.commitlintrc.yml b/.commitlintrc.yml index 261dbc5f..2ea26d9a 100644 --- a/.commitlintrc.yml +++ b/.commitlintrc.yml @@ -1,30 +1,30 @@ -# commitlint.config.yml -extends: - - "@commitlint/config-conventional" - -rules: - # Basic rules - header-max-length: [2, "always", 72] - body-max-line-length: [2, "always", 100] - - # Commit type - type-enum: - - 2 - - "always" - - [ - "feat", # New feature - "fix", # Bug fix - "docs", # Documentation changes - "style", # Code formatting, white spaces, etc. - "refactor", # Code refactoring - "perf", # Performance improvement - "test", # Adding or fixing tests - "build", # Changes affecting the build system or external dependencies - "ci", # Changes to CI configuration files and scripts - "chore", # Other changes that don't modify src or test files - "delete", # Deleting unused files - "revert", # Reverting to a previous commit - ] - - scope-empty: [2, "never"] +# commitlint.config.yml +extends: + - "@commitlint/config-conventional" + +rules: + # Basic rules + header-max-length: [2, "always", 72] + body-max-line-length: [2, "always", 100] + + # Commit type + type-enum: + - 2 + - "always" + - [ + "feat", # New feature + "fix", # Bug fix + "docs", # Documentation changes + "style", # Code formatting, white spaces, etc. + "refactor", # Code refactoring + "perf", # Performance improvement + "test", # Adding or fixing tests + "build", # Changes affecting the build system or external dependencies + "ci", # Changes to CI configuration files and scripts + "chore", # Other changes that don't modify src or test files + "delete", # Deleting unused files + "revert", # Reverting to a previous commit + ] + + scope-empty: [2, "never"] subject-empty: [2, "never"] \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index eb45caf6..948a89c1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,24 +1,24 @@ ---- -name: Bug report 🐛 -about: Create a report to help us improve -title: "[BUG] All its on fire!." -labels: bug -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. +--- +name: Bug report 🐛 +about: Create a report to help us improve +title: "[BUG] All its on fire!." +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index a87f0c78..573d1fb1 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,20 +1,20 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: "[FEAT] Include a pandora box" -labels: enhancement, feature request -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. +--- +name: Feature request +about: Suggest an idea for this project +title: "[FEAT] Include a pandora box" +labels: enhancement, feature request +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/translation.md b/.github/ISSUE_TEMPLATE/translation.md index de3a07c2..8adfaf75 100644 --- a/.github/ISSUE_TEMPLATE/translation.md +++ b/.github/ISSUE_TEMPLATE/translation.md @@ -1,27 +1,27 @@ ---- -name: Translation Error Report 📝 -about: Report a translation error in the application -title: "[LANG] Descriptive Title" -labels: translation, bug -assignees: '' - ---- - -**Description of the Error** 🛠️ -A clear and concise description of what the translation error is. - -**To Reproduce** 🔍 -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '...' -3. Scroll to '...' -4. Observe the error - -**Expected Behavior** ✨ -A clear and concise description of what you expected to happen instead of the translation error. - -**Screenshots** 📸 -If applicable, add screenshots to help explain the issue. - -**Additional Context** ℹ️ -Add any other context about the problem here, such as the language you are using the application in and any other relevant information. +--- +name: Translation Error Report 📝 +about: Report a translation error in the application +title: "[LANG] Descriptive Title" +labels: translation, bug +assignees: '' + +--- + +**Description of the Error** 🛠️ +A clear and concise description of what the translation error is. + +**To Reproduce** 🔍 +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '...' +3. Scroll to '...' +4. Observe the error + +**Expected Behavior** ✨ +A clear and concise description of what you expected to happen instead of the translation error. + +**Screenshots** 📸 +If applicable, add screenshots to help explain the issue. + +**Additional Context** ℹ️ +Add any other context about the problem here, such as the language you are using the application in and any other relevant information. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4fe61375..6f29a9a9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,57 +1,57 @@ -name: Continuous Integration - -on: - push: - branches: - - master - pull_request: - branches: - - master - workflow_dispatch: - -jobs: - check-js: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: "npm" - - run: npm install - - run: npm run lint - - run: npm run test - - check-rust: - runs-on: windows-latest - steps: - - uses: actions/checkout@v4 - - - uses: dtolnay/rust-toolchain@master - with: - toolchain: nightly-2024-06-25 - - uses: Swatinem/rust-cache@v2 - - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: "npm" - - - name: Build - run: |- - npm install - npm run build:ui - cargo build - - - name: Run linter - run: |- - rustup component add rustfmt - cargo fmt -- --check - - - name: Run clippy - run: |- - rustup component add clippy - cargo clippy --all-targets -- -D warnings - - - name: Run tests - run: cargo test --verbose +name: Continuous Integration + +on: + push: + branches: + - master + pull_request: + branches: + - master + workflow_dispatch: + +jobs: + check-js: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "npm" + - run: npm install + - run: npm run lint + - run: npm run test + + check-rust: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + + - uses: dtolnay/rust-toolchain@master + with: + toolchain: nightly-2024-06-25 + - uses: Swatinem/rust-cache@v2 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "npm" + + - name: Build + run: |- + npm install + npm run build:ui + cargo build + + - name: Run linter + run: |- + rustup component add rustfmt + cargo fmt -- --check + + - name: Run clippy + run: |- + rustup component add clippy + cargo clippy --all-targets -- -D warnings + + - name: Run tests + run: cargo test --verbose diff --git a/.github/workflows/msix.yml b/.github/workflows/msix.yml index 5c75824c..b9d12ba7 100644 --- a/.github/workflows/msix.yml +++ b/.github/workflows/msix.yml @@ -1,73 +1,73 @@ -name: Upload store MSIX to release - -permissions: - contents: write - -on: - schedule: - - cron: "0 */6 * * *" # Run the action every 6 hours - workflow_dispatch: # Manually run the action - -jobs: - check-msix: - runs-on: ubuntu-latest - outputs: - MSIX_ALREADY_EXIST: ${{ steps.check_msix.outputs.MSIX_ALREADY_EXIST }} - steps: - - name: Check for MSIX file in latest release - id: check_msix - uses: actions/github-script@v7 - with: - script: | - const { owner, repo } = context.repo; - const latestRelease = await github.rest.repos.getLatestRelease({ owner, repo }); - - // Check if .msix file exists in the release assets - const msixAsset = latestRelease.data.assets.find(asset => asset.name.endsWith('.msix')); - - if (msixAsset) { - core.setOutput('MSIX_ALREADY_EXIST', 'true'); - console.log('MSIX file exists.'); - } else { - core.setOutput('MSIX_ALREADY_EXIST', 'false'); - console.log('No MSIX file found in the latest release.'); - } - - upload-store-msix-to-release: - name: Upload Signed MSIX to release - needs: check-msix - if: ${{ needs.check-msix.outputs.MSIX_ALREADY_EXIST == 'false' }} - runs-on: ubuntu-latest - steps: - - name: Upload store MSIX to release - uses: JasonWei512/Upload-Microsoft-Store-MSIX-Package-to-GitHub-Release@v1 - with: - store-id: 9p67c2d4t9fb - token: ${{ secrets.GITHUB_TOKEN }} - - msix-to-winget: - name: MSIX to Winget - needs: upload-store-msix-to-release - runs-on: windows-latest - steps: - - name: Get Latest Release - id: get-version - uses: actions/github-script@v7 - with: - script: |- - const { owner, repo } = context.repo; - const latestRelease = await github.rest.repos.getLatestRelease({ owner, repo }); - const tag = latestRelease.data.tag_name; - const version = tag.replace("v", "") + ".0"; - core.setOutput('version', version); - core.setOutput('release-tag', tag); - console.log("Release tag: ", tag, " Version: ", version); - - - uses: vedantmgoyal9/winget-releaser@main - with: - identifier: Seelen.SeelenUI - version: ${{ steps.get-version.outputs.version }} - release-tag: ${{ steps.get-version.outputs.release-tag }} - installers-regex: '\.msix$' - fork-user: eythaann - token: ${{ secrets.WINGET_TOKEN }} +name: Upload store MSIX to release + +permissions: + contents: write + +on: + schedule: + - cron: "0 */6 * * *" # Run the action every 6 hours + workflow_dispatch: # Manually run the action + +jobs: + check-msix: + runs-on: ubuntu-latest + outputs: + MSIX_ALREADY_EXIST: ${{ steps.check_msix.outputs.MSIX_ALREADY_EXIST }} + steps: + - name: Check for MSIX file in latest release + id: check_msix + uses: actions/github-script@v7 + with: + script: | + const { owner, repo } = context.repo; + const latestRelease = await github.rest.repos.getLatestRelease({ owner, repo }); + + // Check if .msix file exists in the release assets + const msixAsset = latestRelease.data.assets.find(asset => asset.name.endsWith('.msix')); + + if (msixAsset) { + core.setOutput('MSIX_ALREADY_EXIST', 'true'); + console.log('MSIX file exists.'); + } else { + core.setOutput('MSIX_ALREADY_EXIST', 'false'); + console.log('No MSIX file found in the latest release.'); + } + + upload-store-msix-to-release: + name: Upload Signed MSIX to release + needs: check-msix + if: ${{ needs.check-msix.outputs.MSIX_ALREADY_EXIST == 'false' }} + runs-on: ubuntu-latest + steps: + - name: Upload store MSIX to release + uses: JasonWei512/Upload-Microsoft-Store-MSIX-Package-to-GitHub-Release@v1 + with: + store-id: 9p67c2d4t9fb + token: ${{ secrets.GITHUB_TOKEN }} + + msix-to-winget: + name: MSIX to Winget + needs: upload-store-msix-to-release + runs-on: windows-latest + steps: + - name: Get Latest Release + id: get-version + uses: actions/github-script@v7 + with: + script: |- + const { owner, repo } = context.repo; + const latestRelease = await github.rest.repos.getLatestRelease({ owner, repo }); + const tag = latestRelease.data.tag_name; + const version = tag.replace("v", "") + ".0"; + core.setOutput('version', version); + core.setOutput('release-tag', tag); + console.log("Release tag: ", tag, " Version: ", version); + + - uses: vedantmgoyal9/winget-releaser@main + with: + identifier: Seelen.SeelenUI + version: ${{ steps.get-version.outputs.version }} + release-tag: ${{ steps.get-version.outputs.release-tag }} + installers-regex: '\.msix$' + fork-user: eythaann + token: ${{ secrets.WINGET_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 78507048..a35a810b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,206 +1,206 @@ -name: "Release" - -on: - push: - tags: - - "v*" - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -jobs: - run-tests-and-linter: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 20 - - run: npm clean-install - - run: npm run lint - - run: npm run test - - create-release: - needs: run-tests-and-linter - runs-on: ubuntu-latest - permissions: - contents: write - outputs: - release_id: ${{ steps.create-release.outputs.result }} - - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Get version - run: echo "PACKAGE_VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_ENV - - - name: Create release - id: create-release - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs'); - const changelogContent = fs.readFileSync('changelog.md', 'utf-8'); - const regex = new RegExp(`(?<=\\[${process.env.PACKAGE_VERSION}\\]\\s)([\\s\\S]*?)(?=\\s## \\[)`, 'g'); - const releaseNotes = changelogContent.match(regex)?.[0].trim() || ''; - - const { data } = await github.rest.repos.createRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - tag_name: `v${process.env.PACKAGE_VERSION}`, - name: `Seelen UI v${process.env.PACKAGE_VERSION}`, - body: releaseNotes, - generate_release_notes: true, - draft: true, - prerelease: false, - }); - return data.id; - - build-installers: - needs: create-release - permissions: - contents: write - strategy: - fail-fast: false - matrix: - include: - - platform: "windows-latest" - args: "" - - runs-on: ${{ matrix.platform }} - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Install Rust Nightly - uses: dtolnay/rust-toolchain@master - with: - toolchain: nightly-2024-06-25 - - - name: Install frontend dependencies - run: npm install - - - uses: tauri-apps/tauri-action@v0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} - TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} - with: - releaseId: ${{ needs.create-release.outputs.release_id }} - args: ${{ matrix.args }} - - - name: Install winget - if: matrix.platform == 'windows-latest' - uses: Cyberboss/install-winget@v1 - - - name: Install MSIX dependencies - if: matrix.platform == 'windows-latest' - shell: powershell - run: | - winget install --id Microsoft.DotNet.AspNetCore.8 --accept-package-agreements --accept-source-agreements --force - winget install --id Microsoft.DotNet.DesktopRuntime.8 --accept-package-agreements --accept-source-agreements --force - winget install --id MarcinOtorowski.MSIXHero --accept-package-agreements --accept-source-agreements --force - - - name: Bundle MSIX - if: matrix.platform == 'windows-latest' - run: npx ts-node scripts/bundle.msix.ts - - - name: Upload artifacts - id: artifact-upload-step - uses: actions/upload-artifact@v4 - with: - name: build-bundle - path: target/release/bundle - - - name: Output artifact ID - run: echo 'Artifact ID is ${{ steps.artifact-upload-step.outputs.artifact-id }}' - - microsoft-store-submission: - needs: build-installers - runs-on: windows-latest - steps: - - uses: actions/checkout@v4 - - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - name: build-bundle - path: target/release/bundle - - # Use Store Broker to publish to Microsoft Store - - name: Submit to Partner Center (aka DevCenter) - shell: pwsh - run: | - ./scripts/SubmitToStore.ps1 - env: - PartnerCenterStoreId: ${{ secrets.MS_PRODUCT_ID }} - PartnerCenterTenantId: ${{ secrets.MS_TENANT_ID }} - PartnerCenterClientId: ${{ secrets.MS_CLIENT_ID }} - PartnerCenterClientSecret: ${{ secrets.MS_CLIENT_SECRET }} - SBDisableTelemetry: true - - publish-release: - needs: [build-installers, create-release] - permissions: - contents: write - runs-on: ubuntu-latest - steps: - - name: Publish release - uses: actions/github-script@v7 - env: - releaseId: ${{ needs.create-release.outputs.release_id }} - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" - script: | - const result = await github.rest.repos.listReleaseAssets({ - owner: context.repo.owner, - repo: context.repo.repo, - release_id: process.env.releaseId, - }); - - result.data.forEach(async (asset) => { - if (asset.name.endsWith('.sig')) { - await github.rest.repos.deleteReleaseAsset({ - owner: context.repo.owner, - repo: context.repo.repo, - asset_id: asset.id, - }); - } - }); - - await github.rest.repos.updateRelease({ - owner: context.repo.owner, - repo: context.repo.repo, - release_id: process.env.releaseId, - draft: false, - }); - - discord: - needs: publish-release - name: Send Announcement To Discord Server - runs-on: ubuntu-latest - steps: - - name: Discord notification - uses: LeGitHubDeTai/github-to-discord@main - env: - DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} - DISCORD_USERNAME: Seelen - DISCORD_AVATAR: https://raw.githubusercontent.com/eythaann/Seelen-UI/master/documentation/images/logo_with_margins.png - - AUTHOR_NAME: eythaann - AUTHOR_URL: "https://github.com/eythaann" - AUTHOR_AVATAR: "https://avatars.githubusercontent.com/u/76607907?v=4" - - MESSAGE_TITLE: Seelen UI - MESSAGE_DESCRIPTION: A new release of Seelen UI has been published - MESSAGE_COLOR: 5814783 - - SECTION_NAME: "ChangeLog" - - FOOTER_TEXT: "Seelen Inc." - FOOTER_URL: "https://github.com/eythaann/seelen-ui" +name: "Release" + +on: + push: + tags: + - "v*" + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + run-tests-and-linter: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + - run: npm clean-install + - run: npm run lint + - run: npm run test + + create-release: + needs: run-tests-and-linter + runs-on: ubuntu-latest + permissions: + contents: write + outputs: + release_id: ${{ steps.create-release.outputs.result }} + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Get version + run: echo "PACKAGE_VERSION=$(node -p "require('./package.json').version")" >> $GITHUB_ENV + + - name: Create release + id: create-release + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const changelogContent = fs.readFileSync('changelog.md', 'utf-8'); + const regex = new RegExp(`(?<=\\[${process.env.PACKAGE_VERSION}\\]\\s)([\\s\\S]*?)(?=\\s## \\[)`, 'g'); + const releaseNotes = changelogContent.match(regex)?.[0].trim() || ''; + + const { data } = await github.rest.repos.createRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + tag_name: `v${process.env.PACKAGE_VERSION}`, + name: `Seelen UI v${process.env.PACKAGE_VERSION}`, + body: releaseNotes, + generate_release_notes: true, + draft: true, + prerelease: false, + }); + return data.id; + + build-installers: + needs: create-release + permissions: + contents: write + strategy: + fail-fast: false + matrix: + include: + - platform: "windows-latest" + args: "" + + runs-on: ${{ matrix.platform }} + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Install Rust Nightly + uses: dtolnay/rust-toolchain@master + with: + toolchain: nightly-2024-06-25 + + - name: Install frontend dependencies + run: npm install + + - uses: tauri-apps/tauri-action@v0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + with: + releaseId: ${{ needs.create-release.outputs.release_id }} + args: ${{ matrix.args }} + + - name: Install winget + if: matrix.platform == 'windows-latest' + uses: Cyberboss/install-winget@v1 + + - name: Install MSIX dependencies + if: matrix.platform == 'windows-latest' + shell: powershell + run: | + winget install --id Microsoft.DotNet.AspNetCore.8 --accept-package-agreements --accept-source-agreements --force + winget install --id Microsoft.DotNet.DesktopRuntime.8 --accept-package-agreements --accept-source-agreements --force + winget install --id MarcinOtorowski.MSIXHero --accept-package-agreements --accept-source-agreements --force + + - name: Bundle MSIX + if: matrix.platform == 'windows-latest' + run: npx ts-node scripts/bundle.msix.ts + + - name: Upload artifacts + id: artifact-upload-step + uses: actions/upload-artifact@v4 + with: + name: build-bundle + path: target/release/bundle + + - name: Output artifact ID + run: echo 'Artifact ID is ${{ steps.artifact-upload-step.outputs.artifact-id }}' + + microsoft-store-submission: + needs: build-installers + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + name: build-bundle + path: target/release/bundle + + # Use Store Broker to publish to Microsoft Store + - name: Submit to Partner Center (aka DevCenter) + shell: pwsh + run: | + ./scripts/SubmitToStore.ps1 + env: + PartnerCenterStoreId: ${{ secrets.MS_PRODUCT_ID }} + PartnerCenterTenantId: ${{ secrets.MS_TENANT_ID }} + PartnerCenterClientId: ${{ secrets.MS_CLIENT_ID }} + PartnerCenterClientSecret: ${{ secrets.MS_CLIENT_SECRET }} + SBDisableTelemetry: true + + publish-release: + needs: [build-installers, create-release] + permissions: + contents: write + runs-on: ubuntu-latest + steps: + - name: Publish release + uses: actions/github-script@v7 + env: + releaseId: ${{ needs.create-release.outputs.release_id }} + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + script: | + const result = await github.rest.repos.listReleaseAssets({ + owner: context.repo.owner, + repo: context.repo.repo, + release_id: process.env.releaseId, + }); + + result.data.forEach(async (asset) => { + if (asset.name.endsWith('.sig')) { + await github.rest.repos.deleteReleaseAsset({ + owner: context.repo.owner, + repo: context.repo.repo, + asset_id: asset.id, + }); + } + }); + + await github.rest.repos.updateRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + release_id: process.env.releaseId, + draft: false, + }); + + discord: + needs: publish-release + name: Send Announcement To Discord Server + runs-on: ubuntu-latest + steps: + - name: Discord notification + uses: LeGitHubDeTai/github-to-discord@main + env: + DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} + DISCORD_USERNAME: Seelen + DISCORD_AVATAR: https://raw.githubusercontent.com/eythaann/Seelen-UI/master/documentation/images/logo_with_margins.png + + AUTHOR_NAME: eythaann + AUTHOR_URL: "https://github.com/eythaann" + AUTHOR_AVATAR: "https://avatars.githubusercontent.com/u/76607907?v=4" + + MESSAGE_TITLE: Seelen UI + MESSAGE_DESCRIPTION: A new release of Seelen UI has been published + MESSAGE_COLOR: 5814783 + + SECTION_NAME: "ChangeLog" + + FOOTER_TEXT: "Seelen Inc." + FOOTER_URL: "https://github.com/eythaann/seelen-ui" diff --git a/.github/workflows/web_deployment.yml b/.github/workflows/web_deployment.yml index ae78af9e..3c6c57e3 100644 --- a/.github/workflows/web_deployment.yml +++ b/.github/workflows/web_deployment.yml @@ -1,86 +1,86 @@ -name: Deploy Website to Github Pages - -on: - repository_dispatch: - types: [trigger-deployment] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - ssh-key: ${{ secrets.SSH_PRIVATE_KEY }} - repository: Seelen-Inc/seelen-web - - - name: Detect package manager - id: detect-package-manager - run: | - if [ -f "${{ github.workspace }}/package.json" ]; then - echo "manager=npm" >> $GITHUB_OUTPUT - echo "command=ci" >> $GITHUB_OUTPUT - echo "runner=npx --no-install" >> $GITHUB_OUTPUT - exit 0 - fi - - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: "20" - cache: ${{ steps.detect-package-manager.outputs.manager }} - - - name: Setup Pages - uses: actions/configure-pages@v4 - with: - static_site_generator: next - - - name: Restore cache - uses: actions/cache@v3 - with: - path: | - .next/cache - # Generate a new cache whenever packages or source files change. - key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} - # If source files changed but packages didn't, rebuild from a prior cache. - restore-keys: | - ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}- - - - name: Install dependencies - run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }} - - - name: Build with Next.js - run: ${{ steps.detect-package-manager.outputs.runner }} next build - - - name: Static HTML export with Next.js - run: ${{ steps.detect-package-manager.outputs.runner }} next export - - - name: Upload artifact - uses: actions/upload-pages-artifact@v3 - with: - path: ./out - - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment +name: Deploy Website to Github Pages + +on: + repository_dispatch: + types: [trigger-deployment] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ssh-key: ${{ secrets.SSH_PRIVATE_KEY }} + repository: Seelen-Inc/seelen-web + + - name: Detect package manager + id: detect-package-manager + run: | + if [ -f "${{ github.workspace }}/package.json" ]; then + echo "manager=npm" >> $GITHUB_OUTPUT + echo "command=ci" >> $GITHUB_OUTPUT + echo "runner=npx --no-install" >> $GITHUB_OUTPUT + exit 0 + fi + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: ${{ steps.detect-package-manager.outputs.manager }} + + - name: Setup Pages + uses: actions/configure-pages@v4 + with: + static_site_generator: next + + - name: Restore cache + uses: actions/cache@v3 + with: + path: | + .next/cache + # Generate a new cache whenever packages or source files change. + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} + # If source files changed but packages didn't, rebuild from a prior cache. + restore-keys: | + ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}- + + - name: Install dependencies + run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }} + + - name: Build with Next.js + run: ${{ steps.detect-package-manager.outputs.runner }} next build + + - name: Static HTML export with Next.js + run: ${{ steps.detect-package-manager.outputs.runner }} next export + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./out + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/.gitignore b/.gitignore index be6e2d58..cd59f9e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,12 @@ -/.vscode -/dist -/out -/node_modules -.env -target -gen -/.cert - -# Submission Files -/scripts/SBTemp +/.vscode +/dist +/out +/node_modules +.env +target +gen +/.cert + +# Submission Files +/scripts/SBTemp monitoring.ps1 \ No newline at end of file diff --git a/CLA.md b/CLA.md index 3de9fd78..547e10d6 100644 --- a/CLA.md +++ b/CLA.md @@ -1,19 +1,19 @@ -Seelen UI - Individual Contributor License Agreement (CLA) - -Thank you for your interest in contributing to the Seelen UI project. By submitting a contribution to the Project, you agree to the following terms and conditions: - -1. Grant of License: - By submitting a contribution to the Project, you grant the Project Owner a non-exclusive, perpetual, irrevocable, worldwide license to use, copy, modify, distribute, and sublicense your contribution, as well as any derivative works thereof, under the terms of the open-source license under which the Project is distributed. - -2. Copyright: - You represent that you are the legitimate author of the submitted contribution or that you have the necessary rights to grant the license described in point 1 above. - -3. Warranties: - You acknowledge that your contribution is provided "as is" and that you waive any warranties, express or implied, including, but not limited to, the warranties of merchantability, fitness for a particular purpose, and non-infringement. - -4. Representations and Warranties: - You warrant that the contribution you submit does not infringe any third-party intellectual property rights, and in the event of any third-party claim arising out of or related to your contribution, you agree to indemnify and hold harmless the Project Owner and its affiliates, agents, licensees, and sublicensees. - -5. Acceptance: - By submitting your contribution to the Project, you agree to abide by these terms and conditions. - +Seelen UI - Individual Contributor License Agreement (CLA) + +Thank you for your interest in contributing to the Seelen UI project. By submitting a contribution to the Project, you agree to the following terms and conditions: + +1. Grant of License: + By submitting a contribution to the Project, you grant the Project Owner a non-exclusive, perpetual, irrevocable, worldwide license to use, copy, modify, distribute, and sublicense your contribution, as well as any derivative works thereof, under the terms of the open-source license under which the Project is distributed. + +2. Copyright: + You represent that you are the legitimate author of the submitted contribution or that you have the necessary rights to grant the license described in point 1 above. + +3. Warranties: + You acknowledge that your contribution is provided "as is" and that you waive any warranties, express or implied, including, but not limited to, the warranties of merchantability, fitness for a particular purpose, and non-infringement. + +4. Representations and Warranties: + You warrant that the contribution you submit does not infringe any third-party intellectual property rights, and in the event of any third-party claim arising out of or related to your contribution, you agree to indemnify and hold harmless the Project Owner and its affiliates, agents, licensees, and sublicensees. + +5. Acceptance: + By submitting your contribution to the Project, you agree to abide by these terms and conditions. + diff --git a/CONTRIBUTING b/CONTRIBUTING index 6929a680..434fcc7f 100644 --- a/CONTRIBUTING +++ b/CONTRIBUTING @@ -1,29 +1,29 @@ -# Contributing to Seelen UI - -Thank you for your interest in contributing to this project! We welcome contributions from everyone. By participating in this project, you agree to abide by the following guidelines and terms. - -## How to Contribute - -1. Fork the repository and clone it to your local machine. -2. Read the [Project Documentation](documentation/project.md) to understand the project structure and how to use it. -3. Create a new branch for your contribution: `git checkout -b feature/new-feature`. -4. Make your changes and ensure they are well-tested. -5. Commit your changes: `git commit -m 'Add new feature'`. -6. Push to the branch: `git push origin feature/new-feature`. -7. Submit a pull request. - -## Contributor License Agreement (CLA) - -By submitting code as an individual, you agree to the [Contributor License Agreement](CLA.md). - -## Code of Conduct - -This project adheres to the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT). By participating, you are expected to uphold this code. Please report any unacceptable behavior to [Maintainer's Email]. - -## Licensing - -All contributions to this project are subject to the terms of the [PolyForm Strict License 1.0.0](LICENSE). By contributing, you agree that your contributions will be licensed under the terms of this license. - -## Contact - -If you have any questions or need further clarification, please feel free to contact the project maintainer at [Maintainer's Email]. +# Contributing to Seelen UI + +Thank you for your interest in contributing to this project! We welcome contributions from everyone. By participating in this project, you agree to abide by the following guidelines and terms. + +## How to Contribute + +1. Fork the repository and clone it to your local machine. +2. Read the [Project Documentation](documentation/project.md) to understand the project structure and how to use it. +3. Create a new branch for your contribution: `git checkout -b feature/new-feature`. +4. Make your changes and ensure they are well-tested. +5. Commit your changes: `git commit -m 'Add new feature'`. +6. Push to the branch: `git push origin feature/new-feature`. +7. Submit a pull request. + +## Contributor License Agreement (CLA) + +By submitting code as an individual, you agree to the [Contributor License Agreement](CLA.md). + +## Code of Conduct + +This project adheres to the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT). By participating, you are expected to uphold this code. Please report any unacceptable behavior to [Maintainer's Email]. + +## Licensing + +All contributions to this project are subject to the terms of the [PolyForm Strict License 1.0.0](LICENSE). By contributing, you agree that your contributions will be licensed under the terms of this license. + +## Contact + +If you have any questions or need further clarification, please feel free to contact the project maintainer at [Maintainer's Email]. diff --git a/Cargo.lock b/Cargo.lock index a8a6a412..2c3a5944 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6832 +1,6832 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom 0.2.15", - "once_cell", - "version_check", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "aligned-vec" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" - -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_log-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ecc8056bf6ab9892dcd53216c83d1597487d7dacac16c8df6b877d127df9937" - -[[package]] -name = "android_logger" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b07e8e73d720a1f2e4b6014766e6039fd2e96a4fa44e2a78d0e1fa2ff49826" -dependencies = [ - "android_log-sys", - "env_filter", - "log", -] - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" - -[[package]] -name = "anstyle-parse" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -] - -[[package]] -name = "anyhow" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" - -[[package]] -name = "arbitrary" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" -dependencies = [ - "derive_arbitrary", -] - -[[package]] -name = "arc-swap" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" - -[[package]] -name = "arg_enum_proc_macro" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "ashpd" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd884d7c72877a94102c3715f3b1cd09ff4fac28221add3e57cfbe25c236d093" -dependencies = [ - "enumflags2", - "futures-channel", - "futures-util", - "rand 0.8.5", - "serde", - "serde_repr", - "tokio", - "url", - "zbus", -] - -[[package]] -name = "async-broadcast" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" -dependencies = [ - "event-listener", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-channel" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-io" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" -dependencies = [ - "async-lock", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix", - "slab", - "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "async-lock" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-process" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7eda79bbd84e29c2b308d1dc099d7de8dcc7035e48f4bf5dc4a531a44ff5e2a" -dependencies = [ - "async-channel", - "async-io", - "async-lock", - "async-signal", - "async-task", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "rustix", - "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "async-recursion" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "async-signal" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794f185324c2f00e771cd9f1ae8b5ac68be2ca7abb129a87afd6e86d228bc54d" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if", - "futures-core", - "futures-io", - "rustix", - "signal-hook-registry", - "slab", - "windows-sys 0.52.0", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "async-trait" -version = "0.1.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "atk" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4af014b17dd80e8af9fa689b2d4a211ddba6eb583c1622f35d0cb543f6b17e4" -dependencies = [ - "atk-sys", - "glib", - "libc", -] - -[[package]] -name = "atk-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "251e0b7d90e33e0ba930891a505a9a35ece37b2dd37a14f3ffc306c13b980009" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "auto-launch" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f012b8cc0c850f34117ec8252a44418f2e34a2cf501de89e29b241ae5f79471" -dependencies = [ - "dirs 4.0.0", - "thiserror", - "winreg 0.10.1", -] - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "av1-grain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" -dependencies = [ - "anyhow", - "arrayvec", - "log", - "nom", - "num-rational", - "v_frame", -] - -[[package]] -name = "avif-serialize" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" -dependencies = [ - "arrayvec", -] - -[[package]] -name = "backtrace" -version = "0.3.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "battery" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b624268937c0e0a3edb7c27843f9e547c320d730c610d3b8e6e8e95b2026e4" -dependencies = [ - "cfg-if", - "core-foundation 0.7.0", - "lazycell", - "libc", - "mach", - "nix 0.19.1", - "num-traits", - "uom", - "winapi", -] - -[[package]] -name = "bit_field" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -dependencies = [ - "serde", -] - -[[package]] -name = "bitstream-io" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415f8399438eb5e4b2f73ed3152a3448b98149dda642a957ee704e1daa5cf1d8" - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block2" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" -dependencies = [ - "objc2", -] - -[[package]] -name = "blocking" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" -dependencies = [ - "async-channel", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - -[[package]] -name = "borsh" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d4d6dafc1a3bb54687538972158f07b2c948bc57d5890df22c0739098b3028" -dependencies = [ - "borsh-derive", - "cfg_aliases 0.1.1", -] - -[[package]] -name = "borsh-derive" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4918709cc4dd777ad2b6303ed03cb37f3ca0ccede8c1b0d28ac6db8f4710e0" -dependencies = [ - "once_cell", - "proc-macro-crate 2.0.2", - "proc-macro2", - "quote", - "syn 2.0.68", - "syn_derive", -] - -[[package]] -name = "brotli" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "2.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - -[[package]] -name = "built" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6a6c0b39c38fd754ac338b00a88066436389c0f029da5d37d1e01091d9b7c17" - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "byte-unit" -version = "5.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ac19bdf0b2665407c39d82dbc937e951e7e2001609f0fb32edd0af45a2d63e" -dependencies = [ - "rust_decimal", - "serde", - "utf8-width", -] - -[[package]] -name = "bytecheck" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" -dependencies = [ - "bytecheck_derive", - "ptr_meta", - "simdutf8", -] - -[[package]] -name = "bytecheck_derive" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "bytemuck" -version = "1.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "byteorder-lite" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" - -[[package]] -name = "bytes" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" -dependencies = [ - "serde", -] - -[[package]] -name = "cairo-rs" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" -dependencies = [ - "bitflags 2.6.0", - "cairo-sys-rs", - "glib", - "libc", - "once_cell", - "thiserror", -] - -[[package]] -name = "cairo-sys-rs" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" -dependencies = [ - "glib-sys", - "libc", - "system-deps", -] - -[[package]] -name = "camino" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo-platform" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo_metadata" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cargo_toml" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a969e13a7589e9e3e4207e153bae624ade2b5622fb4684a4923b23ec3d57719" -dependencies = [ - "serde", - "toml 0.8.2", -] - -[[package]] -name = "cc" -version = "1.0.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac367972e516d45567c7eafc73d24e1c193dcf200a8d94e9db7b3d38b349572d" -dependencies = [ - "jobserver", - "libc", - "once_cell", -] - -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - -[[package]] -name = "cfb" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" -dependencies = [ - "byteorder", - "fnv", - "uuid", -] - -[[package]] -name = "cfg-expr" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" -dependencies = [ - "smallvec", - "target-lexicon", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "serde", - "windows-targets 0.52.6", -] - -[[package]] -name = "clap" -version = "4.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "clap_lex" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" - -[[package]] -name = "cocoa" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" -dependencies = [ - "bitflags 1.3.2", - "block", - "cocoa-foundation", - "core-foundation 0.9.4", - "core-graphics", - "foreign-types", - "libc", - "objc", -] - -[[package]] -name = "cocoa-foundation" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" -dependencies = [ - "bitflags 1.3.2", - "block", - "core-foundation 0.9.4", - "core-graphics-types", - "libc", - "objc", -] - -[[package]] -name = "color-eyre" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" -dependencies = [ - "backtrace", - "color-spantrace", - "eyre", - "indenter", - "once_cell", - "owo-colors", - "tracing-error", -] - -[[package]] -name = "color-spantrace" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" -dependencies = [ - "once_cell", - "owo-colors", - "tracing-core", - "tracing-error", -] - -[[package]] -name = "color_quant" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" - -[[package]] -name = "colorchoice" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" - -[[package]] -name = "combine" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "const-random" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" -dependencies = [ - "const-random-macro", -] - -[[package]] -name = "const-random-macro" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" -dependencies = [ - "getrandom 0.2.15", - "once_cell", - "tiny-keccak", -] - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "cookie" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - -[[package]] -name = "cookie_store" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4934e6b7e8419148b6ef56950d277af8561060b56afd59e2aadf98b59fce6baa" -dependencies = [ - "cookie", - "idna 0.5.0", - "log", - "publicsuffix", - "serde", - "serde_derive", - "serde_json", - "time", - "url", -] - -[[package]] -name = "core-foundation" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" -dependencies = [ - "core-foundation-sys 0.7.0", - "libc", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys 0.8.6", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" - -[[package]] -name = "core-foundation-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" - -[[package]] -name = "core-graphics" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "core-graphics-types", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "libc", -] - -[[package]] -name = "cpufeatures" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "cssparser" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" -dependencies = [ - "cssparser-macros", - "dtoa-short", - "itoa 0.4.8", - "matches", - "phf 0.8.0", - "proc-macro2", - "quote", - "smallvec", - "syn 1.0.109", -] - -[[package]] -name = "cssparser-macros" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" -dependencies = [ - "quote", - "syn 2.0.68", -] - -[[package]] -name = "ctor" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" -dependencies = [ - "quote", - "syn 2.0.68", -] - -[[package]] -name = "darling" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.68", -] - -[[package]] -name = "darling_macro" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "data-url" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" - -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", - "serde", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_arbitrary" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "derive_more" -version = "0.99.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.68", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys 0.3.7", -] - -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys 0.4.1", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - -[[package]] -name = "dispatch" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "dlopen2" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1297103d2bbaea85724fcee6294c2d50b1081f9ad47d0f6f6f61eda65315a6" -dependencies = [ - "dlopen2_derive", - "libc", - "once_cell", - "winapi", -] - -[[package]] -name = "dlopen2_derive" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "dlv-list" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" -dependencies = [ - "const-random", -] - -[[package]] -name = "dpi" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" -dependencies = [ - "serde", -] - -[[package]] -name = "dtoa" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" - -[[package]] -name = "dtoa-short" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" -dependencies = [ - "dtoa", -] - -[[package]] -name = "dunce" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" - -[[package]] -name = "dyn-clone" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "embed-resource" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6985554d0688b687c5cb73898a34fbe3ad6c24c58c238a4d91d5e840670ee9d" -dependencies = [ - "cc", - "memchr", - "rustc_version", - "toml 0.8.2", - "vswhom", - "winreg 0.52.0", -] - -[[package]] -name = "embed_plist" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" - -[[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "endi" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" - -[[package]] -name = "enumflags2" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" -dependencies = [ - "enumflags2_derive", - "serde", -] - -[[package]] -name = "enumflags2_derive" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "env_filter" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "erased-serde" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" -dependencies = [ - "serde", - "typeid", -] - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "event-listener" -version = "5.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" -dependencies = [ - "event-listener", - "pin-project-lite", -] - -[[package]] -name = "exr" -version = "1.72.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" -dependencies = [ - "bit_field", - "flume", - "half", - "lebe", - "miniz_oxide", - "rayon-core", - "smallvec", - "zune-inflate", -] - -[[package]] -name = "eyre" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" -dependencies = [ - "indenter", - "once_cell", -] - -[[package]] -name = "fastrand" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" - -[[package]] -name = "fdeflate" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" -dependencies = [ - "simd-adler32", -] - -[[package]] -name = "fern" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee" -dependencies = [ - "log", -] - -[[package]] -name = "field-offset" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" -dependencies = [ - "memoffset", - "rustc_version", -] - -[[package]] -name = "filetime" -version = "0.2.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.4.1", - "windows-sys 0.52.0", -] - -[[package]] -name = "flate2" -version = "1.0.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "flume" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" -dependencies = [ - "spin", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" -dependencies = [ - "foreign-types-macros", - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "foreign-types-shared" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fsevent-sys" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" -dependencies = [ - "libc", -] - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" -dependencies = [ - "mac", - "new_debug_unreachable", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-lite" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - -[[package]] -name = "gdk" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5ba081bdef3b75ebcdbfc953699ed2d7417d6bd853347a42a37d76406a33646" -dependencies = [ - "cairo-rs", - "gdk-pixbuf", - "gdk-sys", - "gio", - "glib", - "libc", - "pango", -] - -[[package]] -name = "gdk-pixbuf" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" -dependencies = [ - "gdk-pixbuf-sys", - "gio", - "glib", - "libc", - "once_cell", -] - -[[package]] -name = "gdk-pixbuf-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" -dependencies = [ - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "gdk-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31ff856cb3386dae1703a920f803abafcc580e9b5f711ca62ed1620c25b51ff2" -dependencies = [ - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "pango-sys", - "pkg-config", - "system-deps", -] - -[[package]] -name = "gdkwayland-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a90fbf5c033c65d93792192a49a8efb5bb1e640c419682a58bb96f5ae77f3d4a" -dependencies = [ - "gdk-sys", - "glib-sys", - "gobject-sys", - "libc", - "pkg-config", - "system-deps", -] - -[[package]] -name = "gdkx11" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2ea8a4909d530f79921290389cbd7c34cb9d623bfe970eaae65ca5f9cd9cce" -dependencies = [ - "gdk", - "gdkx11-sys", - "gio", - "glib", - "libc", - "x11", -] - -[[package]] -name = "gdkx11-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee8f00f4ee46cad2939b8990f5c70c94ff882c3028f3cc5abf950fa4ab53043" -dependencies = [ - "gdk-sys", - "glib-sys", - "libc", - "system-deps", - "x11", -] - -[[package]] -name = "generator" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" -dependencies = [ - "cc", - "libc", - "log", - "rustversion", - "windows 0.48.0", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getset" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "gif" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" -dependencies = [ - "color_quant", - "weezl", -] - -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - -[[package]] -name = "gio" -version = "0.18.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-util", - "gio-sys", - "glib", - "libc", - "once_cell", - "pin-project-lite", - "smallvec", - "thiserror", -] - -[[package]] -name = "gio-sys" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", - "winapi", -] - -[[package]] -name = "glib" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" -dependencies = [ - "bitflags 2.6.0", - "futures-channel", - "futures-core", - "futures-executor", - "futures-task", - "futures-util", - "gio-sys", - "glib-macros", - "glib-sys", - "gobject-sys", - "libc", - "memchr", - "once_cell", - "smallvec", - "thiserror", -] - -[[package]] -name = "glib-macros" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" -dependencies = [ - "heck 0.4.1", - "proc-macro-crate 2.0.2", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "glib-sys" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" -dependencies = [ - "libc", - "system-deps", -] - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "gobject-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" -dependencies = [ - "glib-sys", - "libc", - "system-deps", -] - -[[package]] -name = "gtk" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93c4f5e0e20b60e10631a5f06da7fe3dda744b05ad0ea71fee2f47adf865890c" -dependencies = [ - "atk", - "cairo-rs", - "field-offset", - "futures-channel", - "gdk", - "gdk-pixbuf", - "gio", - "glib", - "gtk-sys", - "gtk3-macros", - "libc", - "pango", - "pkg-config", -] - -[[package]] -name = "gtk-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771437bf1de2c1c0b496c11505bdf748e26066bbe942dfc8f614c9460f6d7722" -dependencies = [ - "atk-sys", - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gdk-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "pango-sys", - "system-deps", -] - -[[package]] -name = "gtk3-macros" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6063efb63db582968fb7df72e1ae68aa6360dcfb0a75143f34fc7d616bad75e" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "h2" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http", - "indexmap 2.2.6", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "half" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" -dependencies = [ - "cfg-if", - "crunchy", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "html5ever" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" -dependencies = [ - "log", - "mac", - "markup5ever", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "http" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" -dependencies = [ - "bytes", - "fnv", - "itoa 1.0.11", -] - -[[package]] -name = "http-body" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" -dependencies = [ - "bytes", - "futures-util", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "http-range" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" - -[[package]] -name = "httparse" -version = "1.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" - -[[package]] -name = "hyper" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "itoa 1.0.11", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" -dependencies = [ - "futures-util", - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", - "webpki-roots", -] - -[[package]] -name = "hyper-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "hyper", - "pin-project-lite", - "socket2", - "tokio", - "tower", - "tower-service", - "tracing", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" -dependencies = [ - "android_system_properties", - "core-foundation-sys 0.8.6", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core 0.52.0", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "ico" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3804960be0bb5e4edb1e1ad67afd321a9ecfd875c3e65c099468fd2717d7cae" -dependencies = [ - "byteorder", - "png", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "image" -version = "0.24.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "num-traits", - "png", -] - -[[package]] -name = "image" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "exr", - "gif", - "image-webp", - "num-traits", - "png", - "qoi", - "ravif", - "rayon", - "rgb", - "tiff", - "zune-core", - "zune-jpeg", -] - -[[package]] -name = "image-webp" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d730b085583c4d789dfd07fdcf185be59501666a90c97c40162b37e4fdad272d" -dependencies = [ - "byteorder-lite", - "thiserror", -] - -[[package]] -name = "imgref" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" - -[[package]] -name = "indenter" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" -dependencies = [ - "equivalent", - "hashbrown 0.14.5", - "serde", -] - -[[package]] -name = "infer" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb33622da908807a06f9513c19b3c1ad50fab3e4137d82a78107d502075aa199" -dependencies = [ - "cfb", -] - -[[package]] -name = "inotify" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" -dependencies = [ - "bitflags 1.3.2", - "inotify-sys", - "libc", -] - -[[package]] -name = "inotify-sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" -dependencies = [ - "libc", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "interpolate_name" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "ipnet" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" - -[[package]] -name = "is-docker" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" -dependencies = [ - "once_cell", -] - -[[package]] -name = "is-wsl" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" -dependencies = [ - "is-docker", - "once_cell", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "javascriptcore-rs" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc" -dependencies = [ - "bitflags 1.3.2", - "glib", - "javascriptcore-rs-sys", -] - -[[package]] -name = "javascriptcore-rs-sys" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine", - "jni-sys", - "log", - "thiserror", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] -name = "jni-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" - -[[package]] -name = "jobserver" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" -dependencies = [ - "libc", -] - -[[package]] -name = "jpeg-decoder" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" - -[[package]] -name = "js-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "json-patch" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec9ad60d674508f3ca8f380a928cfe7b096bc729c4e2dbfe3852bc45da3ab30b" -dependencies = [ - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "keyboard-types" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" -dependencies = [ - "bitflags 2.6.0", - "serde", - "unicode-segmentation", -] - -[[package]] -name = "kqueue" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" -dependencies = [ - "kqueue-sys", - "libc", -] - -[[package]] -name = "kqueue-sys" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" -dependencies = [ - "bitflags 1.3.2", - "libc", -] - -[[package]] -name = "kuchikiki" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8" -dependencies = [ - "cssparser", - "html5ever", - "indexmap 1.9.3", - "matches", - "selectors", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "lebe" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" - -[[package]] -name = "libappindicator" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a" -dependencies = [ - "glib", - "gtk", - "gtk-sys", - "libappindicator-sys", - "log", -] - -[[package]] -name = "libappindicator-sys" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" -dependencies = [ - "gtk-sys", - "libloading", - "once_cell", -] - -[[package]] -name = "libc" -version = "0.2.155" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" - -[[package]] -name = "libfuzzer-sys" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" -dependencies = [ - "arbitrary", - "cc", - "once_cell", -] - -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags 2.6.0", - "libc", -] - -[[package]] -name = "line-wrap" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e" - -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" -dependencies = [ - "value-bag", -] - -[[package]] -name = "loom" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "serde", - "serde_json", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "loop9" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" -dependencies = [ - "imgref", -] - -[[package]] -name = "mac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" - -[[package]] -name = "mach" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" -dependencies = [ - "libc", -] - -[[package]] -name = "macro_rules_attribute" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a82271f7bc033d84bbca59a3ce3e4159938cb08a9c3aebbe54d215131518a13" -dependencies = [ - "macro_rules_attribute-proc_macro", - "paste", -] - -[[package]] -name = "macro_rules_attribute-proc_macro" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8dd856d451cc0da70e2ef2ce95a18e39a93b7558bedf10201ad28503f918568" - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - -[[package]] -name = "markup5ever" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" -dependencies = [ - "log", - "phf 0.10.1", - "phf_codegen 0.10.0", - "string_cache", - "string_cache_codegen", - "tendril", -] - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - -[[package]] -name = "maybe-rayon" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" -dependencies = [ - "cfg-if", - "rayon", -] - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "minisign-verify" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "933dca44d65cdd53b355d0b73d380a2ff5da71f87f036053188bf1eab6a19881" - -[[package]] -name = "miniz_oxide" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" -dependencies = [ - "adler", - "simd-adler32", -] - -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "log", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", -] - -[[package]] -name = "muda" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b959f97c97044e4c96e32e1db292a7d594449546a3c6b77ae613dc3a5b5145" -dependencies = [ - "cocoa", - "crossbeam-channel", - "dpi", - "gtk", - "keyboard-types", - "objc", - "once_cell", - "png", - "serde", - "thiserror", - "windows-sys 0.52.0", -] - -[[package]] -name = "ndk" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" -dependencies = [ - "bitflags 1.3.2", - "jni-sys", - "ndk-sys", - "num_enum", - "raw-window-handle 0.5.2", - "thiserror", -] - -[[package]] -name = "ndk-context" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" - -[[package]] -name = "ndk-sys" -version = "0.4.1+23.1.7779620" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" -dependencies = [ - "jni-sys", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - -[[package]] -name = "nix" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2" -dependencies = [ - "bitflags 1.3.2", - "cc", - "cfg-if", - "libc", -] - -[[package]] -name = "nix" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" -dependencies = [ - "bitflags 2.6.0", - "cfg-if", - "libc", - "memoffset", -] - -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "noop_proc_macro" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" - -[[package]] -name = "notify" -version = "6.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" -dependencies = [ - "bitflags 2.6.0", - "crossbeam-channel", - "filetime", - "fsevent-sys", - "inotify", - "kqueue", - "libc", - "log", - "mio", - "walkdir", - "windows-sys 0.48.0", -] - -[[package]] -name = "ntapi" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" -dependencies = [ - "winapi", -] - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.9", - "libc", -] - -[[package]] -name = "num_enum" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", - "objc_exception", -] - -[[package]] -name = "objc-foundation" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" -dependencies = [ - "block", - "objc", - "objc_id", -] - -[[package]] -name = "objc-sys" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" - -[[package]] -name = "objc2" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" -dependencies = [ - "objc-sys", - "objc2-encode", -] - -[[package]] -name = "objc2-app-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" -dependencies = [ - "bitflags 2.6.0", - "block2", - "libc", - "objc2", - "objc2-core-data", - "objc2-core-image", - "objc2-foundation", - "objc2-quartz-core", -] - -[[package]] -name = "objc2-core-data" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" -dependencies = [ - "bitflags 2.6.0", - "block2", - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-core-image" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" -dependencies = [ - "block2", - "objc2", - "objc2-foundation", - "objc2-metal", -] - -[[package]] -name = "objc2-encode" -version = "4.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" - -[[package]] -name = "objc2-foundation" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" -dependencies = [ - "bitflags 2.6.0", - "block2", - "dispatch", - "libc", - "objc2", -] - -[[package]] -name = "objc2-metal" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" -dependencies = [ - "bitflags 2.6.0", - "block2", - "objc2", - "objc2-foundation", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" -dependencies = [ - "bitflags 2.6.0", - "block2", - "objc2", - "objc2-foundation", - "objc2-metal", -] - -[[package]] -name = "objc_exception" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" -dependencies = [ - "cc", -] - -[[package]] -name = "objc_id" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" -dependencies = [ - "objc", -] - -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - -[[package]] -name = "open" -version = "5.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5ca541f22b1c46d4bb9801014f234758ab4297e7870b904b6a8415b980a7388" -dependencies = [ - "is-wsl", - "libc", - "pathdiff", -] - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "ordered-multimap" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" -dependencies = [ - "dlv-list", - "hashbrown 0.14.5", -] - -[[package]] -name = "ordered-stream" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" -dependencies = [ - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "os_info" -version = "3.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092" -dependencies = [ - "log", - "serde", - "windows-sys 0.52.0", -] - -[[package]] -name = "os_pipe" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29d73ba8daf8fac13b0501d1abeddcfe21ba7401ada61a819144b6c2a4f32209" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "owo-colors" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" - -[[package]] -name = "pango" -version = "0.18.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" -dependencies = [ - "gio", - "glib", - "libc", - "once_cell", - "pango-sys", -] - -[[package]] -name = "pango-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "parking" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.5.2", - "smallvec", - "windows-targets 0.52.6", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "phf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" -dependencies = [ - "phf_macros 0.8.0", - "phf_shared 0.8.0", - "proc-macro-hack", -] - -[[package]] -name = "phf" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" -dependencies = [ - "phf_shared 0.10.0", -] - -[[package]] -name = "phf" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" -dependencies = [ - "phf_macros 0.11.2", - "phf_shared 0.11.2", -] - -[[package]] -name = "phf_codegen" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" -dependencies = [ - "phf_generator 0.8.0", - "phf_shared 0.8.0", -] - -[[package]] -name = "phf_codegen" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", -] - -[[package]] -name = "phf_generator" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" -dependencies = [ - "phf_shared 0.8.0", - "rand 0.7.3", -] - -[[package]] -name = "phf_generator" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" -dependencies = [ - "phf_shared 0.10.0", - "rand 0.8.5", -] - -[[package]] -name = "phf_generator" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" -dependencies = [ - "phf_shared 0.11.2", - "rand 0.8.5", -] - -[[package]] -name = "phf_macros" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" -dependencies = [ - "phf_generator 0.8.0", - "phf_shared 0.8.0", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator 0.11.2", - "phf_shared 0.11.2", - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "phf_shared" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" -dependencies = [ - "siphasher", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - -[[package]] -name = "phf_shared" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "piper" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - -[[package]] -name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - -[[package]] -name = "plist" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9" -dependencies = [ - "base64 0.21.7", - "indexmap 2.2.6", - "line-wrap", - "quick-xml", - "serde", - "time", -] - -[[package]] -name = "png" -version = "0.17.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - -[[package]] -name = "polling" -version = "3.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" -dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi 0.4.0", - "pin-project-lite", - "rustix", - "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" -dependencies = [ - "toml_datetime", - "toml_edit 0.20.2", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "profiling" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" -dependencies = [ - "profiling-procmacros", -] - -[[package]] -name = "profiling-procmacros" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" -dependencies = [ - "quote", - "syn 2.0.68", -] - -[[package]] -name = "psl-types" -version = "2.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" - -[[package]] -name = "ptr_meta" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "publicsuffix" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" -dependencies = [ - "idna 0.3.0", - "psl-types", -] - -[[package]] -name = "qoi" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "quick-error" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" - -[[package]] -name = "quick-xml" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" -dependencies = [ - "memchr", -] - -[[package]] -name = "quinn" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ceeeeabace7857413798eb1ffa1e9c905a9946a57d81fb69b4b71c4d8eb3ad" -dependencies = [ - "bytes", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "quinn-proto" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddf517c03a109db8100448a4be38d498df8a210a99fe0e1b9eaf39e78c640efe" -dependencies = [ - "bytes", - "rand 0.8.5", - "ring", - "rustc-hash", - "rustls", - "slab", - "thiserror", - "tinyvec", - "tracing", -] - -[[package]] -name = "quinn-udp" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9096629c45860fc7fb143e125eb826b5e721e10be3263160c7d60ca832cf8c46" -dependencies = [ - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", - "rand_pcg", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.15", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rav1e" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" -dependencies = [ - "arbitrary", - "arg_enum_proc_macro", - "arrayvec", - "av1-grain", - "bitstream-io", - "built", - "cfg-if", - "interpolate_name", - "itertools", - "libc", - "libfuzzer-sys", - "log", - "maybe-rayon", - "new_debug_unreachable", - "noop_proc_macro", - "num-derive", - "num-traits", - "once_cell", - "paste", - "profiling", - "rand 0.8.5", - "rand_chacha 0.3.1", - "simd_helpers", - "system-deps", - "thiserror", - "v_frame", - "wasm-bindgen", -] - -[[package]] -name = "ravif" -version = "0.11.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67376f469e7e7840d0040bbf4b9b3334005bb167f814621326e4c7ab8cd6e944" -dependencies = [ - "avif-serialize", - "imgref", - "loop9", - "quick-error", - "rav1e", - "rayon", - "rgb", -] - -[[package]] -name = "raw-window-handle" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" - -[[package]] -name = "raw-window-handle" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" - -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" -dependencies = [ - "bitflags 2.6.0", -] - -[[package]] -name = "redox_users" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" -dependencies = [ - "getrandom 0.2.15", - "libredox", - "thiserror", -] - -[[package]] -name = "regex" -version = "1.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.4", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" - -[[package]] -name = "rend" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" -dependencies = [ - "bytecheck", -] - -[[package]] -name = "reqwest" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" -dependencies = [ - "base64 0.22.1", - "bytes", - "cookie", - "cookie_store", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-pemfile", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tokio-rustls", - "tokio-util", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "webpki-roots", - "winreg 0.52.0", -] - -[[package]] -name = "rfd" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a73a7337fc24366edfca76ec521f51877b114e42dab584008209cca6719251" -dependencies = [ - "ashpd", - "block", - "dispatch", - "glib-sys", - "gobject-sys", - "gtk-sys", - "js-sys", - "log", - "objc", - "objc-foundation", - "objc_id", - "raw-window-handle 0.6.2", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows-sys 0.48.0", -] - -[[package]] -name = "rgb" -version = "0.8.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.15", - "libc", - "spin", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rkyv" -version = "0.7.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" -dependencies = [ - "bitvec", - "bytecheck", - "bytes", - "hashbrown 0.12.3", - "ptr_meta", - "rend", - "rkyv_derive", - "seahash", - "tinyvec", - "uuid", -] - -[[package]] -name = "rkyv_derive" -version = "0.7.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "rust-ini" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e310ef0e1b6eeb79169a1171daf9abcb87a2e17c03bee2c4bb100b55c75409f" -dependencies = [ - "cfg-if", - "ordered-multimap", - "trim-in-place", -] - -[[package]] -name = "rust_decimal" -version = "1.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" -dependencies = [ - "arrayvec", - "borsh", - "bytes", - "num-traits", - "rand 0.8.5", - "rkyv", - "serde", - "serde_json", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags 2.6.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustls" -version = "0.23.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402" -dependencies = [ - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pemfile" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" -dependencies = [ - "base64 0.22.1", - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" - -[[package]] -name = "rustls-webpki" -version = "0.102.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schemars" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" -dependencies = [ - "dyn-clone", - "indexmap 1.9.3", - "schemars_derive", - "serde", - "serde_json", - "url", -] - -[[package]] -name = "schemars_derive" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 2.0.68", -] - -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "seahash" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" - -[[package]] -name = "seelen-ui" -version = "1.9.4" -dependencies = [ - "arc-swap", - "base64 0.22.1", - "battery", - "clap", - "color-eyre", - "crossbeam-channel", - "getset", - "image 0.25.1", - "itertools", - "lazy_static", - "log", - "notify", - "os_info", - "parking_lot", - "phf 0.11.2", - "regex", - "serde", - "serde_json", - "serde_yaml", - "sysinfo", - "tauri", - "tauri-build", - "tauri-plugin-autostart", - "tauri-plugin-deep-link", - "tauri-plugin-dialog", - "tauri-plugin-fs", - "tauri-plugin-http", - "tauri-plugin-log", - "tauri-plugin-process", - "tauri-plugin-shell", - "tauri-plugin-updater", - "uuid", - "widestring", - "win-screenshot", - "windows 0.57.0", - "windows-core 0.57.0", - "winreg 0.52.0", - "winvd", -] - -[[package]] -name = "selectors" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" -dependencies = [ - "bitflags 1.3.2", - "cssparser", - "derive_more", - "fxhash", - "log", - "matches", - "phf 0.8.0", - "phf_codegen 0.8.0", - "precomputed-hash", - "servo_arc", - "smallvec", - "thin-slice", -] - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" -dependencies = [ - "serde", -] - -[[package]] -name = "serde" -version = "1.0.203" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-untagged" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2676ba99bd82f75cae5cbd2c8eda6fa0b8760f18978ea840e980dd5567b5c5b6" -dependencies = [ - "erased-serde", - "serde", - "typeid", -] - -[[package]] -name = "serde_derive" -version = "1.0.203" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "serde_derive_internals" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "serde_json" -version = "1.0.118" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4" -dependencies = [ - "itoa 1.0.11", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "serde_spanned" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa 1.0.11", - "ryu", - "serde", -] - -[[package]] -name = "serde_with" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" -dependencies = [ - "base64 0.22.1", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.2.6", - "serde", - "serde_derive", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "serde_yaml" -version = "0.9.34+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" -dependencies = [ - "indexmap 2.2.6", - "itoa 1.0.11", - "ryu", - "serde", - "unsafe-libyaml", -] - -[[package]] -name = "serialize-to-javascript" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9823f2d3b6a81d98228151fdeaf848206a7855a7a042bbf9bf870449a66cafb" -dependencies = [ - "serde", - "serde_json", - "serialize-to-javascript-impl", -] - -[[package]] -name = "serialize-to-javascript-impl" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "servo_arc" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" -dependencies = [ - "nodrop", - "stable_deref_trait", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shared_child" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - -[[package]] -name = "simd_helpers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" -dependencies = [ - "quote", -] - -[[package]] -name = "simdutf8" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" - -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "softbuffer" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d623bff5d06f60d738990980d782c8c866997d9194cfe79ecad00aa2f76826dd" -dependencies = [ - "bytemuck", - "cfg_aliases 0.2.1", - "core-graphics", - "foreign-types", - "js-sys", - "log", - "objc2", - "objc2-app-kit", - "objc2-foundation", - "objc2-quartz-core", - "raw-window-handle 0.6.2", - "redox_syscall 0.5.2", - "wasm-bindgen", - "web-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "soup3" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f" -dependencies = [ - "futures-channel", - "gio", - "glib", - "libc", - "soup3-sys", -] - -[[package]] -name = "soup3-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27" -dependencies = [ - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "state" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8" -dependencies = [ - "loom", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "string_cache" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" -dependencies = [ - "new_debug_unreachable", - "once_cell", - "parking_lot", - "phf_shared 0.10.0", - "precomputed-hash", - "serde", -] - -[[package]] -name = "string_cache_codegen" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", - "proc-macro2", - "quote", -] - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "swift-rs" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bbdb58577b6301f8d17ae2561f32002a5bae056d444e0f69e611e504a276204" -dependencies = [ - "base64 0.21.7", - "serde", - "serde_json", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "sync_wrapper" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" - -[[package]] -name = "sysinfo" -version = "0.30.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732ffa00f53e6b2af46208fba5718d9662a421049204e156328b66791ffa15ae" -dependencies = [ - "cfg-if", - "core-foundation-sys 0.8.6", - "libc", - "ntapi", - "once_cell", - "rayon", - "windows 0.52.0", -] - -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys 0.8.6", - "libc", -] - -[[package]] -name = "system-deps" -version = "6.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" -dependencies = [ - "cfg-expr", - "heck 0.5.0", - "pkg-config", - "toml 0.8.2", - "version-compare", -] - -[[package]] -name = "tao" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea538df05fbc2dcbbd740ba0cfe8607688535f4798d213cbbfa13ce494f3451f" -dependencies = [ - "bitflags 2.6.0", - "cocoa", - "core-foundation 0.9.4", - "core-graphics", - "crossbeam-channel", - "dispatch", - "dlopen2", - "dpi", - "gdkwayland-sys", - "gdkx11-sys", - "gtk", - "instant", - "jni", - "lazy_static", - "libc", - "log", - "ndk", - "ndk-context", - "ndk-sys", - "objc", - "once_cell", - "parking_lot", - "raw-window-handle 0.6.2", - "scopeguard", - "tao-macros", - "unicode-segmentation", - "url", - "windows 0.57.0", - "windows-core 0.57.0", - "windows-version", - "x11-dl", -] - -[[package]] -name = "tao-macros" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec114582505d158b669b136e6851f85840c109819d77c42bb7c0709f727d18c2" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "tar" -version = "0.4.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" -dependencies = [ - "filetime", - "libc", - "xattr", -] - -[[package]] -name = "target-lexicon" -version = "0.12.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" - -[[package]] -name = "tauri" -version = "2.0.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ee93e545e49458813d4ed16179c67ee6141dba140ec3d4f078dda3b8d4e0d1" -dependencies = [ - "anyhow", - "bytes", - "cocoa", - "dirs 5.0.1", - "dunce", - "embed_plist", - "futures-util", - "getrandom 0.2.15", - "glob", - "gtk", - "heck 0.5.0", - "http", - "http-range", - "image 0.24.9", - "jni", - "libc", - "log", - "mime", - "muda", - "objc", - "percent-encoding", - "raw-window-handle 0.6.2", - "reqwest", - "serde", - "serde_json", - "serde_repr", - "serialize-to-javascript", - "state", - "swift-rs", - "tauri-build", - "tauri-macros", - "tauri-runtime", - "tauri-runtime-wry", - "tauri-utils", - "thiserror", - "tokio", - "tray-icon", - "url", - "urlpattern", - "webkit2gtk", - "webview2-com", - "window-vibrancy", - "windows 0.57.0", -] - -[[package]] -name = "tauri-build" -version = "2.0.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96a58b3a716b51d7f671f729bb8c0a53cd2551eec8450c64e828ef4e6c9f948e" -dependencies = [ - "anyhow", - "cargo_toml", - "dirs 5.0.1", - "glob", - "heck 0.5.0", - "json-patch", - "schemars", - "semver", - "serde", - "serde_json", - "tauri-utils", - "tauri-winres", - "toml 0.8.2", - "walkdir", -] - -[[package]] -name = "tauri-codegen" -version = "2.0.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90a9e63ecd827d57228864764e0234935c9aac230099cf145197c8c08e754ced" -dependencies = [ - "base64 0.22.1", - "brotli", - "ico", - "json-patch", - "plist", - "png", - "proc-macro2", - "quote", - "semver", - "serde", - "serde_json", - "sha2", - "syn 2.0.68", - "tauri-utils", - "thiserror", - "time", - "url", - "uuid", - "walkdir", -] - -[[package]] -name = "tauri-macros" -version = "2.0.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a54f5d5b289aa6215ffcfed7d4ff9960a04b7a854436d04519a9fcf911050cba" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.68", - "tauri-codegen", - "tauri-utils", -] - -[[package]] -name = "tauri-plugin" -version = "2.0.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03ce2ac5e182251ff932750d69c9b240a78e44901a7a6234814d63c595b43660" -dependencies = [ - "anyhow", - "glob", - "plist", - "schemars", - "serde", - "serde_json", - "tauri-utils", - "toml 0.8.2", - "walkdir", -] - -[[package]] -name = "tauri-plugin-autostart" -version = "2.0.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25958a42daab7aaff4faff15cbaffd5505873a0654e6382c74fca1729a791898" -dependencies = [ - "auto-launch", - "log", - "serde", - "serde_json", - "tauri", - "tauri-plugin", - "thiserror", -] - -[[package]] -name = "tauri-plugin-deep-link" -version = "2.0.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db97f4b54f2e6f24681c3fffbcb7e9cfff24003b92bb8d3944a39072b8a1178" -dependencies = [ - "dunce", - "log", - "rust-ini", - "serde", - "serde_json", - "tauri", - "tauri-plugin", - "tauri-utils", - "thiserror", - "url", - "windows-registry", - "windows-result 0.2.0", -] - -[[package]] -name = "tauri-plugin-dialog" -version = "2.0.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c538457a755a75b8bb1594ed40d1512f8f6386251d3fcde492f8f46768ec85b" -dependencies = [ - "dunce", - "log", - "raw-window-handle 0.6.2", - "rfd", - "serde", - "serde_json", - "tauri", - "tauri-plugin", - "tauri-plugin-fs", - "thiserror", -] - -[[package]] -name = "tauri-plugin-fs" -version = "2.0.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5df6b25b1f2b7b61565e66c4dbee9eb39e5635d2a763206e380e07cc3f601a67" -dependencies = [ - "anyhow", - "glob", - "schemars", - "serde", - "serde_json", - "serde_repr", - "tauri", - "tauri-plugin", - "thiserror", - "url", - "uuid", -] - -[[package]] -name = "tauri-plugin-http" -version = "2.0.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eef17218eaa8bd0fc6cafb7831c63d82ef83b3950d59dc817d92d5320c4f20c" -dependencies = [ - "data-url", - "http", - "regex", - "reqwest", - "schemars", - "serde", - "serde_json", - "tauri", - "tauri-plugin", - "tauri-plugin-fs", - "thiserror", - "tokio", - "url", - "urlpattern", -] - -[[package]] -name = "tauri-plugin-log" -version = "2.0.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380d27f23c39cde6a73024e65d8ec9b5b0af861e968dbe16b3aad86cd2c578e5" -dependencies = [ - "android_logger", - "byte-unit", - "cocoa", - "fern", - "log", - "objc", - "serde", - "serde_json", - "serde_repr", - "swift-rs", - "tauri", - "tauri-plugin", - "thiserror", - "time", -] - -[[package]] -name = "tauri-plugin-process" -version = "2.0.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d3663df0cd3e96feb37d46aad5d499d2edfcca5c62548ad34f1684e0019168" -dependencies = [ - "tauri", - "tauri-plugin", -] - -[[package]] -name = "tauri-plugin-shell" -version = "2.0.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9209f6c32caec61e156a5616f7d80ba7683ca4a0a5641cbe5d3086ab371aaab2" -dependencies = [ - "encoding_rs", - "log", - "open", - "os_pipe", - "regex", - "schemars", - "serde", - "serde_json", - "shared_child", - "tauri", - "tauri-plugin", - "thiserror", - "tokio", -] - -[[package]] -name = "tauri-plugin-updater" -version = "2.0.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b5f10ba18d2fc65e16bdf053b7beccb621dcf880c52d2ab08bdeb2d685e3e14" -dependencies = [ - "base64 0.22.1", - "dirs 5.0.1", - "flate2", - "futures-util", - "http", - "infer", - "minisign-verify", - "reqwest", - "semver", - "serde", - "serde_json", - "tar", - "tauri", - "tauri-plugin", - "tempfile", - "thiserror", - "time", - "tokio", - "url", - "windows-sys 0.52.0", - "zip", -] - -[[package]] -name = "tauri-runtime" -version = "2.0.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f01b129b1ebdf09563c354760dbe7c0e96a166b4e33362d9c8d207f527c7ea5" -dependencies = [ - "dpi", - "gtk", - "http", - "jni", - "raw-window-handle 0.6.2", - "serde", - "serde_json", - "tauri-utils", - "thiserror", - "url", - "windows 0.57.0", -] - -[[package]] -name = "tauri-runtime-wry" -version = "2.0.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcda27639094ace2bf25f00bc10e35ea4e3af2f92753b1bdd2a174d1fa5a6292" -dependencies = [ - "cocoa", - "gtk", - "http", - "jni", - "log", - "percent-encoding", - "raw-window-handle 0.6.2", - "softbuffer", - "tao", - "tauri-runtime", - "tauri-utils", - "url", - "webkit2gtk", - "webview2-com", - "windows 0.57.0", - "wry", -] - -[[package]] -name = "tauri-utils" -version = "2.0.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28bb83cffa26e9cb7a2b3d0c31ab87bf277f44aaaa90f17159aef4d37aabd051" -dependencies = [ - "brotli", - "cargo_metadata", - "ctor", - "dunce", - "glob", - "html5ever", - "infer", - "json-patch", - "kuchikiki", - "log", - "memchr", - "phf 0.11.2", - "proc-macro2", - "quote", - "regex", - "schemars", - "semver", - "serde", - "serde-untagged", - "serde_json", - "serde_with", - "swift-rs", - "thiserror", - "toml 0.8.2", - "url", - "urlpattern", - "walkdir", -] - -[[package]] -name = "tauri-winres" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5993dc129e544393574288923d1ec447c857f3f644187f4fbf7d9a875fbfc4fb" -dependencies = [ - "embed-resource", - "toml 0.7.8", -] - -[[package]] -name = "tempfile" -version = "3.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" -dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "tendril" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" -dependencies = [ - "futf", - "mac", - "utf-8", -] - -[[package]] -name = "thin-slice" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" - -[[package]] -name = "thiserror" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "tiff" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" -dependencies = [ - "flate2", - "jpeg-decoder", - "weezl", -] - -[[package]] -name = "time" -version = "0.3.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" -dependencies = [ - "deranged", - "itoa 1.0.11", - "libc", - "num-conv", - "num_threads", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - -[[package]] -name = "time-macros" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tinyvec" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.38.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "tracing", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-macros" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" -dependencies = [ - "rustls", - "rustls-pki-types", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.19.15", -] - -[[package]] -name = "toml" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.20.2", -] - -[[package]] -name = "toml_datetime" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.2.6", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - -[[package]] -name = "toml_edit" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" -dependencies = [ - "indexmap 2.2.6", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-error" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" -dependencies = [ - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "tray-icon" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ad8319cca93189ea9ab1b290de0595960529750b6b8b501a399ed1ec3775d60" -dependencies = [ - "cocoa", - "core-graphics", - "crossbeam-channel", - "dirs 5.0.1", - "libappindicator", - "muda", - "objc", - "once_cell", - "png", - "serde", - "thiserror", - "windows-sys 0.52.0", -] - -[[package]] -name = "trim-in-place" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc" - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typeid" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "059d83cc991e7a42fc37bd50941885db0888e34209f8cfd9aab07ddec03bc9cf" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "uds_windows" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" -dependencies = [ - "memoffset", - "tempfile", - "winapi", -] - -[[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-ucd-ident" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" - -[[package]] -name = "unsafe-libyaml" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "uom" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e76503e636584f1e10b9b3b9498538279561adcef5412927ba00c2b32c4ce5ed" -dependencies = [ - "num-traits", - "typenum", -] - -[[package]] -name = "url" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" -dependencies = [ - "form_urlencoded", - "idna 0.5.0", - "percent-encoding", - "serde", -] - -[[package]] -name = "urlpattern" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9bd5ff03aea02fa45b13a7980151fe45009af1980ba69f651ec367121a31609" -dependencies = [ - "derive_more", - "regex", - "serde", - "unic-ucd-ident", - "url", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "utf8-width" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "uuid" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" -dependencies = [ - "getrandom 0.2.15", -] - -[[package]] -name = "v_frame" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" -dependencies = [ - "aligned-vec", - "num-traits", - "wasm-bindgen", -] - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "value-bag" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" - -[[package]] -name = "version-compare" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "vswhom" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" -dependencies = [ - "libc", - "vswhom-sys", -] - -[[package]] -name = "vswhom-sys" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b17ae1f6c8a2b28506cd96d412eebf83b4a0ff2cbefeeb952f2f9dfa44ba18" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.68", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" - -[[package]] -name = "wasm-streams" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" -dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "web-sys" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webkit2gtk" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a" -dependencies = [ - "bitflags 1.3.2", - "cairo-rs", - "gdk", - "gdk-sys", - "gio", - "gio-sys", - "glib", - "glib-sys", - "gobject-sys", - "gtk", - "gtk-sys", - "javascriptcore-rs", - "libc", - "once_cell", - "soup3", - "webkit2gtk-sys", -] - -[[package]] -name = "webkit2gtk-sys" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c" -dependencies = [ - "bitflags 1.3.2", - "cairo-sys-rs", - "gdk-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "gtk-sys", - "javascriptcore-rs-sys", - "libc", - "pkg-config", - "soup3-sys", - "system-deps", -] - -[[package]] -name = "webpki-roots" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "webview2-com" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6516cfa64c6b3212686080eeec378e662c2af54bb2a5b2a22749673f5cb2226f" -dependencies = [ - "webview2-com-macros", - "webview2-com-sys", - "windows 0.57.0", - "windows-core 0.57.0", - "windows-implement", - "windows-interface", -] - -[[package]] -name = "webview2-com-macros" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1345798ecd8122468840bcdf1b95e5dc6d2206c5e4b0eafa078d061f59c9bc" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "webview2-com-sys" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c76d5b77320ff155660be1df3e6588bc85c75f1a9feef938cc4dc4dd60d1d7cf" -dependencies = [ - "thiserror", - "windows 0.57.0", - "windows-core 0.57.0", -] - -[[package]] -name = "weezl" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" - -[[package]] -name = "widestring" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" - -[[package]] -name = "win-screenshot" -version = "4.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1724fbfec1c2344f8da8d2da6b0f8371f009df3291399df8c7b575a8abd121b" -dependencies = [ - "windows 0.57.0", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "window-vibrancy" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33082acd404763b315866e14a0d5193f3422c81086657583937a750cdd3ec340" -dependencies = [ - "cocoa", - "objc", - "raw-window-handle 0.6.2", - "windows-sys 0.52.0", - "windows-version", -] - -[[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" -dependencies = [ - "windows-core 0.52.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" -dependencies = [ - "windows-core 0.57.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-result 0.1.2", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-implement" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "windows-interface" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.68", -] - -[[package]] -name = "windows-registry" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" -dependencies = [ - "windows-result 0.2.0", - "windows-strings", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-result" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-strings" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result 0.2.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-version" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6998aa457c9ba8ff2fb9f13e9d2a930dabcea28f1d0ab94d687d8b3654844515" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - -[[package]] -name = "winreg" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - -[[package]] -name = "winvd" -version = "0.0.47" -source = "git+https://github.com/eythaann/virtualdesktopaccessor.git#b1e1da1931a2a21982396671a32a280330b1f507" -dependencies = [ - "macro_rules_attribute", - "windows 0.57.0", - "windows-core 0.57.0", - "windows-implement", - "windows-interface", -] - -[[package]] -name = "wry" -version = "0.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b00c945786b02d7805d09a969fa36d0eee4e0bd4fb3ec2a79d2bf45a1b44cd" -dependencies = [ - "base64 0.22.1", - "block", - "cocoa", - "core-graphics", - "crossbeam-channel", - "dpi", - "dunce", - "gdkx11", - "gtk", - "html5ever", - "http", - "javascriptcore-rs", - "jni", - "kuchikiki", - "libc", - "ndk", - "ndk-context", - "ndk-sys", - "objc", - "objc_id", - "once_cell", - "percent-encoding", - "raw-window-handle 0.6.2", - "sha2", - "soup3", - "tao-macros", - "thiserror", - "webkit2gtk", - "webkit2gtk-sys", - "webview2-com", - "windows 0.57.0", - "windows-core 0.57.0", - "windows-version", - "x11-dl", -] - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "x11" -version = "2.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" -dependencies = [ - "libc", - "pkg-config", -] - -[[package]] -name = "x11-dl" -version = "2.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" -dependencies = [ - "libc", - "once_cell", - "pkg-config", -] - -[[package]] -name = "xattr" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" -dependencies = [ - "libc", - "linux-raw-sys", - "rustix", -] - -[[package]] -name = "xdg-home" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca91dcf8f93db085f3a0a29358cd0b9d670915468f4290e8b85d118a34211ab8" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "zbus" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b8e3d6ae3342792a6cc2340e4394334c7402f3d793b390d2c5494a4032b3030" -dependencies = [ - "async-broadcast", - "async-process", - "async-recursion", - "async-trait", - "derivative", - "enumflags2", - "event-listener", - "futures-core", - "futures-sink", - "futures-util", - "hex", - "nix 0.27.1", - "ordered-stream", - "rand 0.8.5", - "serde", - "serde_repr", - "sha1", - "static_assertions", - "tokio", - "tracing", - "uds_windows", - "windows-sys 0.52.0", - "xdg-home", - "zbus_macros", - "zbus_names", - "zvariant", -] - -[[package]] -name = "zbus_macros" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7a3e850ff1e7217a3b7a07eba90d37fe9bb9e89a310f718afcde5885ca9b6d7" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "regex", - "syn 1.0.109", - "zvariant_utils", -] - -[[package]] -name = "zbus_names" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" -dependencies = [ - "serde", - "static_assertions", - "zvariant", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" - -[[package]] -name = "zip" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775a2b471036342aa69bc5a602bc889cb0a06cda00477d0c69566757d5553d39" -dependencies = [ - "arbitrary", - "crc32fast", - "crossbeam-utils", - "displaydoc", - "indexmap 2.2.6", - "memchr", - "thiserror", -] - -[[package]] -name = "zune-core" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" - -[[package]] -name = "zune-inflate" -version = "0.2.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" -dependencies = [ - "simd-adler32", -] - -[[package]] -name = "zune-jpeg" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" -dependencies = [ - "zune-core", -] - -[[package]] -name = "zvariant" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e09e8be97d44eeab994d752f341e67b3b0d80512a8b315a0671d47232ef1b65" -dependencies = [ - "endi", - "enumflags2", - "serde", - "static_assertions", - "url", - "zvariant_derive", -] - -[[package]] -name = "zvariant_derive" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a5857e2856435331636a9fbb415b09243df4521a267c5bedcd5289b4d5799e" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", - "zvariant_utils", -] - -[[package]] -name = "zvariant_utils" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00bedb16a193cc12451873fee2a1bc6550225acece0e36f333e68326c73c8172" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.15", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_log-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ecc8056bf6ab9892dcd53216c83d1597487d7dacac16c8df6b877d127df9937" + +[[package]] +name = "android_logger" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b07e8e73d720a1f2e4b6014766e6039fd2e96a4fa44e2a78d0e1fa2ff49826" +dependencies = [ + "android_log-sys", + "env_filter", + "log", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "ashpd" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd884d7c72877a94102c3715f3b1cd09ff4fac28221add3e57cfbe25c236d093" +dependencies = [ + "enumflags2", + "futures-channel", + "futures-util", + "rand 0.8.5", + "serde", + "serde_repr", + "tokio", + "url", + "zbus", +] + +[[package]] +name = "async-broadcast" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-io" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" +dependencies = [ + "async-lock", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7eda79bbd84e29c2b308d1dc099d7de8dcc7035e48f4bf5dc4a531a44ff5e2a" +dependencies = [ + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "async-signal" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "794f185324c2f00e771cd9f1ae8b5ac68be2ca7abb129a87afd6e86d228bc54d" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "atk" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4af014b17dd80e8af9fa689b2d4a211ddba6eb583c1622f35d0cb543f6b17e4" +dependencies = [ + "atk-sys", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "251e0b7d90e33e0ba930891a505a9a35ece37b2dd37a14f3ffc306c13b980009" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "auto-launch" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f012b8cc0c850f34117ec8252a44418f2e34a2cf501de89e29b241ae5f79471" +dependencies = [ + "dirs 4.0.0", + "thiserror", + "winreg 0.10.1", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "battery" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b624268937c0e0a3edb7c27843f9e547c320d730c610d3b8e6e8e95b2026e4" +dependencies = [ + "cfg-if", + "core-foundation 0.7.0", + "lazycell", + "libc", + "mach", + "nix 0.19.1", + "num-traits", + "uom", + "winapi", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] + +[[package]] +name = "bitstream-io" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "415f8399438eb5e4b2f73ed3152a3448b98149dda642a957ee704e1daa5cf1d8" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2", +] + +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "borsh" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d4d6dafc1a3bb54687538972158f07b2c948bc57d5890df22c0739098b3028" +dependencies = [ + "borsh-derive", + "cfg_aliases 0.1.1", +] + +[[package]] +name = "borsh-derive" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4918709cc4dd777ad2b6303ed03cb37f3ca0ccede8c1b0d28ac6db8f4710e0" +dependencies = [ + "once_cell", + "proc-macro-crate 2.0.2", + "proc-macro2", + "quote", + "syn 2.0.68", + "syn_derive", +] + +[[package]] +name = "brotli" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "built" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6a6c0b39c38fd754ac338b00a88066436389c0f029da5d37d1e01091d9b7c17" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byte-unit" +version = "5.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ac19bdf0b2665407c39d82dbc937e951e7e2001609f0fb32edd0af45a2d63e" +dependencies = [ + "rust_decimal", + "serde", + "utf8-width", +] + +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bytemuck" +version = "1.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +dependencies = [ + "serde", +] + +[[package]] +name = "cairo-rs" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" +dependencies = [ + "bitflags 2.6.0", + "cairo-sys-rs", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "camino" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cargo_toml" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a969e13a7589e9e3e4207e153bae624ade2b5622fb4684a4923b23ec3d57719" +dependencies = [ + "serde", + "toml 0.8.2", +] + +[[package]] +name = "cc" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac367972e516d45567c7eafc73d24e1c193dcf200a8d94e9db7b3d38b349572d" +dependencies = [ + "jobserver", + "libc", + "once_cell", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfb" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-targets 0.52.6", +] + +[[package]] +name = "clap" +version = "4.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "clap_lex" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" + +[[package]] +name = "cocoa" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation 0.9.4", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation 0.9.4", + "core-graphics-types", + "libc", + "objc", +] + +[[package]] +name = "color-eyre" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.15", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4934e6b7e8419148b6ef56950d277af8561060b56afd59e2aadf98b59fce6baa" +dependencies = [ + "cookie", + "idna 0.5.0", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + +[[package]] +name = "core-foundation" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" +dependencies = [ + "core-foundation-sys 0.7.0", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys 0.8.6", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.68", +] + +[[package]] +name = "ctor" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" +dependencies = [ + "quote", + "syn 2.0.68", +] + +[[package]] +name = "darling" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.68", +] + +[[package]] +name = "darling_macro" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "data-url" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.68", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys 0.3.7", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys 0.4.1", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "dlopen2" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1297103d2bbaea85724fcee6294c2d50b1081f9ad47d0f6f6f61eda65315a6" +dependencies = [ + "dlopen2_derive", + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "dlopen2_derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + +[[package]] +name = "dpi" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" +dependencies = [ + "serde", +] + +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "embed-resource" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6985554d0688b687c5cb73898a34fbe3ad6c24c58c238a4d91d5e840670ee9d" +dependencies = [ + "cc", + "memchr", + "rustc_version", + "toml 0.8.2", + "vswhom", + "winreg 0.52.0", +] + +[[package]] +name = "embed_plist" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" + +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "endi" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" + +[[package]] +name = "enumflags2" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "erased-serde" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" +dependencies = [ + "serde", + "typeid", +] + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "exr" +version = "1.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "fdeflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "fern" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee" +dependencies = [ + "log", +] + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", +] + +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gdk" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5ba081bdef3b75ebcdbfc953699ed2d7417d6bd853347a42a37d76406a33646" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", + "once_cell", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31ff856cb3386dae1703a920f803abafcc580e9b5f711ca62ed1620c25b51ff2" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkwayland-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a90fbf5c033c65d93792192a49a8efb5bb1e640c419682a58bb96f5ae77f3d4a" +dependencies = [ + "gdk-sys", + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkx11" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2ea8a4909d530f79921290389cbd7c34cb9d623bfe970eaae65ca5f9cd9cce" +dependencies = [ + "gdk", + "gdkx11-sys", + "gio", + "glib", + "libc", + "x11", +] + +[[package]] +name = "gdkx11-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee8f00f4ee46cad2939b8990f5c70c94ff882c3028f3cc5abf950fa4ab53043" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps", + "x11", +] + +[[package]] +name = "generator" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows 0.48.0", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getset" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "gio" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "once_cell", + "pin-project-lite", + "smallvec", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + +[[package]] +name = "glib" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" +dependencies = [ + "bitflags 2.6.0", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "once_cell", + "smallvec", + "thiserror", +] + +[[package]] +name = "glib-macros" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" +dependencies = [ + "heck 0.4.1", + "proc-macro-crate 2.0.2", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "glib-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gobject-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gtk" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93c4f5e0e20b60e10631a5f06da7fe3dda744b05ad0ea71fee2f47adf865890c" +dependencies = [ + "atk", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771437bf1de2c1c0b496c11505bdf748e26066bbe942dfc8f614c9460f6d7722" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk3-macros" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6063efb63db582968fb7df72e1ae68aa6360dcfb0a75143f34fc7d616bad75e" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "h2" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "html5ever" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.11", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "http-range" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" + +[[package]] +name = "httparse" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" + +[[package]] +name = "hyper" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "itoa 1.0.11", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys 0.8.6", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core 0.52.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ico" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3804960be0bb5e4edb1e1ad67afd321a9ecfd875c3e65c099468fd2717d7cae" +dependencies = [ + "byteorder", + "png", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-traits", + "png", +] + +[[package]] +name = "image" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "image-webp", + "num-traits", + "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d730b085583c4d789dfd07fdcf185be59501666a90c97c40162b37e4fdad272d" +dependencies = [ + "byteorder-lite", + "thiserror", +] + +[[package]] +name = "imgref" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", + "serde", +] + +[[package]] +name = "infer" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb33622da908807a06f9513c19b3c1ad50fab3e4137d82a78107d502075aa199" +dependencies = [ + "cfb", +] + +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags 1.3.2", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "javascriptcore-rs" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc" +dependencies = [ + "bitflags 1.3.2", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json-patch" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec9ad60d674508f3ca8f380a928cfe7b096bc729c4e2dbfe3852bc45da3ab30b" +dependencies = [ + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "keyboard-types" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" +dependencies = [ + "bitflags 2.6.0", + "serde", + "unicode-segmentation", +] + +[[package]] +name = "kqueue" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + +[[package]] +name = "kuchikiki" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8" +dependencies = [ + "cssparser", + "html5ever", + "indexmap 1.9.3", + "matches", + "selectors", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "libappindicator" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a" +dependencies = [ + "glib", + "gtk", + "gtk-sys", + "libappindicator-sys", + "log", +] + +[[package]] +name = "libappindicator-sys" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" +dependencies = [ + "gtk-sys", + "libloading", + "once_cell", +] + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libfuzzer-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", +] + +[[package]] +name = "line-wrap" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +dependencies = [ + "value-bag", +] + +[[package]] +name = "loom" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "macro_rules_attribute" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a82271f7bc033d84bbca59a3ce3e4159938cb08a9c3aebbe54d215131518a13" +dependencies = [ + "macro_rules_attribute-proc_macro", + "paste", +] + +[[package]] +name = "macro_rules_attribute-proc_macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dd856d451cc0da70e2ef2ce95a18e39a93b7558bedf10201ad28503f918568" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "markup5ever" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" +dependencies = [ + "log", + "phf 0.10.1", + "phf_codegen 0.10.0", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "minisign-verify" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "933dca44d65cdd53b355d0b73d380a2ff5da71f87f036053188bf1eab6a19881" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "muda" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b959f97c97044e4c96e32e1db292a7d594449546a3c6b77ae613dc3a5b5145" +dependencies = [ + "cocoa", + "crossbeam-channel", + "dpi", + "gtk", + "keyboard-types", + "objc", + "once_cell", + "png", + "serde", + "thiserror", + "windows-sys 0.52.0", +] + +[[package]] +name = "ndk" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +dependencies = [ + "bitflags 1.3.2", + "jni-sys", + "ndk-sys", + "num_enum", + "raw-window-handle 0.5.2", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.4.1+23.1.7779620" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nix" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2" +dependencies = [ + "bitflags 1.3.2", + "cc", + "cfg-if", + "libc", +] + +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + +[[package]] +name = "notify" +version = "6.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" +dependencies = [ + "bitflags 2.6.0", + "crossbeam-channel", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "walkdir", + "windows-sys 0.48.0", +] + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.6.0", + "block2", + "libc", + "objc2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-encode" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.6.0", + "block2", + "dispatch", + "libc", + "objc2", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "open" +version = "5.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5ca541f22b1c46d4bb9801014f234758ab4297e7870b904b6a8415b980a7388" +dependencies = [ + "is-wsl", + "libc", + "pathdiff", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "ordered-multimap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" +dependencies = [ + "dlv-list", + "hashbrown 0.14.5", +] + +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "os_info" +version = "3.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092" +dependencies = [ + "log", + "serde", + "windows-sys 0.52.0", +] + +[[package]] +name = "os_pipe" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29d73ba8daf8fac13b0501d1abeddcfe21ba7401ada61a819144b6c2a4f32209" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "pango" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" +dependencies = [ + "gio", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.2", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_shared 0.10.0", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros 0.11.2", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_codegen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.5", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "plist" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9d34169e64b3c7a80c8621a48adaf44e0cf62c78a9b25dd9dd35f1881a17cf9" +dependencies = [ + "base64 0.21.7", + "indexmap 2.2.6", + "line-wrap", + "quick-xml", + "serde", + "time", +] + +[[package]] +name = "png" +version = "0.17.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "3.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +dependencies = [ + "toml_datetime", + "toml_edit 0.20.2", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" +dependencies = [ + "quote", + "syn 2.0.68", +] + +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "publicsuffix" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" +dependencies = [ + "idna 0.3.0", + "psl-types", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quick-xml" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +dependencies = [ + "memchr", +] + +[[package]] +name = "quinn" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ceeeeabace7857413798eb1ffa1e9c905a9946a57d81fb69b4b71c4d8eb3ad" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddf517c03a109db8100448a4be38d498df8a210a99fe0e1b9eaf39e78c640efe" +dependencies = [ + "bytes", + "rand 0.8.5", + "ring", + "rustc-hash", + "rustls", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9096629c45860fc7fb143e125eb826b5e721e10be3263160c7d60ca832cf8c46" +dependencies = [ + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand 0.8.5", + "rand_chacha 0.3.1", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67376f469e7e7840d0040bbf4b9b3334005bb167f814621326e4c7ab8cd6e944" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom 0.2.15", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "reqwest" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +dependencies = [ + "base64 0.22.1", + "bytes", + "cookie", + "cookie_store", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pemfile", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-rustls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", + "winreg 0.52.0", +] + +[[package]] +name = "rfd" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a73a7337fc24366edfca76ec521f51877b114e42dab584008209cca6719251" +dependencies = [ + "ashpd", + "block", + "dispatch", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "log", + "objc", + "objc-foundation", + "objc_id", + "raw-window-handle 0.6.2", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rgb" +version = "0.8.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.15", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rkyv" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rust-ini" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e310ef0e1b6eeb79169a1171daf9abcb87a2e17c03bee2c4bb100b55c75409f" +dependencies = [ + "cfg-if", + "ordered-multimap", + "trim-in-place", +] + +[[package]] +name = "rust_decimal" +version = "1.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits", + "rand 0.8.5", + "rkyv", + "serde", + "serde_json", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.23.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + +[[package]] +name = "rustls-webpki" +version = "0.102.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schemars" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" +dependencies = [ + "dyn-clone", + "indexmap 1.9.3", + "schemars_derive", + "serde", + "serde_json", + "url", +] + +[[package]] +name = "schemars_derive" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.68", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "seelen-ui" +version = "1.9.4" +dependencies = [ + "arc-swap", + "base64 0.22.1", + "battery", + "clap", + "color-eyre", + "crossbeam-channel", + "getset", + "image 0.25.1", + "itertools", + "lazy_static", + "log", + "notify", + "os_info", + "parking_lot", + "phf 0.11.2", + "regex", + "serde", + "serde_json", + "serde_yaml", + "sysinfo", + "tauri", + "tauri-build", + "tauri-plugin-autostart", + "tauri-plugin-deep-link", + "tauri-plugin-dialog", + "tauri-plugin-fs", + "tauri-plugin-http", + "tauri-plugin-log", + "tauri-plugin-process", + "tauri-plugin-shell", + "tauri-plugin-updater", + "uuid", + "widestring", + "win-screenshot", + "windows 0.57.0", + "windows-core 0.57.0", + "winreg 0.52.0", + "winvd", +] + +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags 1.3.2", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen 0.8.0", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +dependencies = [ + "serde", +] + +[[package]] +name = "serde" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-untagged" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2676ba99bd82f75cae5cbd2c8eda6fa0b8760f18978ea840e980dd5567b5c5b6" +dependencies = [ + "erased-serde", + "serde", + "typeid", +] + +[[package]] +name = "serde_derive" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "serde_json" +version = "1.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4" +dependencies = [ + "itoa 1.0.11", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "serde_spanned" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa 1.0.11", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.2.6", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap 2.2.6", + "itoa 1.0.11", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "serialize-to-javascript" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9823f2d3b6a81d98228151fdeaf848206a7855a7a042bbf9bf870449a66cafb" +dependencies = [ + "serde", + "serde_json", + "serialize-to-javascript-impl", +] + +[[package]] +name = "serialize-to-javascript-impl" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74064874e9f6a15f04c1f3cb627902d0e6b410abbf36668afa873c61889f1763" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shared_child" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d94659ad3c2137fef23ae75b03d5241d633f8acded53d672decfa0e6e0caef" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "softbuffer" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d623bff5d06f60d738990980d782c8c866997d9194cfe79ecad00aa2f76826dd" +dependencies = [ + "bytemuck", + "cfg_aliases 0.2.1", + "core-graphics", + "foreign-types", + "js-sys", + "log", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-quartz-core", + "raw-window-handle 0.6.2", + "redox_syscall 0.5.2", + "wasm-bindgen", + "web-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "soup3" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f" +dependencies = [ + "futures-channel", + "gio", + "glib", + "libc", + "soup3-sys", +] + +[[package]] +name = "soup3-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "state" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8" +dependencies = [ + "loom", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared 0.10.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "swift-rs" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bbdb58577b6301f8d17ae2561f32002a5bae056d444e0f69e611e504a276204" +dependencies = [ + "base64 0.21.7", + "serde", + "serde_json", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + +[[package]] +name = "sysinfo" +version = "0.30.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732ffa00f53e6b2af46208fba5718d9662a421049204e156328b66791ffa15ae" +dependencies = [ + "cfg-if", + "core-foundation-sys 0.8.6", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows 0.52.0", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys 0.8.6", + "libc", +] + +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck 0.5.0", + "pkg-config", + "toml 0.8.2", + "version-compare", +] + +[[package]] +name = "tao" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea538df05fbc2dcbbd740ba0cfe8607688535f4798d213cbbfa13ce494f3451f" +dependencies = [ + "bitflags 2.6.0", + "cocoa", + "core-foundation 0.9.4", + "core-graphics", + "crossbeam-channel", + "dispatch", + "dlopen2", + "dpi", + "gdkwayland-sys", + "gdkx11-sys", + "gtk", + "instant", + "jni", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "objc", + "once_cell", + "parking_lot", + "raw-window-handle 0.6.2", + "scopeguard", + "tao-macros", + "unicode-segmentation", + "url", + "windows 0.57.0", + "windows-core 0.57.0", + "windows-version", + "x11-dl", +] + +[[package]] +name = "tao-macros" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec114582505d158b669b136e6851f85840c109819d77c42bb7c0709f727d18c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tar" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "target-lexicon" +version = "0.12.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" + +[[package]] +name = "tauri" +version = "2.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ee93e545e49458813d4ed16179c67ee6141dba140ec3d4f078dda3b8d4e0d1" +dependencies = [ + "anyhow", + "bytes", + "cocoa", + "dirs 5.0.1", + "dunce", + "embed_plist", + "futures-util", + "getrandom 0.2.15", + "glob", + "gtk", + "heck 0.5.0", + "http", + "http-range", + "image 0.24.9", + "jni", + "libc", + "log", + "mime", + "muda", + "objc", + "percent-encoding", + "raw-window-handle 0.6.2", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "serialize-to-javascript", + "state", + "swift-rs", + "tauri-build", + "tauri-macros", + "tauri-runtime", + "tauri-runtime-wry", + "tauri-utils", + "thiserror", + "tokio", + "tray-icon", + "url", + "urlpattern", + "webkit2gtk", + "webview2-com", + "window-vibrancy", + "windows 0.57.0", +] + +[[package]] +name = "tauri-build" +version = "2.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a58b3a716b51d7f671f729bb8c0a53cd2551eec8450c64e828ef4e6c9f948e" +dependencies = [ + "anyhow", + "cargo_toml", + "dirs 5.0.1", + "glob", + "heck 0.5.0", + "json-patch", + "schemars", + "semver", + "serde", + "serde_json", + "tauri-utils", + "tauri-winres", + "toml 0.8.2", + "walkdir", +] + +[[package]] +name = "tauri-codegen" +version = "2.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90a9e63ecd827d57228864764e0234935c9aac230099cf145197c8c08e754ced" +dependencies = [ + "base64 0.22.1", + "brotli", + "ico", + "json-patch", + "plist", + "png", + "proc-macro2", + "quote", + "semver", + "serde", + "serde_json", + "sha2", + "syn 2.0.68", + "tauri-utils", + "thiserror", + "time", + "url", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-macros" +version = "2.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a54f5d5b289aa6215ffcfed7d4ff9960a04b7a854436d04519a9fcf911050cba" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.68", + "tauri-codegen", + "tauri-utils", +] + +[[package]] +name = "tauri-plugin" +version = "2.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03ce2ac5e182251ff932750d69c9b240a78e44901a7a6234814d63c595b43660" +dependencies = [ + "anyhow", + "glob", + "plist", + "schemars", + "serde", + "serde_json", + "tauri-utils", + "toml 0.8.2", + "walkdir", +] + +[[package]] +name = "tauri-plugin-autostart" +version = "2.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25958a42daab7aaff4faff15cbaffd5505873a0654e6382c74fca1729a791898" +dependencies = [ + "auto-launch", + "log", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "thiserror", +] + +[[package]] +name = "tauri-plugin-deep-link" +version = "2.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db97f4b54f2e6f24681c3fffbcb7e9cfff24003b92bb8d3944a39072b8a1178" +dependencies = [ + "dunce", + "log", + "rust-ini", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "tauri-utils", + "thiserror", + "url", + "windows-registry", + "windows-result 0.2.0", +] + +[[package]] +name = "tauri-plugin-dialog" +version = "2.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c538457a755a75b8bb1594ed40d1512f8f6386251d3fcde492f8f46768ec85b" +dependencies = [ + "dunce", + "log", + "raw-window-handle 0.6.2", + "rfd", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "tauri-plugin-fs", + "thiserror", +] + +[[package]] +name = "tauri-plugin-fs" +version = "2.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5df6b25b1f2b7b61565e66c4dbee9eb39e5635d2a763206e380e07cc3f601a67" +dependencies = [ + "anyhow", + "glob", + "schemars", + "serde", + "serde_json", + "serde_repr", + "tauri", + "tauri-plugin", + "thiserror", + "url", + "uuid", +] + +[[package]] +name = "tauri-plugin-http" +version = "2.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1eef17218eaa8bd0fc6cafb7831c63d82ef83b3950d59dc817d92d5320c4f20c" +dependencies = [ + "data-url", + "http", + "regex", + "reqwest", + "schemars", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "tauri-plugin-fs", + "thiserror", + "tokio", + "url", + "urlpattern", +] + +[[package]] +name = "tauri-plugin-log" +version = "2.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380d27f23c39cde6a73024e65d8ec9b5b0af861e968dbe16b3aad86cd2c578e5" +dependencies = [ + "android_logger", + "byte-unit", + "cocoa", + "fern", + "log", + "objc", + "serde", + "serde_json", + "serde_repr", + "swift-rs", + "tauri", + "tauri-plugin", + "thiserror", + "time", +] + +[[package]] +name = "tauri-plugin-process" +version = "2.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d3663df0cd3e96feb37d46aad5d499d2edfcca5c62548ad34f1684e0019168" +dependencies = [ + "tauri", + "tauri-plugin", +] + +[[package]] +name = "tauri-plugin-shell" +version = "2.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9209f6c32caec61e156a5616f7d80ba7683ca4a0a5641cbe5d3086ab371aaab2" +dependencies = [ + "encoding_rs", + "log", + "open", + "os_pipe", + "regex", + "schemars", + "serde", + "serde_json", + "shared_child", + "tauri", + "tauri-plugin", + "thiserror", + "tokio", +] + +[[package]] +name = "tauri-plugin-updater" +version = "2.0.0-rc.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b5f10ba18d2fc65e16bdf053b7beccb621dcf880c52d2ab08bdeb2d685e3e14" +dependencies = [ + "base64 0.22.1", + "dirs 5.0.1", + "flate2", + "futures-util", + "http", + "infer", + "minisign-verify", + "reqwest", + "semver", + "serde", + "serde_json", + "tar", + "tauri", + "tauri-plugin", + "tempfile", + "thiserror", + "time", + "tokio", + "url", + "windows-sys 0.52.0", + "zip", +] + +[[package]] +name = "tauri-runtime" +version = "2.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f01b129b1ebdf09563c354760dbe7c0e96a166b4e33362d9c8d207f527c7ea5" +dependencies = [ + "dpi", + "gtk", + "http", + "jni", + "raw-window-handle 0.6.2", + "serde", + "serde_json", + "tauri-utils", + "thiserror", + "url", + "windows 0.57.0", +] + +[[package]] +name = "tauri-runtime-wry" +version = "2.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcda27639094ace2bf25f00bc10e35ea4e3af2f92753b1bdd2a174d1fa5a6292" +dependencies = [ + "cocoa", + "gtk", + "http", + "jni", + "log", + "percent-encoding", + "raw-window-handle 0.6.2", + "softbuffer", + "tao", + "tauri-runtime", + "tauri-utils", + "url", + "webkit2gtk", + "webview2-com", + "windows 0.57.0", + "wry", +] + +[[package]] +name = "tauri-utils" +version = "2.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28bb83cffa26e9cb7a2b3d0c31ab87bf277f44aaaa90f17159aef4d37aabd051" +dependencies = [ + "brotli", + "cargo_metadata", + "ctor", + "dunce", + "glob", + "html5ever", + "infer", + "json-patch", + "kuchikiki", + "log", + "memchr", + "phf 0.11.2", + "proc-macro2", + "quote", + "regex", + "schemars", + "semver", + "serde", + "serde-untagged", + "serde_json", + "serde_with", + "swift-rs", + "thiserror", + "toml 0.8.2", + "url", + "urlpattern", + "walkdir", +] + +[[package]] +name = "tauri-winres" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5993dc129e544393574288923d1ec447c857f3f644187f4fbf7d9a875fbfc4fb" +dependencies = [ + "embed-resource", + "toml 0.7.8", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa 1.0.11", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "tracing", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.19.15", +] + +[[package]] +name = "toml" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.20.2", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "tray-icon" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ad8319cca93189ea9ab1b290de0595960529750b6b8b501a399ed1ec3775d60" +dependencies = [ + "cocoa", + "core-graphics", + "crossbeam-channel", + "dirs 5.0.1", + "libappindicator", + "muda", + "objc", + "once_cell", + "png", + "serde", + "thiserror", + "windows-sys 0.52.0", +] + +[[package]] +name = "trim-in-place" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc" + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typeid" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "059d83cc991e7a42fc37bd50941885db0888e34209f8cfd9aab07ddec03bc9cf" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "uds_windows" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" +dependencies = [ + "memoffset", + "tempfile", + "winapi", +] + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-ucd-ident" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "uom" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e76503e636584f1e10b9b3b9498538279561adcef5412927ba00c2b32c4ce5ed" +dependencies = [ + "num-traits", + "typenum", +] + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna 0.5.0", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlpattern" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9bd5ff03aea02fa45b13a7980151fe45009af1980ba69f651ec367121a31609" +dependencies = [ + "derive_more", + "regex", + "serde", + "unic-ucd-ident", + "url", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" +dependencies = [ + "getrandom 0.2.15", +] + +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "value-bag" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" + +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vswhom" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" +dependencies = [ + "libc", + "vswhom-sys", +] + +[[package]] +name = "vswhom-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b17ae1f6c8a2b28506cd96d412eebf83b4a0ff2cbefeeb952f2f9dfa44ba18" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.68", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wasm-streams" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webkit2gtk" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup3", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c" +dependencies = [ + "bitflags 1.3.2", + "cairo-sys-rs", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pkg-config", + "soup3-sys", + "system-deps", +] + +[[package]] +name = "webpki-roots" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "webview2-com" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6516cfa64c6b3212686080eeec378e662c2af54bb2a5b2a22749673f5cb2226f" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows 0.57.0", + "windows-core 0.57.0", + "windows-implement", + "windows-interface", +] + +[[package]] +name = "webview2-com-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1345798ecd8122468840bcdf1b95e5dc6d2206c5e4b0eafa078d061f59c9bc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "webview2-com-sys" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c76d5b77320ff155660be1df3e6588bc85c75f1a9feef938cc4dc4dd60d1d7cf" +dependencies = [ + "thiserror", + "windows 0.57.0", + "windows-core 0.57.0", +] + +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + +[[package]] +name = "win-screenshot" +version = "4.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1724fbfec1c2344f8da8d2da6b0f8371f009df3291399df8c7b575a8abd121b" +dependencies = [ + "windows 0.57.0", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "window-vibrancy" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33082acd404763b315866e14a0d5193f3422c81086657583937a750cdd3ec340" +dependencies = [ + "cocoa", + "objc", + "raw-window-handle 0.6.2", + "windows-sys 0.52.0", + "windows-version", +] + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +dependencies = [ + "windows-core 0.57.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result 0.1.2", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.68", +] + +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result 0.2.0", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-version" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6998aa457c9ba8ff2fb9f13e9d2a930dabcea28f1d0ab94d687d8b3654844515" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "winvd" +version = "0.0.47" +source = "git+https://github.com/eythaann/virtualdesktopaccessor.git#b1e1da1931a2a21982396671a32a280330b1f507" +dependencies = [ + "macro_rules_attribute", + "windows 0.57.0", + "windows-core 0.57.0", + "windows-implement", + "windows-interface", +] + +[[package]] +name = "wry" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b00c945786b02d7805d09a969fa36d0eee4e0bd4fb3ec2a79d2bf45a1b44cd" +dependencies = [ + "base64 0.22.1", + "block", + "cocoa", + "core-graphics", + "crossbeam-channel", + "dpi", + "dunce", + "gdkx11", + "gtk", + "html5ever", + "http", + "javascriptcore-rs", + "jni", + "kuchikiki", + "libc", + "ndk", + "ndk-context", + "ndk-sys", + "objc", + "objc_id", + "once_cell", + "percent-encoding", + "raw-window-handle 0.6.2", + "sha2", + "soup3", + "tao-macros", + "thiserror", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows 0.57.0", + "windows-core 0.57.0", + "windows-version", + "x11-dl", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys", + "rustix", +] + +[[package]] +name = "xdg-home" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca91dcf8f93db085f3a0a29358cd0b9d670915468f4290e8b85d118a34211ab8" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "zbus" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b8e3d6ae3342792a6cc2340e4394334c7402f3d793b390d2c5494a4032b3030" +dependencies = [ + "async-broadcast", + "async-process", + "async-recursion", + "async-trait", + "derivative", + "enumflags2", + "event-listener", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix 0.27.1", + "ordered-stream", + "rand 0.8.5", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tokio", + "tracing", + "uds_windows", + "windows-sys 0.52.0", + "xdg-home", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7a3e850ff1e7217a3b7a07eba90d37fe9bb9e89a310f718afcde5885ca9b6d7" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" +dependencies = [ + "serde", + "static_assertions", + "zvariant", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zip" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775a2b471036342aa69bc5a602bc889cb0a06cda00477d0c69566757d5553d39" +dependencies = [ + "arbitrary", + "crc32fast", + "crossbeam-utils", + "displaydoc", + "indexmap 2.2.6", + "memchr", + "thiserror", +] + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" +dependencies = [ + "zune-core", +] + +[[package]] +name = "zvariant" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e09e8be97d44eeab994d752f341e67b3b0d80512a8b315a0671d47232ef1b65" +dependencies = [ + "endi", + "enumflags2", + "serde", + "static_assertions", + "url", + "zvariant_derive", +] + +[[package]] +name = "zvariant_derive" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72a5857e2856435331636a9fbb415b09243df4521a267c5bedcd5289b4d5799e" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00bedb16a193cc12451873fee2a1bc6550225acece0e36f333e68326c73c8172" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] diff --git a/Cargo.toml b/Cargo.toml index 4f03492f..5a9dff22 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,118 +1,118 @@ -cargo-features = ["profile-rustflags"] - -[package] -name = "seelen-ui" -version = "1.9.4" -description = "Seelen UI Background" -authors = ["eythaann"] -license = "Polyform Strict License" -repository = "https://github.com/eythaann/seelen-ui.git" -default-run = "seelen-ui" -edition = "2021" -rust-version = "1.70" -build = "scripts/build.rs" - -[[bin]] -name = "seelen-ui" -path = "src/background/main.rs" - -[profile.dev] -incremental = true -rustflags = ["-Z", "threads=8"] - -[build-dependencies] -tauri-build = { version = "2.0.0-beta", features = [] } - -[dependencies] -tauri = { version = "2.0.0-beta", features = [ - "protocol-asset", - "tray-icon", - "image-png", -] } -tauri-plugin-fs = "2.0.0-beta.2" -tauri-plugin-dialog = "2.0.0-beta.2" -tauri-plugin-autostart = "2.0.0-beta.2" -tauri-plugin-shell = "2.0.0-beta.2" -tauri-plugin-process = "2.0.0-beta.2" -tauri-plugin-log = "2.0.0-beta.2" -tauri-plugin-updater = "2.0.0-beta.2" -tauri-plugin-deep-link = "2.0.0-beta.10" -tauri-plugin-http = "2.0.0-beta.0" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -serde_yaml = "0.9.34" -color-eyre = "0.6.2" -lazy_static = "1.4.0" -parking_lot = "0.12.1" -log = "0.4" -uuid = "1.8.0" -image = "0.25.0" -widestring = "1.0.2" -itertools = "0.12.1" -clap = { version = "4.5.4", features = ["derive", "string"] } -os_info = "3.8.2" -crossbeam-channel = "0.5.12" -regex = "1.10.4" -getset = "0.1.2" -phf = "0.11.2" -sysinfo = "0.30.12" -battery = "0.7.8" -notify = "6.1.1" -winvd = { git = "https://github.com/eythaann/virtualdesktopaccessor.git" } -winreg = "0.52.0" -windows-core = "=0.57.0" # windows-rs already depends and reexports this, but we need it as a direct dependency (implement macro) -win-screenshot = "4.0.8" -base64 = "0.22.1" -arc-swap = "1.7.1" - -[dependencies.windows] -version = "=0.57.0" -features = [ - "Win32_Foundation", - "ApplicationModel", - "ApplicationModel_Core", # uwp apps - "ApplicationModel_Background", # background taks - "Foundation_Collections", # uwp apps - "Management_Deployment", # uwp apps - "Win32_UI_Input_KeyboardAndMouse", - "Win32_UI_WindowsAndMessaging", - "Win32_UI_Shell", - "Win32_UI_Shell_PropertiesSystem", - "Win32_UI_Accessibility", - "Win32_Graphics_Dwm", - "Win32_System_Com", - "Win32_System_Console", # required to attach to console on cli mode - "Win32_System_Registry", # required for system tray icon module - "Win32_Security", # required for power management (shutdown, reboot) - "Win32_System_Threading", - "Win32_System_WinRT", # uwp apps - "Win32_System_StationsAndDesktops", - "Win32_System_RemoteDesktop", - "Win32_System_ProcessStatus", - "Win32_System_Power", # required for power management (battery - AC) - "Win32_System_Shutdown", # required for power management (shutdown) - "Win32_Storage_EnhancedStorage", # PKEYS and Devices/Storage/etc - "Win32_Media_Audio_Endpoints", # required for audio module - "Win32_Media_DeviceManager", # required for audio module - "Media", # required for audio module - "Media_Control", # required for audio module - "Storage_Streams", # required for audio module - "Win32_Devices_Display", # required for display (brightness, etc) - "Win32_Devices_FunctionDiscovery", # PKEYS for Devices - "Devices_Custom", - "UI_Core", - "UI_Notifications_Management", # required for notifications - "UI_ViewManagement", # required for colors UISettings - "Win32_NetworkManagement_IpHelper", # required for network manager - "Win32_NetworkManagement_Ndis", # required for network manager - "Win32_Networking_WinSock", # required for network manager - "Win32_Networking_NetworkListManager", # required for network manager // events - "Win32_NetworkManagement_WiFi", # required for network manager // wifi -] - -[features] -# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled. -# If you use cargo directly instead of tauri's cli you can use this feature flag to switch between tauri's `dev` and `build` modes. -custom-protocol = ["tauri/custom-protocol"] -devtools = ["tauri/devtools"] -trace_lock = [] +cargo-features = ["profile-rustflags"] + +[package] +name = "seelen-ui" +version = "1.9.4" +description = "Seelen UI Background" +authors = ["eythaann"] +license = "Polyform Strict License" +repository = "https://github.com/eythaann/seelen-ui.git" +default-run = "seelen-ui" +edition = "2021" +rust-version = "1.70" +build = "scripts/build.rs" + +[[bin]] +name = "seelen-ui" +path = "src/background/main.rs" + +[profile.dev] +incremental = true +rustflags = ["-Z", "threads=8"] + +[build-dependencies] +tauri-build = { version = "2.0.0-beta", features = [] } + +[dependencies] +tauri = { version = "2.0.0-beta", features = [ + "protocol-asset", + "tray-icon", + "image-png", +] } +tauri-plugin-fs = "2.0.0-beta.2" +tauri-plugin-dialog = "2.0.0-beta.2" +tauri-plugin-autostart = "2.0.0-beta.2" +tauri-plugin-shell = "2.0.0-beta.2" +tauri-plugin-process = "2.0.0-beta.2" +tauri-plugin-log = "2.0.0-beta.2" +tauri-plugin-updater = "2.0.0-beta.2" +tauri-plugin-deep-link = "2.0.0-beta.10" +tauri-plugin-http = "2.0.0-beta.0" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +serde_yaml = "0.9.34" +color-eyre = "0.6.2" +lazy_static = "1.4.0" +parking_lot = "0.12.1" +log = "0.4" +uuid = "1.8.0" +image = "0.25.0" +widestring = "1.0.2" +itertools = "0.12.1" +clap = { version = "4.5.4", features = ["derive", "string"] } +os_info = "3.8.2" +crossbeam-channel = "0.5.12" +regex = "1.10.4" +getset = "0.1.2" +phf = "0.11.2" +sysinfo = "0.30.12" +battery = "0.7.8" +notify = "6.1.1" +winvd = { git = "https://github.com/eythaann/virtualdesktopaccessor.git" } +winreg = "0.52.0" +windows-core = "=0.57.0" # windows-rs already depends and reexports this, but we need it as a direct dependency (implement macro) +win-screenshot = "4.0.8" +base64 = "0.22.1" +arc-swap = "1.7.1" + +[dependencies.windows] +version = "=0.57.0" +features = [ + "Win32_Foundation", + "ApplicationModel", + "ApplicationModel_Core", # uwp apps + "ApplicationModel_Background", # background taks + "Foundation_Collections", # uwp apps + "Management_Deployment", # uwp apps + "Win32_UI_Input_KeyboardAndMouse", + "Win32_UI_WindowsAndMessaging", + "Win32_UI_Shell", + "Win32_UI_Shell_PropertiesSystem", + "Win32_UI_Accessibility", + "Win32_Graphics_Dwm", + "Win32_System_Com", + "Win32_System_Console", # required to attach to console on cli mode + "Win32_System_Registry", # required for system tray icon module + "Win32_Security", # required for power management (shutdown, reboot) + "Win32_System_Threading", + "Win32_System_WinRT", # uwp apps + "Win32_System_StationsAndDesktops", + "Win32_System_RemoteDesktop", + "Win32_System_ProcessStatus", + "Win32_System_Power", # required for power management (battery - AC) + "Win32_System_Shutdown", # required for power management (shutdown) + "Win32_Storage_EnhancedStorage", # PKEYS and Devices/Storage/etc + "Win32_Media_Audio_Endpoints", # required for audio module + "Win32_Media_DeviceManager", # required for audio module + "Media", # required for audio module + "Media_Control", # required for audio module + "Storage_Streams", # required for audio module + "Win32_Devices_Display", # required for display (brightness, etc) + "Win32_Devices_FunctionDiscovery", # PKEYS for Devices + "Devices_Custom", + "UI_Core", + "UI_Notifications_Management", # required for notifications + "UI_ViewManagement", # required for colors UISettings + "Win32_NetworkManagement_IpHelper", # required for network manager + "Win32_NetworkManagement_Ndis", # required for network manager + "Win32_Networking_WinSock", # required for network manager + "Win32_Networking_NetworkListManager", # required for network manager // events + "Win32_NetworkManagement_WiFi", # required for network manager // wifi +] + +[features] +# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled. +# If you use cargo directly instead of tauri's cli you can use this feature flag to switch between tauri's `dev` and `build` modes. +custom-protocol = ["tauri/custom-protocol"] +devtools = ["tauri/devtools"] +trace_lock = [] diff --git a/LICENSE b/LICENSE index aa142d5a..de1d03d9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,104 +1,104 @@ -# PolyForm Strict License 1.0.0 - - - -## Acceptance - -In order to get any license under these terms, you must agree -to them as both strict obligations and conditions to all -your licenses. - -## Copyright License - -The licensor grants you a copyright license for the software -to do everything you might do with the software that would -otherwise infringe the licensor's copyright in it for any -permitted purpose, other than distributing the software or -making changes or new works based on the software. - -## Patent License - -The licensor grants you a patent license for the software that -covers patent claims the licensor can license, or becomes able -to license, that you would infringe by using the software. - -## Noncommercial Purposes - -Any noncommercial purpose is a permitted purpose. - -## Personal Uses - -Personal use for research, experiment, and testing for -the benefit of public knowledge, personal study, private -entertainment, hobby projects, amateur pursuits, or religious -observance, without any anticipated commercial application, -is use for a permitted purpose. - -## Noncommercial Organizations - -Use by any charitable organization, educational institution, -public research organization, public safety or health -organization, environmental protection organization, -or government institution is use for a permitted purpose -regardless of the source of funding or obligations resulting -from the funding. - -## Fair Use - -You may have "fair use" rights for the software under the -law. These terms do not limit them. - -## No Other Rights - -These terms do not allow you to sublicense or transfer any of -your licenses to anyone else, or prevent the licensor from -granting licenses to anyone else. These terms do not imply -any other licenses. - -## Patent Defense - -If you make any written claim that the software infringes or -contributes to infringement of any patent, your patent license -for the software granted under these terms ends immediately. If -your company makes such a claim, your patent license ends -immediately for work on behalf of your company. - -## Violations - -The first time you are notified in writing that you have -violated any of these terms, or done anything with the software -not covered by your licenses, your licenses can nonetheless -continue if you come into full compliance with these terms, -and take practical steps to correct past violations, within -32 days of receiving notice. Otherwise, all your licenses -end immediately. - -## No Liability - -***As far as the law allows, the software comes as is, without -any warranty or condition, and the licensor will not be liable -to you for any damages arising out of these terms or the use -or nature of the software, under any kind of legal claim.*** - -## Definitions - -The **licensor** is the individual or entity offering these -terms, and the **software** is the software the licensor makes -available under these terms. - -**You** refers to the individual or entity agreeing to these -terms. - -**Your company** is any legal entity, sole proprietorship, -or other kind of organization that you work for, plus all -organizations that have control over, are under the control of, -or are under common control with that organization. **Control** -means ownership of substantially all the assets of an entity, -or the power to direct its management and policies by vote, -contract, or otherwise. Control can be direct or indirect. - -**Your licenses** are all the licenses granted to you for the -software under these terms. - -**Use** means anything you do with the software requiring one +# PolyForm Strict License 1.0.0 + + + +## Acceptance + +In order to get any license under these terms, you must agree +to them as both strict obligations and conditions to all +your licenses. + +## Copyright License + +The licensor grants you a copyright license for the software +to do everything you might do with the software that would +otherwise infringe the licensor's copyright in it for any +permitted purpose, other than distributing the software or +making changes or new works based on the software. + +## Patent License + +The licensor grants you a patent license for the software that +covers patent claims the licensor can license, or becomes able +to license, that you would infringe by using the software. + +## Noncommercial Purposes + +Any noncommercial purpose is a permitted purpose. + +## Personal Uses + +Personal use for research, experiment, and testing for +the benefit of public knowledge, personal study, private +entertainment, hobby projects, amateur pursuits, or religious +observance, without any anticipated commercial application, +is use for a permitted purpose. + +## Noncommercial Organizations + +Use by any charitable organization, educational institution, +public research organization, public safety or health +organization, environmental protection organization, +or government institution is use for a permitted purpose +regardless of the source of funding or obligations resulting +from the funding. + +## Fair Use + +You may have "fair use" rights for the software under the +law. These terms do not limit them. + +## No Other Rights + +These terms do not allow you to sublicense or transfer any of +your licenses to anyone else, or prevent the licensor from +granting licenses to anyone else. These terms do not imply +any other licenses. + +## Patent Defense + +If you make any written claim that the software infringes or +contributes to infringement of any patent, your patent license +for the software granted under these terms ends immediately. If +your company makes such a claim, your patent license ends +immediately for work on behalf of your company. + +## Violations + +The first time you are notified in writing that you have +violated any of these terms, or done anything with the software +not covered by your licenses, your licenses can nonetheless +continue if you come into full compliance with these terms, +and take practical steps to correct past violations, within +32 days of receiving notice. Otherwise, all your licenses +end immediately. + +## No Liability + +***As far as the law allows, the software comes as is, without +any warranty or condition, and the licensor will not be liable +to you for any damages arising out of these terms or the use +or nature of the software, under any kind of legal claim.*** + +## Definitions + +The **licensor** is the individual or entity offering these +terms, and the **software** is the software the licensor makes +available under these terms. + +**You** refers to the individual or entity agreeing to these +terms. + +**Your company** is any legal entity, sole proprietorship, +or other kind of organization that you work for, plus all +organizations that have control over, are under the control of, +or are under common control with that organization. **Control** +means ownership of substantially all the assets of an entity, +or the power to direct its management and policies by vote, +contract, or otherwise. Control can be direct or indirect. + +**Your licenses** are all the licenses granted to you for the +software under these terms. + +**Use** means anything you do with the software requiring one of your licenses. \ No newline at end of file diff --git a/capabilities/migrated.json b/capabilities/migrated.json index 83ffbba5..d0c2459d 100644 --- a/capabilities/migrated.json +++ b/capabilities/migrated.json @@ -1,73 +1,73 @@ -{ - "$schema": "../gen/schemas/windows-schema.json", - "identifier": "migrated", - "description": "permissions that were migrated from v1", - "local": true, - "windows": [ - "settings", - "seelenweg/*", - "seelenweg-hitbox/*", - "updater", - "window-manager/*", - "fancy-toolbar/*", - "fancy-toolbar-hitbox/*" - ], - "permissions": [ - "core:path:default", - "core:event:default", - "core:window:default", - "core:webview:default", - "core:app:default", - "core:resources:default", - "core:menu:default", - "core:tray:default", - "deep-link:default", - - "fs:allow-read-text-file", - "fs:allow-write-text-file", - "fs:allow-exists", - "fs:allow-mkdir", - "fs:allow-read-dir", - "fs:allow-copy-file", - "fs:allow-remove", - - { - "identifier": "fs:scope", - "allow": [ - { - "path": "**" - }, - { - "path": "**/*" - }, - { - "path": "/**/*" - } - ] - }, - - "core:window:allow-show", - "core:window:allow-close", - "core:window:allow-start-dragging", - "core:window:allow-set-size", - "core:window:allow-set-position", - "core:window:allow-set-ignore-cursor-events", - - "autostart:allow-enable", - "autostart:allow-disable", - "autostart:allow-is-enabled", - - "dialog:allow-save", - "dialog:allow-open", - - "process:allow-restart", - "process:allow-exit", - - "log:allow-log", - - "updater:allow-check", - "updater:allow-download-and-install", - - "shell:allow-open" - ] +{ + "$schema": "../gen/schemas/windows-schema.json", + "identifier": "migrated", + "description": "permissions that were migrated from v1", + "local": true, + "windows": [ + "settings", + "seelenweg/*", + "seelenweg-hitbox/*", + "updater", + "window-manager/*", + "fancy-toolbar/*", + "fancy-toolbar-hitbox/*" + ], + "permissions": [ + "core:path:default", + "core:event:default", + "core:window:default", + "core:webview:default", + "core:app:default", + "core:resources:default", + "core:menu:default", + "core:tray:default", + "deep-link:default", + + "fs:allow-read-text-file", + "fs:allow-write-text-file", + "fs:allow-exists", + "fs:allow-mkdir", + "fs:allow-read-dir", + "fs:allow-copy-file", + "fs:allow-remove", + + { + "identifier": "fs:scope", + "allow": [ + { + "path": "**" + }, + { + "path": "**/*" + }, + { + "path": "/**/*" + } + ] + }, + + "core:window:allow-show", + "core:window:allow-close", + "core:window:allow-start-dragging", + "core:window:allow-set-size", + "core:window:allow-set-position", + "core:window:allow-set-ignore-cursor-events", + + "autostart:allow-enable", + "autostart:allow-disable", + "autostart:allow-is-enabled", + + "dialog:allow-save", + "dialog:allow-open", + + "process:allow-restart", + "process:allow-exit", + + "log:allow-log", + + "updater:allow-check", + "updater:allow-download-and-install", + + "shell:allow-open" + ] } \ No newline at end of file diff --git a/changelog.md b/changelog.md index f5716be5..fabf38fa 100644 --- a/changelog.md +++ b/changelog.md @@ -1,573 +1,573 @@ -# Changelog - -## [Unreleased] -## [1.9.4] -### fix -- app crashing for new users - -## [1.9.3] -### performance -- reduce load time from ~7s to ~4s - -### features -- .slu and uri now are loaded correctly on seelen ui. -- allow change wallpaper from seelen settings. - -### enhancements -- add file associations for .slu files -- add uri associations for seelen-ui:uri -- improve settings editor experience by adding live reload feature. - -### fix -- cli no working on production - -## [1.9.1] -### fix -- no listening window moving of virtual desktop events. -- no closing or starting widgets on settings changes. -- no listening monitors changes. -- no loading toolbar modules on wake up - -## [1.9.0] -### features -- allow custom images on toolbar by `imgFromUrl`, `imgFromPath` and `imgFromExe` functions. -- add notifications module to toolbar. -- add exe path to window in generic module for toolbar. -- add focused window icon to default toolbar layouts. - -### enhancements -- icons now are recreated from exe path if icon was deleted. -- uwp icons now are loaded from background. -- improvements on themes selector. -- improvements on system color detection and expose more system colors based in accent gamma. -- improve theme creation experience by adding live reload feature. -- improve toolbar layouts (placeholders) creation experience by adding live reload feature. -- improve weg items editor experience by adding live reload feature. - -### refactor -- deprecate `onClick` and add new `onClickV2` on toolbar modules. - -### fix -- bad translations keys. -- no restoring dock on closing fullscreened app. - -## [1.8.12] -### fix -- app installed by msix no opening. - -## [1.8.11] -### fix -- remove unnecessary 1px padding on toolbar. - -## [1.8.10] -### enhancements -- remove unnecessary loop on taskbar hiding function. - -### fix -- no loading translations correctly on update modal. - -## [1.8.9] -### enhancements -- add translation to the rest of apps (dock, toolbar, and update modal). - -### fix -- not hiding the taskbar at start. -- opening multiple instances of the app. - -## [1.8.8] -### fix -- app not running on startup - -## [1.8.7] -### fix -- no updating themes on changes saved. - -## [1.8.6] -### features -- Add multi-language support! 🥳. -- Add default media input/output selectors to media module in fancy toolbar. -- Add start module to dock/taskbar (opens start menu). - -### enhancements -- Flat default themes to allow easier overrides. - -### fix -- Fix zorder on hovering on weg and toolbar respectively to wm borders. -- Applying bad themes on apps. -- Not hiding the taskbar at start. - -## [1.8.5] -### fix -- no executing seelen after update installation - -## [1.8.4] -## [1.8.3] -### refactor -- migrate settings files from `$USER/.config/seelen` to `$APPDATA/com.seelen.seelen-ui` -- load uwp apps info asynchronously - -### fix -- crash on move toolbar item -- can not remove media module - -## [1.8.2] -### features -- fancy toolbar items now can be dragged of position. -- using fancy toolbar's layout now can be modified and saved as custom.yml. - -## [1.8.1] -### features -- styles can be specified in fancy toolbar placeholder item. -- fancy toolbar item now will have an unique id, this can be specified in the placeholder file. - -### enhancements -- replace "bluetooth" for "devices" on bundled fancy toolbar placeholders. - -## [1.8.0] -### features -- Media module added to the toolbar. -- Media module added to SeelenWeg. - - ![Media Module Example](documentation/images/media_module_preview.png) - -- SeelenWeg now has a context menu (Right Click Menu). - -### enhancements -- enhancements on fullscreen events. - -### refactor -- remove Default Wave animation on seelenweg (users will be able to add their own animations). - -### fix -- no updating colors correctly on change light or dark mode on windows settings. -- window manager enabled by default for new users. -- showing tray icons with empty name. -- no focusing seelen settings if it was minimized. - -## [1.7.7] -### fix -- no registering system events (battery/network/etc) - -## [1.7.6] -### enhancements -- improve logging on dev mode and fix missing target on production logged errors. -- improve fullscreen matching. - -### fix -- network icon showing incorrect interface icon (lan instead wifi). -- no updating adapters list and using adapter on network changes. - -## [1.7.5] -## [1.7.4] -### enhancements -- improvements on workflows to auto upload artifacts to the store. - -## [1.7.3] -### enhancements -- improvements on fullscreen events. - -## [1.7.2] -### enhancements -- disable tiling window manager on windows 10 from UI (can be forced on settings.json file) - -### fix -- app crashing on windows 10 -- empty tray icons list on windows 10 - -## [1.7.1] -### enhancements -- separate `information` and `developer tools` tabs in the settings. -- add a option to open the install path in explorer. -- focus settings window if already exist. -- better performance on canceling changes in settings. -- avoid loading innecesary files in modules that are not used. -- update pinned apps path by filename on open (some apps change of path on updates so this will fix that). -- show empty message on toolbar when no wlan networks are found. - -### fix -- ahk error on save. - -## [1.7.0] -### features -- add Network toolbar module. -- add WLAN selector to the Network toolbar module. -- add css variable (--config-accent-color-rgb) to be used with css functions like `rgb` or `rgba`. - -### enhancements -- now placeholders, layouts and themes can be loaded from data users folder (`AppData\Roaming\com.seelen.seelen-ui`) -- now buttons and others components will use the user accent color. - -### fix -- no max size on System Tray List module. - -## [1.6.4] -### fix -- xbox games showing missing icons on SeelenWeg. - -### enhancements -- follow user accent color for tray list and windows borders - -### fix -- no showing promoted (pinned on taskbar) tray icons. -- toolbar no initialized correctly sometimes, now will retry if fails. -- battery no updating level. -- battery showing as always charging on default toolbar templates. -- tray overflow module no working on different languages. - -### refactor -- refactor on window_api and AppBar structures. - -## [1.6.3] -### enhancements -- only show a progress bar on update and not the complete installer GUI. - -### fix -- main app no running if the forced creation of tray overflow fails. - -## [1.6.2] -### features -- now `batteries` and `battery` (same as: `batteries[0]`) are available on the scope of power toolbar module. - -### enhancements -- add battery crate to handle batteries info directly from their drivers. -- show if is smart charging. -- now battery module wont be shown if batteries are not found. - -### fix -- battery showing 255%. - -## [1.6.1] -### fix -- tray icons not showing on startup -- hidden trays if icon was not found (now will show a missing icon) - -## [1.6.0] -### features -- add "Run as admin" option at context menu on Seelenweg. -- allow receive commands using TCP connections. -- Add System Tray Icons module, (incomplete, devices like usb or windows antivirus trays are still not supported). - -### enhancements -- improve power (battery) events performance. -- Window manager disabled by default to new users. - -### refactor -- remove tauri single instance plugin by TCP connection. - -## [1.5.0] -### features -- new placeholder added to the bundle as alternative to default. -- new workspace item available to be used in placeholders. - -### enhancements -- support fullscreen apps (will hide the toolbar and the weg on fullscreen an app). - -### fix -- showing incorrect format on dates at start of the app. -- complex text with icons on toolbar items cause wraps. -- missing icons on some uwp apps. - -### refactor -- refactor on window event manager to allow synthetic events. - -## [1.4.1] -### fix -- no truncating text on toolbar items overflow. -- rendering empty items on toolbar when empty placeholder is declared. - -## [1.4.0] -### features -- Modular Themes -- Themes now allow tags to be categorized. -- Allow add, organize, combine multiple themes as cascade layers. -- Themes now allow folder structure to improve developers experience. - -### refactor -- Now themes will use .yml files instead json to improve developers experience. -- Themes schema updated, no backwards compatibility with json themes. (.json in themes folder will be ignored) - -### fix -- No hiding the taskbar correctly. - -## [1.3.4] -### enhancements -- Add splash screen to Settings window. -- Add discord link on Information Section. - -### refactor -- Use TaskScheduler for autostart Seelen with priority and admin privileges. - -### fix -- bad zorder on Weg and Toolbar under the WM borders - -## [1.3.3] -### features -- Multi-monitor support for Fancy Toolbar. -- Multi-monitor support for Seelenweg. - -## [1.3.2] -### enhancements -- Remove unnecessary tooltip collision on toolbar items. - -### fix -- Crash on restoring app in other virtual desktop using Weg. -- Touch events not working on Toolbar and Weg. - -## [1.3.1] -### fix -- disable binding monitors and monitors on apps configurations for now. - -## [1.3.0] -### features -- Allow pin apps on Open using Apps Configurations. -- Allow changes Shortcuts using UI. -- Allow Binary Conditions in Apps Configurations Identifiers. -- Allow change the Auto hide behavior for Seelenweg. - -### enhancements -- Close AHK by itself if app is crashed or forcedly closed. -- Configurations by apps are enabled again. -- Allow open settings file from Extras/Information -- Add opacity to toolbar (theme: default) - -### fix -- Ahk not closing on app close or when user change options. - -## [1.2.4] -### enhancements -- Automatic MSIX bundle. -- Add Github Actions for Releases. -- Add Github Actions for Web Page. - -## [1.2.3] -### features -- Allow customize Fancy Toolbar modules using placeholders yaml files. -- Add fast settings for toolbar allowing to adjust volume, brightness, etc. - -## [1.2.2] -### enhancements -- if app on weg is cloak, change of virtual desktop instead minimize/restore - -### fix -- no closing AHK instances -- floating size on fallback -- reservation not working properly -- ignore top most windows by default (normally these are tools or widgets) -- minimization on weg not working properly if window manager is activated -- change focus using commands not working with conditional layouts -- randomly frozen app on start -- no tiling UWP apps - -## [1.2.1] -### enhancements -- Allow quit from settings -- Using Box-Content style in the position of windows instead outlined for a better user experience - -### fix -- Managing windows without caption (Title bar) -- can't update border configurations -- hiding dock on switching virtual desktops - -## [1.2.0] -### fix -- Taskbar showing instead be always hidden - -## [1.1.1] -### fix -- Bad download URL in Update Notification -- Showing update notification on installations by Windows Store - -## [1.1.0] -### features -- Add Smart Auto Hide for Seelenweg. -- Add visible Separators Option -- Enable animations for items into LEFT, TOP, RIGHT positions - -### enhancements -- Now the copy handles option will return hexadecimal handles instead decimal (good for faster debug in tools like spy++). - -### fix -- duped handles -- inconsistencies in separators width - -## [1.0.1] -### fix -- App downloaded form Microsoft Store was not running without admin. - -## [1.0.0] -### refactored -- Update notifications always enabled for nsis installer -- Update notifications will not appear if app is installed using msix (Microsoft Store). - -### enhancements -- Now by default if user is Admin, UAC will be triggered on run the app to allow a better integrated experience in SeelenWeg and Komorebi Tiling Manager. - -## [1.0.0-prerelease.14] -### features -- add indicator to know opens and focused apps on SeelenWeg -- allow set the position of seelenweg (left, top, right, bottom) 🎉 - -### enhancements -- only creates app icons the first time they are loaded - -### refactor -- change themes implementation to allow customs css files - -### fix -- incorrect icon for UWP (was using store icon instead taskbar icon) -- replacing icons on each load -- showing logs of opened apps on development -- offset margins working like windows RECT instead like one side margins - -## [1.0.0-prerelease.13] -### features -- add Themes Feature 🎉 (incomplete only for Seelenweg for now) -- add SeelenWeg (a Dock or Taskbar) beta feature -- add SeelenWeg in to Settings -- add ContextMenu for apps in SeelenWeg -- allow move apps in the Weg 😄 -- add Grouped Apps in one item -- live reload of Apps on events like change of title -- UWP apps support - -### enhancements -- move readme blob to documentation/images - -## [1.0.0-prerelease.12] -### enhancements -- add some traces on functions to save logs - -### fix -- clean installation of komorebi no working - -## [1.0.0-prerelease.11] -### refactor -- little improvements on background code - -### fix -- initial users can not save the settings - -## [1.0.0-prerelease.10] -### features -- add a update tab to allow users decide if will receive notifications for updates - -## [1.0.0-prerelease.9] -## [1.0.0-prerelease.8] -- add functionality to pause btn on tray menu - -## [1.0.0-prerelease.6] -### added -- Enable Updater 🎉 - -## [1.0.0-prerelease.3] -### fix -- icon not showing on tray -- poor icon quality on task bar -- StartUp running bad exe file - -## [1.0.0-prerelease.2] -## [1.0.0-prerelease.1] -### added -- implement tray icon - -### refactored -- Migrate all app background from Electron ⚡ to Tauri 🦀 -- reimplement startup to use native system startup -- reimplement included shortcuts with ahk -- reimplement komorebi autostart -- reimplement installer to use NSIS -- refactor folder structure to isolate front-end apps - -## [1.0.0-beta.13] -### enhancements -- improve maximized windows experience - -### fixed -- fix resize not working (now works like master) - -## [1.0.0-beta.12] -### added -- show current used versions on information -- add grid layout preview -- add win + k to open komorebi settings - -### refactored -- update komorebi to 0.1.22 - -### removed -- remove invisible borders feature - -## [1.0.0-beta.11] -### fixed -- missing property on schema -- white screen on start app - -## [1.0.0-beta.10] -### added -- add a new way to match applications by path - -### fixed -- searching feature on apps -- no focusing windows on change workspace -- autostacking not working properly -- workspaces rules not working - -## [1.0.0-beta.9] -### added -- add popups on actions 🦀 -- now can switch from installed and packaged and should work as the same - -### fixed -- fix no removing old path -- lag on many applications - -## [1.0.0-beta.8] -### added -- add more templates - -## [1.0.0-beta.7] -### fixed -- fix first install - -## [1.0.0-beta.6] -### added -- delete old paths on update - -### fixed -- fix not saving templates -- fix toggle ahk shortcuts does not run or stop the instance -- running ahk when disabled -- not updating the path of installation folder on update for windows tasks - -## [1.0.0-beta.5] -### added -- new searching option for applications -- templates feature - -### fixed -- including ghost apps on migration - -## [1.0.0-beta.4] -### added -- new feature of invisible borders per app -- new easy way to hard restart the services and AHK - -### changed -- delete border overflow and changed for invisible borders per app - -### fixed -- components was not triggering dark mode correctly - -## [1.0.0-beta.3] -### added -- new apps templates -- add AHK as a dependency to show to new users -- add AHK settings - -## [1.0.0-beta.2] -### added -- export option for apps - -### fixed -- delete bound monitor and workspace on an application +# Changelog + +## [Unreleased] +## [1.9.4] +### fix +- app crashing for new users + +## [1.9.3] +### performance +- reduce load time from ~7s to ~4s + +### features +- .slu and uri now are loaded correctly on seelen ui. +- allow change wallpaper from seelen settings. + +### enhancements +- add file associations for .slu files +- add uri associations for seelen-ui:uri +- improve settings editor experience by adding live reload feature. + +### fix +- cli no working on production + +## [1.9.1] +### fix +- no listening window moving of virtual desktop events. +- no closing or starting widgets on settings changes. +- no listening monitors changes. +- no loading toolbar modules on wake up + +## [1.9.0] +### features +- allow custom images on toolbar by `imgFromUrl`, `imgFromPath` and `imgFromExe` functions. +- add notifications module to toolbar. +- add exe path to window in generic module for toolbar. +- add focused window icon to default toolbar layouts. + +### enhancements +- icons now are recreated from exe path if icon was deleted. +- uwp icons now are loaded from background. +- improvements on themes selector. +- improvements on system color detection and expose more system colors based in accent gamma. +- improve theme creation experience by adding live reload feature. +- improve toolbar layouts (placeholders) creation experience by adding live reload feature. +- improve weg items editor experience by adding live reload feature. + +### refactor +- deprecate `onClick` and add new `onClickV2` on toolbar modules. + +### fix +- bad translations keys. +- no restoring dock on closing fullscreened app. + +## [1.8.12] +### fix +- app installed by msix no opening. + +## [1.8.11] +### fix +- remove unnecessary 1px padding on toolbar. + +## [1.8.10] +### enhancements +- remove unnecessary loop on taskbar hiding function. + +### fix +- no loading translations correctly on update modal. + +## [1.8.9] +### enhancements +- add translation to the rest of apps (dock, toolbar, and update modal). + +### fix +- not hiding the taskbar at start. +- opening multiple instances of the app. + +## [1.8.8] +### fix +- app not running on startup + +## [1.8.7] +### fix +- no updating themes on changes saved. + +## [1.8.6] +### features +- Add multi-language support! 🥳. +- Add default media input/output selectors to media module in fancy toolbar. +- Add start module to dock/taskbar (opens start menu). + +### enhancements +- Flat default themes to allow easier overrides. + +### fix +- Fix zorder on hovering on weg and toolbar respectively to wm borders. +- Applying bad themes on apps. +- Not hiding the taskbar at start. + +## [1.8.5] +### fix +- no executing seelen after update installation + +## [1.8.4] +## [1.8.3] +### refactor +- migrate settings files from `$USER/.config/seelen` to `$APPDATA/com.seelen.seelen-ui` +- load uwp apps info asynchronously + +### fix +- crash on move toolbar item +- can not remove media module + +## [1.8.2] +### features +- fancy toolbar items now can be dragged of position. +- using fancy toolbar's layout now can be modified and saved as custom.yml. + +## [1.8.1] +### features +- styles can be specified in fancy toolbar placeholder item. +- fancy toolbar item now will have an unique id, this can be specified in the placeholder file. + +### enhancements +- replace "bluetooth" for "devices" on bundled fancy toolbar placeholders. + +## [1.8.0] +### features +- Media module added to the toolbar. +- Media module added to SeelenWeg. + + ![Media Module Example](documentation/images/media_module_preview.png) + +- SeelenWeg now has a context menu (Right Click Menu). + +### enhancements +- enhancements on fullscreen events. + +### refactor +- remove Default Wave animation on seelenweg (users will be able to add their own animations). + +### fix +- no updating colors correctly on change light or dark mode on windows settings. +- window manager enabled by default for new users. +- showing tray icons with empty name. +- no focusing seelen settings if it was minimized. + +## [1.7.7] +### fix +- no registering system events (battery/network/etc) + +## [1.7.6] +### enhancements +- improve logging on dev mode and fix missing target on production logged errors. +- improve fullscreen matching. + +### fix +- network icon showing incorrect interface icon (lan instead wifi). +- no updating adapters list and using adapter on network changes. + +## [1.7.5] +## [1.7.4] +### enhancements +- improvements on workflows to auto upload artifacts to the store. + +## [1.7.3] +### enhancements +- improvements on fullscreen events. + +## [1.7.2] +### enhancements +- disable tiling window manager on windows 10 from UI (can be forced on settings.json file) + +### fix +- app crashing on windows 10 +- empty tray icons list on windows 10 + +## [1.7.1] +### enhancements +- separate `information` and `developer tools` tabs in the settings. +- add a option to open the install path in explorer. +- focus settings window if already exist. +- better performance on canceling changes in settings. +- avoid loading innecesary files in modules that are not used. +- update pinned apps path by filename on open (some apps change of path on updates so this will fix that). +- show empty message on toolbar when no wlan networks are found. + +### fix +- ahk error on save. + +## [1.7.0] +### features +- add Network toolbar module. +- add WLAN selector to the Network toolbar module. +- add css variable (--config-accent-color-rgb) to be used with css functions like `rgb` or `rgba`. + +### enhancements +- now placeholders, layouts and themes can be loaded from data users folder (`AppData\Roaming\com.seelen.seelen-ui`) +- now buttons and others components will use the user accent color. + +### fix +- no max size on System Tray List module. + +## [1.6.4] +### fix +- xbox games showing missing icons on SeelenWeg. + +### enhancements +- follow user accent color for tray list and windows borders + +### fix +- no showing promoted (pinned on taskbar) tray icons. +- toolbar no initialized correctly sometimes, now will retry if fails. +- battery no updating level. +- battery showing as always charging on default toolbar templates. +- tray overflow module no working on different languages. + +### refactor +- refactor on window_api and AppBar structures. + +## [1.6.3] +### enhancements +- only show a progress bar on update and not the complete installer GUI. + +### fix +- main app no running if the forced creation of tray overflow fails. + +## [1.6.2] +### features +- now `batteries` and `battery` (same as: `batteries[0]`) are available on the scope of power toolbar module. + +### enhancements +- add battery crate to handle batteries info directly from their drivers. +- show if is smart charging. +- now battery module wont be shown if batteries are not found. + +### fix +- battery showing 255%. + +## [1.6.1] +### fix +- tray icons not showing on startup +- hidden trays if icon was not found (now will show a missing icon) + +## [1.6.0] +### features +- add "Run as admin" option at context menu on Seelenweg. +- allow receive commands using TCP connections. +- Add System Tray Icons module, (incomplete, devices like usb or windows antivirus trays are still not supported). + +### enhancements +- improve power (battery) events performance. +- Window manager disabled by default to new users. + +### refactor +- remove tauri single instance plugin by TCP connection. + +## [1.5.0] +### features +- new placeholder added to the bundle as alternative to default. +- new workspace item available to be used in placeholders. + +### enhancements +- support fullscreen apps (will hide the toolbar and the weg on fullscreen an app). + +### fix +- showing incorrect format on dates at start of the app. +- complex text with icons on toolbar items cause wraps. +- missing icons on some uwp apps. + +### refactor +- refactor on window event manager to allow synthetic events. + +## [1.4.1] +### fix +- no truncating text on toolbar items overflow. +- rendering empty items on toolbar when empty placeholder is declared. + +## [1.4.0] +### features +- Modular Themes +- Themes now allow tags to be categorized. +- Allow add, organize, combine multiple themes as cascade layers. +- Themes now allow folder structure to improve developers experience. + +### refactor +- Now themes will use .yml files instead json to improve developers experience. +- Themes schema updated, no backwards compatibility with json themes. (.json in themes folder will be ignored) + +### fix +- No hiding the taskbar correctly. + +## [1.3.4] +### enhancements +- Add splash screen to Settings window. +- Add discord link on Information Section. + +### refactor +- Use TaskScheduler for autostart Seelen with priority and admin privileges. + +### fix +- bad zorder on Weg and Toolbar under the WM borders + +## [1.3.3] +### features +- Multi-monitor support for Fancy Toolbar. +- Multi-monitor support for Seelenweg. + +## [1.3.2] +### enhancements +- Remove unnecessary tooltip collision on toolbar items. + +### fix +- Crash on restoring app in other virtual desktop using Weg. +- Touch events not working on Toolbar and Weg. + +## [1.3.1] +### fix +- disable binding monitors and monitors on apps configurations for now. + +## [1.3.0] +### features +- Allow pin apps on Open using Apps Configurations. +- Allow changes Shortcuts using UI. +- Allow Binary Conditions in Apps Configurations Identifiers. +- Allow change the Auto hide behavior for Seelenweg. + +### enhancements +- Close AHK by itself if app is crashed or forcedly closed. +- Configurations by apps are enabled again. +- Allow open settings file from Extras/Information +- Add opacity to toolbar (theme: default) + +### fix +- Ahk not closing on app close or when user change options. + +## [1.2.4] +### enhancements +- Automatic MSIX bundle. +- Add Github Actions for Releases. +- Add Github Actions for Web Page. + +## [1.2.3] +### features +- Allow customize Fancy Toolbar modules using placeholders yaml files. +- Add fast settings for toolbar allowing to adjust volume, brightness, etc. + +## [1.2.2] +### enhancements +- if app on weg is cloak, change of virtual desktop instead minimize/restore + +### fix +- no closing AHK instances +- floating size on fallback +- reservation not working properly +- ignore top most windows by default (normally these are tools or widgets) +- minimization on weg not working properly if window manager is activated +- change focus using commands not working with conditional layouts +- randomly frozen app on start +- no tiling UWP apps + +## [1.2.1] +### enhancements +- Allow quit from settings +- Using Box-Content style in the position of windows instead outlined for a better user experience + +### fix +- Managing windows without caption (Title bar) +- can't update border configurations +- hiding dock on switching virtual desktops + +## [1.2.0] +### fix +- Taskbar showing instead be always hidden + +## [1.1.1] +### fix +- Bad download URL in Update Notification +- Showing update notification on installations by Windows Store + +## [1.1.0] +### features +- Add Smart Auto Hide for Seelenweg. +- Add visible Separators Option +- Enable animations for items into LEFT, TOP, RIGHT positions + +### enhancements +- Now the copy handles option will return hexadecimal handles instead decimal (good for faster debug in tools like spy++). + +### fix +- duped handles +- inconsistencies in separators width + +## [1.0.1] +### fix +- App downloaded form Microsoft Store was not running without admin. + +## [1.0.0] +### refactored +- Update notifications always enabled for nsis installer +- Update notifications will not appear if app is installed using msix (Microsoft Store). + +### enhancements +- Now by default if user is Admin, UAC will be triggered on run the app to allow a better integrated experience in SeelenWeg and Komorebi Tiling Manager. + +## [1.0.0-prerelease.14] +### features +- add indicator to know opens and focused apps on SeelenWeg +- allow set the position of seelenweg (left, top, right, bottom) 🎉 + +### enhancements +- only creates app icons the first time they are loaded + +### refactor +- change themes implementation to allow customs css files + +### fix +- incorrect icon for UWP (was using store icon instead taskbar icon) +- replacing icons on each load +- showing logs of opened apps on development +- offset margins working like windows RECT instead like one side margins + +## [1.0.0-prerelease.13] +### features +- add Themes Feature 🎉 (incomplete only for Seelenweg for now) +- add SeelenWeg (a Dock or Taskbar) beta feature +- add SeelenWeg in to Settings +- add ContextMenu for apps in SeelenWeg +- allow move apps in the Weg 😄 +- add Grouped Apps in one item +- live reload of Apps on events like change of title +- UWP apps support + +### enhancements +- move readme blob to documentation/images + +## [1.0.0-prerelease.12] +### enhancements +- add some traces on functions to save logs + +### fix +- clean installation of komorebi no working + +## [1.0.0-prerelease.11] +### refactor +- little improvements on background code + +### fix +- initial users can not save the settings + +## [1.0.0-prerelease.10] +### features +- add a update tab to allow users decide if will receive notifications for updates + +## [1.0.0-prerelease.9] +## [1.0.0-prerelease.8] +- add functionality to pause btn on tray menu + +## [1.0.0-prerelease.6] +### added +- Enable Updater 🎉 + +## [1.0.0-prerelease.3] +### fix +- icon not showing on tray +- poor icon quality on task bar +- StartUp running bad exe file + +## [1.0.0-prerelease.2] +## [1.0.0-prerelease.1] +### added +- implement tray icon + +### refactored +- Migrate all app background from Electron ⚡ to Tauri 🦀 +- reimplement startup to use native system startup +- reimplement included shortcuts with ahk +- reimplement komorebi autostart +- reimplement installer to use NSIS +- refactor folder structure to isolate front-end apps + +## [1.0.0-beta.13] +### enhancements +- improve maximized windows experience + +### fixed +- fix resize not working (now works like master) + +## [1.0.0-beta.12] +### added +- show current used versions on information +- add grid layout preview +- add win + k to open komorebi settings + +### refactored +- update komorebi to 0.1.22 + +### removed +- remove invisible borders feature + +## [1.0.0-beta.11] +### fixed +- missing property on schema +- white screen on start app + +## [1.0.0-beta.10] +### added +- add a new way to match applications by path + +### fixed +- searching feature on apps +- no focusing windows on change workspace +- autostacking not working properly +- workspaces rules not working + +## [1.0.0-beta.9] +### added +- add popups on actions 🦀 +- now can switch from installed and packaged and should work as the same + +### fixed +- fix no removing old path +- lag on many applications + +## [1.0.0-beta.8] +### added +- add more templates + +## [1.0.0-beta.7] +### fixed +- fix first install + +## [1.0.0-beta.6] +### added +- delete old paths on update + +### fixed +- fix not saving templates +- fix toggle ahk shortcuts does not run or stop the instance +- running ahk when disabled +- not updating the path of installation folder on update for windows tasks + +## [1.0.0-beta.5] +### added +- new searching option for applications +- templates feature + +### fixed +- including ghost apps on migration + +## [1.0.0-beta.4] +### added +- new feature of invisible borders per app +- new easy way to hard restart the services and AHK + +### changed +- delete border overflow and changed for invisible borders per app + +### fixed +- components was not triggering dark mode correctly + +## [1.0.0-beta.3] +### added +- new apps templates +- add AHK as a dependency to show to new users +- add AHK settings + +## [1.0.0-beta.2] +### added +- export option for apps + +### fixed +- delete bound monitor and workspace on an application - bad installation on setup \ No newline at end of file diff --git a/documentation/images/logo.svg b/documentation/images/logo.svg index dbf78f7a..90d69197 100644 --- a/documentation/images/logo.svg +++ b/documentation/images/logo.svg @@ -1,14 +1,14 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/documentation/privacy policy.md b/documentation/privacy policy.md index 9adacede..49b32180 100644 --- a/documentation/privacy policy.md +++ b/documentation/privacy policy.md @@ -1,76 +1,76 @@ -# PRIVACY POLICY -Last updated April 04, 2024 - -This privacy notice for Seelen ("we," "us," or "our"), describes how and why we might collect, store, use, and/or share ("process") your information when you use our services ("Services"), such as when you: - -* Download and use our desktop application (Seelen UI), or any other application of ours that links to this privacy notice - -* Engage with us in other related ways, including any sales, marketing, or events - -Questions or concerns? Reading this privacy notice will help you understand your privacy rights and choices. If you do not agree with our policies and practices, please do not use our Services. - -## SUMMARY OF KEY POINTS -This summary provides key points from our privacy notice, but you can find out more details about any of these topics by clicking the link following each key point or by using our table of contents below to find the section you are looking for. - -What personal information do we process? When you visit, use, or navigate our Services, we may process personal information depending on how you interact with us and the Services, the choices you make, and the products and features you use. Learn more about personal information you disclose to us. - -Do we process any sensitive personal information? We do not process sensitive personal information. -Do we receive any information from third parties? We do not receive any information from third parties. -How do we process your information? We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent. We process your information only when we have a valid legal reason to do so. Learn more about how we process your information. -In what situations and with which parties do we share personal information? We may share information in specific situations and with specific third parties. Learn more about when and with whom we share your personal information. -What are your rights? Depending on where you are located geographically, the applicable privacy law may mean you have certain rights regarding your personal information. Learn more about your privacy rights. -How do you exercise your rights? The easiest way to exercise your rights is by submitting a data subject access request, or by contacting us. We will consider and act upon any request in accordance with applicable data protection laws. -Want to learn more about what we do with any information we collect? Review the privacy notice in full. - -## TABLE OF CONTENTS -1. WHAT INFORMATION DO WE COLLECT? -2. HOW DO WE PROCESS YOUR INFORMATION? -3. WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION? -4. HOW LONG DO WE KEEP YOUR INFORMATION? -5. WHAT ARE YOUR PRIVACY RIGHTS? -6. CONTROLS FOR DO-NOT-TRACK FEATURES -7. DO WE MAKE UPDATES TO THIS NOTICE? -8. HOW CAN YOU CONTACT US ABOUT THIS NOTICE? -9. HOW CAN YOU REVIEW, UPDATE, OR DELETE THE DATA WE COLLECT FROM YOU? - -## 1. WHAT INFORMATION DO WE COLLECT? -Personal information you disclose to us -In Short: We collect personal information that you provide to us. -We collect personal information that you voluntarily provide to us when you express an interest in obtaining information about us or our products and Services, when you participate in activities on the Services, or otherwise when you contact us. -Sensitive Information. We do not process sensitive information. -All personal information that you provide to us must be true, complete, and accurate, and you must notify us of any changes to such personal information. - -## 2. HOW DO WE PROCESS YOUR INFORMATION? -In Short: We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent. -We process your personal information for a variety of reasons, depending on how you interact with our Services, including: -* resolutions of bugs - -## 3. WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION? -In Short: We may share information in specific situations described in this section and/or with the following third parties. -We may need to share your personal information in the following situations: - - Business Transfers. We may share or transfer your information in connection with, or during negotiations of, any merger, sale of company assets, financing, or acquisition of all or a portion of our business to another company. - -## 4. HOW LONG DO WE KEEP YOUR INFORMATION? -In Short: We keep your information for as long as necessary to fulfill the purposes outlined in this privacy notice unless otherwise required by law. -We will only keep your personal information for as long as it is necessary for the purposes set out in this privacy notice, unless a longer retention period is required or permitted by law (such as tax, accounting, or other legal requirements). -When we have no ongoing legitimate business need to process your personal information, we will either delete or anonymize such information, or, if this is not possible (for example, because your personal information has been stored in backup archives), then we will securely store your personal information and isolate it from any further processing until deletion is possible. - -## 5. WHAT ARE YOUR PRIVACY RIGHTS? -In Short: You may review, change, or terminate your account at any time. -Withdrawing your consent: If we are relying on your consent to process your personal information, which may be express and/or implied consent depending on the applicable law, you have the right to withdraw your consent at any time. You can withdraw your consent at any time by contacting us by using the contact details provided in the section "HOW CAN YOU CONTACT US ABOUT THIS NOTICE?" below. -However, please note that this will not affect the lawfulness of the processing before its withdrawal nor, when applicable law allows, will it affect the processing of your personal information conducted in reliance on lawful processing grounds other than consent. - -## 6. CONTROLS FOR DO-NOT-TRACK FEATURES -Most web browsers and some mobile operating systems and mobile applications include a Do-Not-Track ("DNT") feature or setting you can activate to signal your privacy preference not to have data about your online browsing activities monitored and collected. At this stage no uniform technology standard for recognizing and implementing DNT signals has been finalized. As such, we do not currently respond to DNT browser signals or any other mechanism that automatically communicates your choice not to be tracked online. If a standard for online tracking is adopted that we must follow in the future, we will inform you about that practice in a revised version of this privacy notice. - -## 7. DO WE MAKE UPDATES TO THIS NOTICE? -In Short: Yes, we will update this notice as necessary to stay compliant with relevant laws. -We may update this privacy notice from time to time. The updated version will be indicated by an updated "Revised" date and the updated version will be effective as soon as it is accessible. If we make material changes to this privacy notice, we may notify you either by prominently posting a notice of such changes or by directly sending you a notification. We encourage you to review this privacy notice frequently to be informed of how we are protecting your information. - -## 8. HOW CAN YOU CONTACT US ABOUT THIS NOTICE? -If you have questions or comments about this notice, you may email us at eythan.cvt@gmail.com or contact us by post at: -Seelen -__________ -Guayaquil, Guayas +# PRIVACY POLICY +Last updated April 04, 2024 + +This privacy notice for Seelen ("we," "us," or "our"), describes how and why we might collect, store, use, and/or share ("process") your information when you use our services ("Services"), such as when you: + +* Download and use our desktop application (Seelen UI), or any other application of ours that links to this privacy notice + +* Engage with us in other related ways, including any sales, marketing, or events + +Questions or concerns? Reading this privacy notice will help you understand your privacy rights and choices. If you do not agree with our policies and practices, please do not use our Services. + +## SUMMARY OF KEY POINTS +This summary provides key points from our privacy notice, but you can find out more details about any of these topics by clicking the link following each key point or by using our table of contents below to find the section you are looking for. + +What personal information do we process? When you visit, use, or navigate our Services, we may process personal information depending on how you interact with us and the Services, the choices you make, and the products and features you use. Learn more about personal information you disclose to us. + +Do we process any sensitive personal information? We do not process sensitive personal information. +Do we receive any information from third parties? We do not receive any information from third parties. +How do we process your information? We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent. We process your information only when we have a valid legal reason to do so. Learn more about how we process your information. +In what situations and with which parties do we share personal information? We may share information in specific situations and with specific third parties. Learn more about when and with whom we share your personal information. +What are your rights? Depending on where you are located geographically, the applicable privacy law may mean you have certain rights regarding your personal information. Learn more about your privacy rights. +How do you exercise your rights? The easiest way to exercise your rights is by submitting a data subject access request, or by contacting us. We will consider and act upon any request in accordance with applicable data protection laws. +Want to learn more about what we do with any information we collect? Review the privacy notice in full. + +## TABLE OF CONTENTS +1. WHAT INFORMATION DO WE COLLECT? +2. HOW DO WE PROCESS YOUR INFORMATION? +3. WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION? +4. HOW LONG DO WE KEEP YOUR INFORMATION? +5. WHAT ARE YOUR PRIVACY RIGHTS? +6. CONTROLS FOR DO-NOT-TRACK FEATURES +7. DO WE MAKE UPDATES TO THIS NOTICE? +8. HOW CAN YOU CONTACT US ABOUT THIS NOTICE? +9. HOW CAN YOU REVIEW, UPDATE, OR DELETE THE DATA WE COLLECT FROM YOU? + +## 1. WHAT INFORMATION DO WE COLLECT? +Personal information you disclose to us +In Short: We collect personal information that you provide to us. +We collect personal information that you voluntarily provide to us when you express an interest in obtaining information about us or our products and Services, when you participate in activities on the Services, or otherwise when you contact us. +Sensitive Information. We do not process sensitive information. +All personal information that you provide to us must be true, complete, and accurate, and you must notify us of any changes to such personal information. + +## 2. HOW DO WE PROCESS YOUR INFORMATION? +In Short: We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent. +We process your personal information for a variety of reasons, depending on how you interact with our Services, including: +* resolutions of bugs + +## 3. WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION? +In Short: We may share information in specific situations described in this section and/or with the following third parties. +We may need to share your personal information in the following situations: + + Business Transfers. We may share or transfer your information in connection with, or during negotiations of, any merger, sale of company assets, financing, or acquisition of all or a portion of our business to another company. + +## 4. HOW LONG DO WE KEEP YOUR INFORMATION? +In Short: We keep your information for as long as necessary to fulfill the purposes outlined in this privacy notice unless otherwise required by law. +We will only keep your personal information for as long as it is necessary for the purposes set out in this privacy notice, unless a longer retention period is required or permitted by law (such as tax, accounting, or other legal requirements). +When we have no ongoing legitimate business need to process your personal information, we will either delete or anonymize such information, or, if this is not possible (for example, because your personal information has been stored in backup archives), then we will securely store your personal information and isolate it from any further processing until deletion is possible. + +## 5. WHAT ARE YOUR PRIVACY RIGHTS? +In Short: You may review, change, or terminate your account at any time. +Withdrawing your consent: If we are relying on your consent to process your personal information, which may be express and/or implied consent depending on the applicable law, you have the right to withdraw your consent at any time. You can withdraw your consent at any time by contacting us by using the contact details provided in the section "HOW CAN YOU CONTACT US ABOUT THIS NOTICE?" below. +However, please note that this will not affect the lawfulness of the processing before its withdrawal nor, when applicable law allows, will it affect the processing of your personal information conducted in reliance on lawful processing grounds other than consent. + +## 6. CONTROLS FOR DO-NOT-TRACK FEATURES +Most web browsers and some mobile operating systems and mobile applications include a Do-Not-Track ("DNT") feature or setting you can activate to signal your privacy preference not to have data about your online browsing activities monitored and collected. At this stage no uniform technology standard for recognizing and implementing DNT signals has been finalized. As such, we do not currently respond to DNT browser signals or any other mechanism that automatically communicates your choice not to be tracked online. If a standard for online tracking is adopted that we must follow in the future, we will inform you about that practice in a revised version of this privacy notice. + +## 7. DO WE MAKE UPDATES TO THIS NOTICE? +In Short: Yes, we will update this notice as necessary to stay compliant with relevant laws. +We may update this privacy notice from time to time. The updated version will be indicated by an updated "Revised" date and the updated version will be effective as soon as it is accessible. If we make material changes to this privacy notice, we may notify you either by prominently posting a notice of such changes or by directly sending you a notification. We encourage you to review this privacy notice frequently to be informed of how we are protecting your information. + +## 8. HOW CAN YOU CONTACT US ABOUT THIS NOTICE? +If you have questions or comments about this notice, you may email us at eythan.cvt@gmail.com or contact us by post at: +Seelen +__________ +Guayaquil, Guayas Ecuador \ No newline at end of file diff --git a/documentation/project.md b/documentation/project.md index f4e598e8..89988798 100644 --- a/documentation/project.md +++ b/documentation/project.md @@ -1,34 +1,34 @@ -# Welcome to the Seelen UI Project - -Welcome to the Seelen UI project! This guide will help you get started with the codebase and understand its structure. - -## Languages Used -This project utilizes the following languages: -- **Rust** -- **TypeScript** -- **PowerShell** (in special cases) - -## Getting Started -To run this project, follow these steps: - -1. [Install Rust](https://www.rust-lang.org/tools/install). -2. Run the following commands: - -```bash -npm install && npm run dev -``` - -This will set up the project similarly to any other Node.js project, with the added step of installing Rust first. - -## Architecture - -### Views Architecture - -The `src\apps` folder contains views that follow Hexagonal Architecture. Each folder in `src\apps` represents a view (excluding shared). These views are independent web pages bundled with `esbuild`. While any technology or library can be used in a view, most are based on `React` and `Redux`. - -#### Shared Folder -Following Hexagonal Architecture, the `shared` folder contains utilities, schemas, and other shared resources used across multiple views. - -### Background Architecture - +# Welcome to the Seelen UI Project + +Welcome to the Seelen UI project! This guide will help you get started with the codebase and understand its structure. + +## Languages Used +This project utilizes the following languages: +- **Rust** +- **TypeScript** +- **PowerShell** (in special cases) + +## Getting Started +To run this project, follow these steps: + +1. [Install Rust](https://www.rust-lang.org/tools/install). +2. Run the following commands: + +```bash +npm install && npm run dev +``` + +This will set up the project similarly to any other Node.js project, with the added step of installing Rust first. + +## Architecture + +### Views Architecture + +The `src\apps` folder contains views that follow Hexagonal Architecture. Each folder in `src\apps` represents a view (excluding shared). These views are independent web pages bundled with `esbuild`. While any technology or library can be used in a view, most are based on `React` and `Redux`. + +#### Shared Folder +Following Hexagonal Architecture, the `shared` folder contains utilities, schemas, and other shared resources used across multiple views. + +### Background Architecture + The `src\background` folder does not follow a specific architecture but is based on Events Architecture. \ No newline at end of file diff --git a/documentation/schemas/layout.schema.json b/documentation/schemas/layout.schema.json index 3593f323..c57419a9 100644 --- a/documentation/schemas/layout.schema.json +++ b/documentation/schemas/layout.schema.json @@ -1,275 +1,275 @@ -{ - "type": "object", - "properties": { - "info": { - "type": "object", - "properties": { - "displayName": { - "type": "string", - "default": "Unknown" - }, - "author": { - "type": "string", - "default": "Unknown" - }, - "description": { - "type": "string", - "default": "Empty" - } - }, - "additionalProperties": false, - "default": {} - }, - "structure": { - "anyOf": [ - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "Stack" - }, - "subtype": { - "type": "string", - "enum": [ - "Temporal", - "Permanent" - ], - "default": "Permanent" - }, - "priority": { - "type": "number", - "exclusiveMinimum": 0, - "description": "Order in how the tree will be traversed (1 = first, 2 = second, etc.)", - "default": 1 - }, - "growFactor": { - "type": "number", - "description": "How much of the remaining space this node will take", - "default": 1 - }, - "condition": { - "anyOf": [ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "string" - } - ] - }, - { - "type": "null" - } - ], - "description": "Math Condition for the node to be shown, e.g: n >= 3" - }, - "active": { - "anyOf": [ - { - "type": "number", - "minimum": 0, - "description": "Window handle" - }, - { - "type": "null" - } - ], - "description": "Window handle", - "default": null - }, - "handles": { - "type": "array", - "items": { - "$ref": "#/properties/structure/anyOf/0/properties/active/anyOf/0" - }, - "default": [] - } - }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "Fallback" - }, - "subtype": { - "type": "string", - "const": "Permanent", - "default": "Permanent" - }, - "priority": { - "$ref": "#/properties/structure/anyOf/0/properties/priority" - }, - "growFactor": { - "$ref": "#/properties/structure/anyOf/0/properties/growFactor" - }, - "condition": { - "$ref": "#/properties/structure/anyOf/0/properties/condition" - }, - "active": { - "anyOf": [ - { - "$ref": "#/properties/structure/anyOf/0/properties/active/anyOf/0" - }, - { - "type": "null" - } - ], - "description": "Window handle", - "default": null - }, - "handles": { - "type": "array", - "items": { - "$ref": "#/properties/structure/anyOf/0/properties/active/anyOf/0" - }, - "default": [] - } - }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "Leaf" - }, - "subtype": { - "$ref": "#/properties/structure/anyOf/0/properties/subtype" - }, - "priority": { - "$ref": "#/properties/structure/anyOf/0/properties/priority" - }, - "growFactor": { - "$ref": "#/properties/structure/anyOf/0/properties/growFactor" - }, - "condition": { - "$ref": "#/properties/structure/anyOf/0/properties/condition" - }, - "handle": { - "anyOf": [ - { - "$ref": "#/properties/structure/anyOf/0/properties/active/anyOf/0" - }, - { - "type": "null" - } - ], - "description": "Window handle", - "default": null - } - }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "Horizontal" - }, - "subtype": { - "$ref": "#/properties/structure/anyOf/0/properties/subtype" - }, - "priority": { - "$ref": "#/properties/structure/anyOf/0/properties/priority" - }, - "growFactor": { - "$ref": "#/properties/structure/anyOf/0/properties/growFactor" - }, - "condition": { - "$ref": "#/properties/structure/anyOf/0/properties/condition" - }, - "children": { - "type": "array", - "items": { - "$ref": "#/properties/structure" - }, - "minItems": 1 - } - }, - "required": [ - "type", - "children" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "Vertical" - }, - "subtype": { - "$ref": "#/properties/structure/anyOf/0/properties/subtype" - }, - "priority": { - "$ref": "#/properties/structure/anyOf/0/properties/priority" - }, - "growFactor": { - "$ref": "#/properties/structure/anyOf/0/properties/growFactor" - }, - "condition": { - "$ref": "#/properties/structure/anyOf/0/properties/condition" - }, - "children": { - "type": "array", - "items": { - "$ref": "#/properties/structure" - }, - "minItems": 1 - } - }, - "required": [ - "type", - "children" - ], - "additionalProperties": false - } - ], - "description": "The layout tree", - "default": { - "type": "Fallback" - } - }, - "no_fallback_behavior": { - "anyOf": [ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "string", - "enum": [ - "Float", - "Unmanaged" - ] - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" +{ + "type": "object", + "properties": { + "info": { + "type": "object", + "properties": { + "displayName": { + "type": "string", + "default": "Unknown" + }, + "author": { + "type": "string", + "default": "Unknown" + }, + "description": { + "type": "string", + "default": "Empty" + } + }, + "additionalProperties": false, + "default": {} + }, + "structure": { + "anyOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "Stack" + }, + "subtype": { + "type": "string", + "enum": [ + "Temporal", + "Permanent" + ], + "default": "Permanent" + }, + "priority": { + "type": "number", + "exclusiveMinimum": 0, + "description": "Order in how the tree will be traversed (1 = first, 2 = second, etc.)", + "default": 1 + }, + "growFactor": { + "type": "number", + "description": "How much of the remaining space this node will take", + "default": 1 + }, + "condition": { + "anyOf": [ + { + "anyOf": [ + { + "not": {} + }, + { + "type": "string" + } + ] + }, + { + "type": "null" + } + ], + "description": "Math Condition for the node to be shown, e.g: n >= 3" + }, + "active": { + "anyOf": [ + { + "type": "number", + "minimum": 0, + "description": "Window handle" + }, + { + "type": "null" + } + ], + "description": "Window handle", + "default": null + }, + "handles": { + "type": "array", + "items": { + "$ref": "#/properties/structure/anyOf/0/properties/active/anyOf/0" + }, + "default": [] + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "Fallback" + }, + "subtype": { + "type": "string", + "const": "Permanent", + "default": "Permanent" + }, + "priority": { + "$ref": "#/properties/structure/anyOf/0/properties/priority" + }, + "growFactor": { + "$ref": "#/properties/structure/anyOf/0/properties/growFactor" + }, + "condition": { + "$ref": "#/properties/structure/anyOf/0/properties/condition" + }, + "active": { + "anyOf": [ + { + "$ref": "#/properties/structure/anyOf/0/properties/active/anyOf/0" + }, + { + "type": "null" + } + ], + "description": "Window handle", + "default": null + }, + "handles": { + "type": "array", + "items": { + "$ref": "#/properties/structure/anyOf/0/properties/active/anyOf/0" + }, + "default": [] + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "Leaf" + }, + "subtype": { + "$ref": "#/properties/structure/anyOf/0/properties/subtype" + }, + "priority": { + "$ref": "#/properties/structure/anyOf/0/properties/priority" + }, + "growFactor": { + "$ref": "#/properties/structure/anyOf/0/properties/growFactor" + }, + "condition": { + "$ref": "#/properties/structure/anyOf/0/properties/condition" + }, + "handle": { + "anyOf": [ + { + "$ref": "#/properties/structure/anyOf/0/properties/active/anyOf/0" + }, + { + "type": "null" + } + ], + "description": "Window handle", + "default": null + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "Horizontal" + }, + "subtype": { + "$ref": "#/properties/structure/anyOf/0/properties/subtype" + }, + "priority": { + "$ref": "#/properties/structure/anyOf/0/properties/priority" + }, + "growFactor": { + "$ref": "#/properties/structure/anyOf/0/properties/growFactor" + }, + "condition": { + "$ref": "#/properties/structure/anyOf/0/properties/condition" + }, + "children": { + "type": "array", + "items": { + "$ref": "#/properties/structure" + }, + "minItems": 1 + } + }, + "required": [ + "type", + "children" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "Vertical" + }, + "subtype": { + "$ref": "#/properties/structure/anyOf/0/properties/subtype" + }, + "priority": { + "$ref": "#/properties/structure/anyOf/0/properties/priority" + }, + "growFactor": { + "$ref": "#/properties/structure/anyOf/0/properties/growFactor" + }, + "condition": { + "$ref": "#/properties/structure/anyOf/0/properties/condition" + }, + "children": { + "type": "array", + "items": { + "$ref": "#/properties/structure" + }, + "minItems": 1 + } + }, + "required": [ + "type", + "children" + ], + "additionalProperties": false + } + ], + "description": "The layout tree", + "default": { + "type": "Fallback" + } + }, + "no_fallback_behavior": { + "anyOf": [ + { + "anyOf": [ + { + "not": {} + }, + { + "type": "string", + "enum": [ + "Float", + "Unmanaged" + ] + } + ] + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/documentation/schemas/placeholder.schema.json b/documentation/schemas/placeholder.schema.json index 01fe1cb6..d956321f 100644 --- a/documentation/schemas/placeholder.schema.json +++ b/documentation/schemas/placeholder.schema.json @@ -1,348 +1,348 @@ -{ - "type": "object", - "properties": { - "info": { - "type": "object", - "properties": { - "displayName": { - "type": "string", - "default": "Unknown" - }, - "author": { - "type": "string", - "default": "Unknown" - }, - "description": { - "type": "string", - "default": "Empty" - } - }, - "additionalProperties": false, - "default": {} - }, - "left": { - "type": "array", - "items": { - "anyOf": [ - { - "type": "object", - "properties": { - "id": { - "type": "string", - "default": "e0113b78-2a87-4706-b69c-d565384ab101" - }, - "type": { - "type": "string", - "enum": [ - "generic", - "text" - ] - }, - "template": { - "type": "string", - "default": "\"Unset\"" - }, - "tooltip": { - "type": [ - "string", - "null" - ], - "default": null - }, - "onClick": { - "type": [ - "string", - "null" - ], - "default": null - }, - "style": { - "type": "object", - "additionalProperties": {}, - "default": {} - } - }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "date" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" - }, - "each": { - "type": "string", - "enum": [ - "second", - "minute", - "hour", - "day" - ], - "description": "Time unit to update the showing date", - "default": "minute" - }, - "format": { - "type": "string", - "default": "MMM Do, HH:mm" - } - }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "power" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" - } - }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "settings" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" - } - }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "workspaces" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" - }, - "mode": { - "type": "string", - "enum": [ - "dotted", - "named", - "numbered" - ], - "default": "numbered" - } - }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "tray" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" - } - }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "network" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" - }, - "withWlanSelector": { - "type": "boolean", - "description": "Show Wi-fi settings on click (overrides onClick property)", - "default": false - } - }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "media" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" - }, - "withMediaControls": { - "type": "boolean", - "default": false - } - }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "id": { - "$ref": "#/properties/left/items/anyOf/0/properties/id" - }, - "type": { - "type": "string", - "const": "device" - }, - "template": { - "$ref": "#/properties/left/items/anyOf/0/properties/template" - }, - "tooltip": { - "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" - }, - "onClick": { - "$ref": "#/properties/left/items/anyOf/0/properties/onClick" - }, - "style": { - "$ref": "#/properties/left/items/anyOf/0/properties/style" - } - }, - "required": [ - "type" - ], - "additionalProperties": false - } - ] - }, - "default": [] - }, - "center": { - "type": "array", - "items": { - "$ref": "#/properties/left/items" - }, - "default": [] - }, - "right": { - "type": "array", - "items": { - "$ref": "#/properties/left/items" - }, - "default": [] - } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" +{ + "type": "object", + "properties": { + "info": { + "type": "object", + "properties": { + "displayName": { + "type": "string", + "default": "Unknown" + }, + "author": { + "type": "string", + "default": "Unknown" + }, + "description": { + "type": "string", + "default": "Empty" + } + }, + "additionalProperties": false, + "default": {} + }, + "left": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "id": { + "type": "string", + "default": "e0113b78-2a87-4706-b69c-d565384ab101" + }, + "type": { + "type": "string", + "enum": [ + "generic", + "text" + ] + }, + "template": { + "type": "string", + "default": "\"Unset\"" + }, + "tooltip": { + "type": [ + "string", + "null" + ], + "default": null + }, + "onClick": { + "type": [ + "string", + "null" + ], + "default": null + }, + "style": { + "type": "object", + "additionalProperties": {}, + "default": {} + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "id": { + "$ref": "#/properties/left/items/anyOf/0/properties/id" + }, + "type": { + "type": "string", + "const": "date" + }, + "template": { + "$ref": "#/properties/left/items/anyOf/0/properties/template" + }, + "tooltip": { + "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" + }, + "onClick": { + "$ref": "#/properties/left/items/anyOf/0/properties/onClick" + }, + "style": { + "$ref": "#/properties/left/items/anyOf/0/properties/style" + }, + "each": { + "type": "string", + "enum": [ + "second", + "minute", + "hour", + "day" + ], + "description": "Time unit to update the showing date", + "default": "minute" + }, + "format": { + "type": "string", + "default": "MMM Do, HH:mm" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "id": { + "$ref": "#/properties/left/items/anyOf/0/properties/id" + }, + "type": { + "type": "string", + "const": "power" + }, + "template": { + "$ref": "#/properties/left/items/anyOf/0/properties/template" + }, + "tooltip": { + "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" + }, + "onClick": { + "$ref": "#/properties/left/items/anyOf/0/properties/onClick" + }, + "style": { + "$ref": "#/properties/left/items/anyOf/0/properties/style" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "id": { + "$ref": "#/properties/left/items/anyOf/0/properties/id" + }, + "type": { + "type": "string", + "const": "settings" + }, + "template": { + "$ref": "#/properties/left/items/anyOf/0/properties/template" + }, + "tooltip": { + "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" + }, + "onClick": { + "$ref": "#/properties/left/items/anyOf/0/properties/onClick" + }, + "style": { + "$ref": "#/properties/left/items/anyOf/0/properties/style" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "id": { + "$ref": "#/properties/left/items/anyOf/0/properties/id" + }, + "type": { + "type": "string", + "const": "workspaces" + }, + "template": { + "$ref": "#/properties/left/items/anyOf/0/properties/template" + }, + "tooltip": { + "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" + }, + "onClick": { + "$ref": "#/properties/left/items/anyOf/0/properties/onClick" + }, + "style": { + "$ref": "#/properties/left/items/anyOf/0/properties/style" + }, + "mode": { + "type": "string", + "enum": [ + "dotted", + "named", + "numbered" + ], + "default": "numbered" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "id": { + "$ref": "#/properties/left/items/anyOf/0/properties/id" + }, + "type": { + "type": "string", + "const": "tray" + }, + "template": { + "$ref": "#/properties/left/items/anyOf/0/properties/template" + }, + "tooltip": { + "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" + }, + "onClick": { + "$ref": "#/properties/left/items/anyOf/0/properties/onClick" + }, + "style": { + "$ref": "#/properties/left/items/anyOf/0/properties/style" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "id": { + "$ref": "#/properties/left/items/anyOf/0/properties/id" + }, + "type": { + "type": "string", + "const": "network" + }, + "template": { + "$ref": "#/properties/left/items/anyOf/0/properties/template" + }, + "tooltip": { + "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" + }, + "onClick": { + "$ref": "#/properties/left/items/anyOf/0/properties/onClick" + }, + "style": { + "$ref": "#/properties/left/items/anyOf/0/properties/style" + }, + "withWlanSelector": { + "type": "boolean", + "description": "Show Wi-fi settings on click (overrides onClick property)", + "default": false + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "id": { + "$ref": "#/properties/left/items/anyOf/0/properties/id" + }, + "type": { + "type": "string", + "const": "media" + }, + "template": { + "$ref": "#/properties/left/items/anyOf/0/properties/template" + }, + "tooltip": { + "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" + }, + "onClick": { + "$ref": "#/properties/left/items/anyOf/0/properties/onClick" + }, + "style": { + "$ref": "#/properties/left/items/anyOf/0/properties/style" + }, + "withMediaControls": { + "type": "boolean", + "default": false + } + }, + "required": [ + "type" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "id": { + "$ref": "#/properties/left/items/anyOf/0/properties/id" + }, + "type": { + "type": "string", + "const": "device" + }, + "template": { + "$ref": "#/properties/left/items/anyOf/0/properties/template" + }, + "tooltip": { + "$ref": "#/properties/left/items/anyOf/0/properties/tooltip" + }, + "onClick": { + "$ref": "#/properties/left/items/anyOf/0/properties/onClick" + }, + "style": { + "$ref": "#/properties/left/items/anyOf/0/properties/style" + } + }, + "required": [ + "type" + ], + "additionalProperties": false + } + ] + }, + "default": [] + }, + "center": { + "type": "array", + "items": { + "$ref": "#/properties/left/items" + }, + "default": [] + }, + "right": { + "type": "array", + "items": { + "$ref": "#/properties/left/items" + }, + "default": [] + } + }, + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/documentation/schemas/settings.schema.json b/documentation/schemas/settings.schema.json index 596e8a29..e504c8ee 100644 --- a/documentation/schemas/settings.schema.json +++ b/documentation/schemas/settings.schema.json @@ -1,673 +1,673 @@ -{ - "type": "object", - "properties": { - "fancy_toolbar": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": true - }, - "height": { - "type": "number", - "exclusiveMinimum": 0, - "default": 30 - }, - "placeholder": { - "type": [ - "string", - "null" - ], - "default": null - } - }, - "additionalProperties": false, - "default": {} - }, - "seelenweg": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": true - }, - "mode": { - "type": "string", - "enum": [ - "Full-Width", - "Min-Content" - ], - "default": "Min-Content" - }, - "hide_mode": { - "type": "string", - "enum": [ - "Never", - "Always", - "On-Overlap" - ], - "default": "On-Overlap" - }, - "position": { - "type": "string", - "enum": [ - "Left", - "Right", - "Top", - "Bottom" - ], - "default": "Bottom" - }, - "visible_separators": { - "type": "boolean", - "default": true - }, - "size": { - "type": "number", - "exclusiveMinimum": 0, - "default": 40, - "description": "Item size in pixels" - }, - "zoom_size": { - "type": "number", - "exclusiveMinimum": 0, - "default": 70, - "description": "Zoomed item size in pixels" - }, - "margin": { - "type": "number", - "minimum": 0, - "default": 8, - "description": "Dock/Bar margin in pixels" - }, - "padding": { - "type": "number", - "minimum": 0, - "default": 8, - "description": "Dock/Bar padding in pixels" - }, - "space_between_items": { - "type": "number", - "minimum": 0, - "default": 8, - "description": "Space between items (gap) in pixels" - } - }, - "additionalProperties": false, - "default": {} - }, - "window_manager": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": false - }, - "auto_stacking_by_category": { - "type": "boolean", - "default": true - }, - "border": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": true - }, - "width": { - "type": "number", - "minimum": 0, - "default": 3 - }, - "offset": { - "type": "number", - "default": -1 - } - }, - "additionalProperties": false, - "default": {} - }, - "resize_delta": { - "type": "number", - "default": 10, - "description": "% to add or remove on resize of windows using the CLI" - }, - "workspace_gap": { - "type": "number", - "minimum": 0, - "default": 10, - "description": "Space between windows" - }, - "workspace_padding": { - "type": "number", - "minimum": 0, - "default": 10 - }, - "global_work_area_offset": { - "type": "object", - "properties": { - "top": { - "type": "number", - "default": 0 - }, - "left": { - "type": "number", - "default": 0 - }, - "right": { - "type": "number", - "default": 0 - }, - "bottom": { - "type": "number", - "default": 0 - } - }, - "additionalProperties": false, - "default": {} - }, - "floating": { - "type": "object", - "properties": { - "width": { - "type": "number", - "exclusiveMinimum": 0, - "default": 800 - }, - "height": { - "type": "number", - "exclusiveMinimum": 0, - "default": 500 - } - }, - "additionalProperties": false, - "default": {} - }, - "default_layout": { - "type": [ - "string", - "null" - ], - "default": null - } - }, - "additionalProperties": false, - "default": {} - }, - "monitors": { - "type": "array", - "items": { - "type": "object", - "properties": { - "workspaces": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "default": "New Workspace" - }, - "layout": { - "type": "string", - "default": "BSP" - }, - "padding": { - "anyOf": [ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "number", - "minimum": 0 - } - ] - }, - { - "type": "null" - } - ] - }, - "gap": { - "anyOf": [ - { - "anyOf": [ - { - "not": {} - }, - { - "type": "number", - "minimum": 0 - } - ] - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "minItems": 1, - "default": [ - { - "name": "New Workspace", - "layout": "BSP" - } - ] - }, - "work_area_offset": { - "anyOf": [ - { - "anyOf": [ - { - "not": {} - }, - { - "$ref": "#/properties/window_manager/properties/global_work_area_offset" - } - ] - }, - { - "type": "null" - } - ] - }, - "editing_workspace": { - "type": "number", - "minimum": 0, - "default": 0 - } - }, - "additionalProperties": false - }, - "minItems": 1, - "default": [ - { - "workspaces": [ - { - "name": "New Workspace", - "layout": "BSP" - } - ], - "editing_workspace": 0 - } - ] - }, - "ahk_enabled": { - "type": "boolean", - "default": true - }, - "ahk_variables": { - "type": "object", - "properties": { - "reserve_top": { - "type": "object", - "properties": { - "fancy": { - "type": "string" - }, - "ahk": { - "type": "string" - } - }, - "required": [ - "fancy", - "ahk" - ], - "additionalProperties": false, - "default": { - "fancy": "Win + Shift + I", - "ahk": "#+i" - } - }, - "reserve_bottom": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + K", - "ahk": "#+k" - } - }, - "reserve_left": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + J", - "ahk": "#+j" - } - }, - "reserve_right": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + L", - "ahk": "#+l" - } - }, - "reserve_float": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + U", - "ahk": "#+u" - } - }, - "reserve_stack": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + O", - "ahk": "#+o" - } - }, - "focus_top": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + W", - "ahk": "#+w" - } - }, - "focus_bottom": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + S", - "ahk": "#+s" - } - }, - "focus_left": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + A", - "ahk": "#+a" - } - }, - "focus_right": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + D", - "ahk": "#+d" - } - }, - "focus_latest": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + E", - "ahk": "#+e" - } - }, - "increase_width": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Alt + =", - "ahk": "#!=" - } - }, - "decrease_width": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Alt + -", - "ahk": "#!-" - } - }, - "increase_height": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + =", - "ahk": "#+=" - } - }, - "decrease_height": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + -", - "ahk": "#+-" - } - }, - "restore_sizes": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Alt + 0", - "ahk": "#!0" - } - }, - "switch_workspace_0": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + 1", - "ahk": "!1" - } - }, - "switch_workspace_1": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + 2", - "ahk": "!2" - } - }, - "switch_workspace_2": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + 3", - "ahk": "!3" - } - }, - "switch_workspace_3": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + 4", - "ahk": "!4" - } - }, - "switch_workspace_4": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + 5", - "ahk": "!5" - } - }, - "switch_workspace_5": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + 6", - "ahk": "!6" - } - }, - "switch_workspace_6": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + 7", - "ahk": "!7" - } - }, - "switch_workspace_7": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + 8", - "ahk": "!8" - } - }, - "switch_workspace_8": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + 9", - "ahk": "!9" - } - }, - "switch_workspace_9": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + 0", - "ahk": "!0" - } - }, - "move_to_workspace_0": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + Shift + 1", - "ahk": "!+1" - } - }, - "move_to_workspace_1": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + Shift + 2", - "ahk": "!+2" - } - }, - "move_to_workspace_2": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + Shift + 3", - "ahk": "!+3" - } - }, - "move_to_workspace_3": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + Shift + 4", - "ahk": "!+4" - } - }, - "move_to_workspace_4": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + Shift + 5", - "ahk": "!+5" - } - }, - "move_to_workspace_5": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + Shift + 6", - "ahk": "!+6" - } - }, - "move_to_workspace_6": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + Shift + 7", - "ahk": "!+7" - } - }, - "move_to_workspace_7": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + Shift + 8", - "ahk": "!+8" - } - }, - "move_to_workspace_8": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + Shift + 9", - "ahk": "!+9" - } - }, - "move_to_workspace_9": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Alt + Shift + 0", - "ahk": "!+0" - } - }, - "send_to_workspace_0": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + 1", - "ahk": "#+1" - } - }, - "send_to_workspace_1": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + 2", - "ahk": "#+2" - } - }, - "send_to_workspace_2": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + 3", - "ahk": "#+3" - } - }, - "send_to_workspace_3": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + 4", - "ahk": "#+4" - } - }, - "send_to_workspace_4": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + 5", - "ahk": "#+5" - } - }, - "send_to_workspace_5": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + 6", - "ahk": "#+6" - } - }, - "send_to_workspace_6": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + 7", - "ahk": "#+7" - } - }, - "send_to_workspace_7": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + 8", - "ahk": "#+8" - } - }, - "send_to_workspace_8": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + 9", - "ahk": "#+9" - } - }, - "send_to_workspace_9": { - "$ref": "#/properties/ahk_variables/properties/reserve_top", - "default": { - "fancy": "Win + Shift + 0", - "ahk": "#+0" - } - } - }, - "additionalProperties": false, - "default": {} - }, - "selected_theme": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ], - "default": [ - "default" - ] - }, - "dev_tools": { - "type": "boolean", - "default": false - }, - "language": { - "type": "string", - "default": "en" - } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" +{ + "type": "object", + "properties": { + "fancy_toolbar": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + }, + "height": { + "type": "number", + "exclusiveMinimum": 0, + "default": 30 + }, + "placeholder": { + "type": [ + "string", + "null" + ], + "default": null + } + }, + "additionalProperties": false, + "default": {} + }, + "seelenweg": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + }, + "mode": { + "type": "string", + "enum": [ + "Full-Width", + "Min-Content" + ], + "default": "Min-Content" + }, + "hide_mode": { + "type": "string", + "enum": [ + "Never", + "Always", + "On-Overlap" + ], + "default": "On-Overlap" + }, + "position": { + "type": "string", + "enum": [ + "Left", + "Right", + "Top", + "Bottom" + ], + "default": "Bottom" + }, + "visible_separators": { + "type": "boolean", + "default": true + }, + "size": { + "type": "number", + "exclusiveMinimum": 0, + "default": 40, + "description": "Item size in pixels" + }, + "zoom_size": { + "type": "number", + "exclusiveMinimum": 0, + "default": 70, + "description": "Zoomed item size in pixels" + }, + "margin": { + "type": "number", + "minimum": 0, + "default": 8, + "description": "Dock/Bar margin in pixels" + }, + "padding": { + "type": "number", + "minimum": 0, + "default": 8, + "description": "Dock/Bar padding in pixels" + }, + "space_between_items": { + "type": "number", + "minimum": 0, + "default": 8, + "description": "Space between items (gap) in pixels" + } + }, + "additionalProperties": false, + "default": {} + }, + "window_manager": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "auto_stacking_by_category": { + "type": "boolean", + "default": true + }, + "border": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + }, + "width": { + "type": "number", + "minimum": 0, + "default": 3 + }, + "offset": { + "type": "number", + "default": -1 + } + }, + "additionalProperties": false, + "default": {} + }, + "resize_delta": { + "type": "number", + "default": 10, + "description": "% to add or remove on resize of windows using the CLI" + }, + "workspace_gap": { + "type": "number", + "minimum": 0, + "default": 10, + "description": "Space between windows" + }, + "workspace_padding": { + "type": "number", + "minimum": 0, + "default": 10 + }, + "global_work_area_offset": { + "type": "object", + "properties": { + "top": { + "type": "number", + "default": 0 + }, + "left": { + "type": "number", + "default": 0 + }, + "right": { + "type": "number", + "default": 0 + }, + "bottom": { + "type": "number", + "default": 0 + } + }, + "additionalProperties": false, + "default": {} + }, + "floating": { + "type": "object", + "properties": { + "width": { + "type": "number", + "exclusiveMinimum": 0, + "default": 800 + }, + "height": { + "type": "number", + "exclusiveMinimum": 0, + "default": 500 + } + }, + "additionalProperties": false, + "default": {} + }, + "default_layout": { + "type": [ + "string", + "null" + ], + "default": null + } + }, + "additionalProperties": false, + "default": {} + }, + "monitors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "workspaces": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "default": "New Workspace" + }, + "layout": { + "type": "string", + "default": "BSP" + }, + "padding": { + "anyOf": [ + { + "anyOf": [ + { + "not": {} + }, + { + "type": "number", + "minimum": 0 + } + ] + }, + { + "type": "null" + } + ] + }, + "gap": { + "anyOf": [ + { + "anyOf": [ + { + "not": {} + }, + { + "type": "number", + "minimum": 0 + } + ] + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "minItems": 1, + "default": [ + { + "name": "New Workspace", + "layout": "BSP" + } + ] + }, + "work_area_offset": { + "anyOf": [ + { + "anyOf": [ + { + "not": {} + }, + { + "$ref": "#/properties/window_manager/properties/global_work_area_offset" + } + ] + }, + { + "type": "null" + } + ] + }, + "editing_workspace": { + "type": "number", + "minimum": 0, + "default": 0 + } + }, + "additionalProperties": false + }, + "minItems": 1, + "default": [ + { + "workspaces": [ + { + "name": "New Workspace", + "layout": "BSP" + } + ], + "editing_workspace": 0 + } + ] + }, + "ahk_enabled": { + "type": "boolean", + "default": true + }, + "ahk_variables": { + "type": "object", + "properties": { + "reserve_top": { + "type": "object", + "properties": { + "fancy": { + "type": "string" + }, + "ahk": { + "type": "string" + } + }, + "required": [ + "fancy", + "ahk" + ], + "additionalProperties": false, + "default": { + "fancy": "Win + Shift + I", + "ahk": "#+i" + } + }, + "reserve_bottom": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + K", + "ahk": "#+k" + } + }, + "reserve_left": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + J", + "ahk": "#+j" + } + }, + "reserve_right": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + L", + "ahk": "#+l" + } + }, + "reserve_float": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + U", + "ahk": "#+u" + } + }, + "reserve_stack": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + O", + "ahk": "#+o" + } + }, + "focus_top": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + W", + "ahk": "#+w" + } + }, + "focus_bottom": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + S", + "ahk": "#+s" + } + }, + "focus_left": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + A", + "ahk": "#+a" + } + }, + "focus_right": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + D", + "ahk": "#+d" + } + }, + "focus_latest": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + E", + "ahk": "#+e" + } + }, + "increase_width": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Alt + =", + "ahk": "#!=" + } + }, + "decrease_width": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Alt + -", + "ahk": "#!-" + } + }, + "increase_height": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + =", + "ahk": "#+=" + } + }, + "decrease_height": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + -", + "ahk": "#+-" + } + }, + "restore_sizes": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Alt + 0", + "ahk": "#!0" + } + }, + "switch_workspace_0": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + 1", + "ahk": "!1" + } + }, + "switch_workspace_1": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + 2", + "ahk": "!2" + } + }, + "switch_workspace_2": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + 3", + "ahk": "!3" + } + }, + "switch_workspace_3": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + 4", + "ahk": "!4" + } + }, + "switch_workspace_4": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + 5", + "ahk": "!5" + } + }, + "switch_workspace_5": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + 6", + "ahk": "!6" + } + }, + "switch_workspace_6": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + 7", + "ahk": "!7" + } + }, + "switch_workspace_7": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + 8", + "ahk": "!8" + } + }, + "switch_workspace_8": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + 9", + "ahk": "!9" + } + }, + "switch_workspace_9": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + 0", + "ahk": "!0" + } + }, + "move_to_workspace_0": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + Shift + 1", + "ahk": "!+1" + } + }, + "move_to_workspace_1": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + Shift + 2", + "ahk": "!+2" + } + }, + "move_to_workspace_2": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + Shift + 3", + "ahk": "!+3" + } + }, + "move_to_workspace_3": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + Shift + 4", + "ahk": "!+4" + } + }, + "move_to_workspace_4": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + Shift + 5", + "ahk": "!+5" + } + }, + "move_to_workspace_5": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + Shift + 6", + "ahk": "!+6" + } + }, + "move_to_workspace_6": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + Shift + 7", + "ahk": "!+7" + } + }, + "move_to_workspace_7": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + Shift + 8", + "ahk": "!+8" + } + }, + "move_to_workspace_8": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + Shift + 9", + "ahk": "!+9" + } + }, + "move_to_workspace_9": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Alt + Shift + 0", + "ahk": "!+0" + } + }, + "send_to_workspace_0": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + 1", + "ahk": "#+1" + } + }, + "send_to_workspace_1": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + 2", + "ahk": "#+2" + } + }, + "send_to_workspace_2": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + 3", + "ahk": "#+3" + } + }, + "send_to_workspace_3": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + 4", + "ahk": "#+4" + } + }, + "send_to_workspace_4": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + 5", + "ahk": "#+5" + } + }, + "send_to_workspace_5": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + 6", + "ahk": "#+6" + } + }, + "send_to_workspace_6": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + 7", + "ahk": "#+7" + } + }, + "send_to_workspace_7": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + 8", + "ahk": "#+8" + } + }, + "send_to_workspace_8": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + 9", + "ahk": "#+9" + } + }, + "send_to_workspace_9": { + "$ref": "#/properties/ahk_variables/properties/reserve_top", + "default": { + "fancy": "Win + Shift + 0", + "ahk": "#+0" + } + } + }, + "additionalProperties": false, + "default": {} + }, + "selected_theme": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "default": [ + "default" + ] + }, + "dev_tools": { + "type": "boolean", + "default": false + }, + "language": { + "type": "string", + "default": "en" + } + }, + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/documentation/schemas/theme.schema.json b/documentation/schemas/theme.schema.json index 55e65ebe..86b3632c 100644 --- a/documentation/schemas/theme.schema.json +++ b/documentation/schemas/theme.schema.json @@ -1,141 +1,141 @@ -{ - "type": "object", - "properties": { - "info": { - "type": "object", - "properties": { - "displayName": { - "type": "string", - "default": "Unknown" - }, - "author": { - "type": "string", - "default": "Unknown" - }, - "description": { - "type": "string", - "default": "Empty" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - }, - "default": [] - } - }, - "additionalProperties": false, - "default": {} - }, - "variables": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "propertyNames": { - "pattern": "^\\-\\-" - }, - "default": {} - }, - "layers": { - "type": "object", - "properties": { - "weg": { - "type": "object", - "properties": { - "bg": { - "type": "number", - "minimum": 1, - "default": 1 - }, - "items": { - "type": "object", - "properties": { - "bg": { - "$ref": "#/properties/layers/properties/weg/properties/bg" - } - }, - "additionalProperties": false, - "default": {} - }, - "contextMenu": { - "type": "object", - "properties": { - "bg": { - "$ref": "#/properties/layers/properties/weg/properties/bg" - } - }, - "additionalProperties": false, - "default": {} - }, - "preview": { - "type": "object", - "properties": { - "bg": { - "$ref": "#/properties/layers/properties/weg/properties/bg" - } - }, - "additionalProperties": false, - "default": {} - } - }, - "additionalProperties": false, - "default": {} - }, - "toolbar": { - "type": "object", - "properties": { - "bg": { - "$ref": "#/properties/layers/properties/weg/properties/bg" - }, - "fastSettings": { - "type": "object", - "properties": { - "bg": { - "$ref": "#/properties/layers/properties/weg/properties/bg" - } - }, - "additionalProperties": false, - "default": {} - }, - "systemTray": { - "type": "object", - "properties": { - "bg": { - "$ref": "#/properties/layers/properties/weg/properties/bg" - } - }, - "additionalProperties": false, - "default": {} - } - }, - "additionalProperties": false, - "default": {} - } - }, - "additionalProperties": false, - "default": {} - }, - "styles": { - "type": "object", - "properties": { - "weg": { - "type": "string", - "default": "" - }, - "toolbar": { - "type": "string", - "default": "" - }, - "wm": { - "type": "string", - "default": "" - } - }, - "additionalProperties": false, - "default": {} - } - }, - "additionalProperties": false, - "$schema": "http://json-schema.org/draft-07/schema#" +{ + "type": "object", + "properties": { + "info": { + "type": "object", + "properties": { + "displayName": { + "type": "string", + "default": "Unknown" + }, + "author": { + "type": "string", + "default": "Unknown" + }, + "description": { + "type": "string", + "default": "Empty" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "default": [] + } + }, + "additionalProperties": false, + "default": {} + }, + "variables": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "pattern": "^\\-\\-" + }, + "default": {} + }, + "layers": { + "type": "object", + "properties": { + "weg": { + "type": "object", + "properties": { + "bg": { + "type": "number", + "minimum": 1, + "default": 1 + }, + "items": { + "type": "object", + "properties": { + "bg": { + "$ref": "#/properties/layers/properties/weg/properties/bg" + } + }, + "additionalProperties": false, + "default": {} + }, + "contextMenu": { + "type": "object", + "properties": { + "bg": { + "$ref": "#/properties/layers/properties/weg/properties/bg" + } + }, + "additionalProperties": false, + "default": {} + }, + "preview": { + "type": "object", + "properties": { + "bg": { + "$ref": "#/properties/layers/properties/weg/properties/bg" + } + }, + "additionalProperties": false, + "default": {} + } + }, + "additionalProperties": false, + "default": {} + }, + "toolbar": { + "type": "object", + "properties": { + "bg": { + "$ref": "#/properties/layers/properties/weg/properties/bg" + }, + "fastSettings": { + "type": "object", + "properties": { + "bg": { + "$ref": "#/properties/layers/properties/weg/properties/bg" + } + }, + "additionalProperties": false, + "default": {} + }, + "systemTray": { + "type": "object", + "properties": { + "bg": { + "$ref": "#/properties/layers/properties/weg/properties/bg" + } + }, + "additionalProperties": false, + "default": {} + } + }, + "additionalProperties": false, + "default": {} + } + }, + "additionalProperties": false, + "default": {} + }, + "styles": { + "type": "object", + "properties": { + "weg": { + "type": "string", + "default": "" + }, + "toolbar": { + "type": "string", + "default": "" + }, + "wm": { + "type": "string", + "default": "" + } + }, + "additionalProperties": false, + "default": {} + } + }, + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#" } \ No newline at end of file diff --git a/documentation/themes.md b/documentation/themes.md index 25ce4df0..91367ac7 100644 --- a/documentation/themes.md +++ b/documentation/themes.md @@ -1,53 +1,53 @@ -# Themes - -In Seelen UI, themes are managed as layers, allowing multiple themes to be used simultaneously. Since themes are like CSS files, their order is crucial as it determines the cascade order. - -Themes can be either a single file or a folder containing a specific file. The file should be a `.yml` file that adheres to the [theme schema](./schemas/theme.schema.json). - -For a folder, it follows this structure. Instead of using `styles.{module}` in the metadata file, it uses a CSS file named `theme.{module}.css`: - -``` -C:\Users\{USER}\AppData\Roaming\com.seelen.seelen-ui\themes -└── YourThemeFolder # Name of your theme - ├── theme.yml # Theme metadata file - ├── theme.weg.css - ├── theme.toolbar.css - └── theme.wm.css -``` - -**Note:** the file name or the folder name is used as the identifier of the theme. - -## Examples -You can use the default themes included in the executable as a guide. See the [themes](../static/themes/) directory in the code as example. - -## System Colors - -Seelen UI exposes system colors through CSS variables, such as: - -* `--config-accent-color`: This is a hex color without alpha, e.g., `#ffbbaa`. -* `--config-accent-color-rgb`: This represents RGB color values, e.g., `255, 187, 170`. It can be used in CSS as `rgba(var(--config-accent-color-rgb), 0.5)`. - -Complete list of system color variables: - -* `--config-accent-darkest-color` -* `--config-accent-darkest-color-rgb` -* `--config-accent-darker-color` -* `--config-accent-darker-color-rgb` -* `--config-accent-dark-color` -* `--config-accent-dark-color-rgb` -* `--config-accent-color` -* `--config-accent-color-rgb` -* `--config-accent-light-color` -* `--config-accent-light-color-rgb` -* `--config-accent-lighter-color` -* `--config-accent-lighter-color-rgb` -* `--config-accent-lightest-color` -* `--config-accent-lightest-color-rgb` - -All these are variants of the accent color set in your system settings. - -![alt text](images/colors.png) - -## Other Colors - -All the colors listed in the following [Gist](https://gist.github.com/eythaann/cd9a3cda0206ce23a17f5ea00ec2ba06) are also exposed for use in your themes. +# Themes + +In Seelen UI, themes are managed as layers, allowing multiple themes to be used simultaneously. Since themes are like CSS files, their order is crucial as it determines the cascade order. + +Themes can be either a single file or a folder containing a specific file. The file should be a `.yml` file that adheres to the [theme schema](./schemas/theme.schema.json). + +For a folder, it follows this structure. Instead of using `styles.{module}` in the metadata file, it uses a CSS file named `theme.{module}.css`: + +``` +C:\Users\{USER}\AppData\Roaming\com.seelen.seelen-ui\themes +└── YourThemeFolder # Name of your theme + ├── theme.yml # Theme metadata file + ├── theme.weg.css + ├── theme.toolbar.css + └── theme.wm.css +``` + +**Note:** the file name or the folder name is used as the identifier of the theme. + +## Examples +You can use the default themes included in the executable as a guide. See the [themes](../static/themes/) directory in the code as example. + +## System Colors + +Seelen UI exposes system colors through CSS variables, such as: + +* `--config-accent-color`: This is a hex color without alpha, e.g., `#ffbbaa`. +* `--config-accent-color-rgb`: This represents RGB color values, e.g., `255, 187, 170`. It can be used in CSS as `rgba(var(--config-accent-color-rgb), 0.5)`. + +Complete list of system color variables: + +* `--config-accent-darkest-color` +* `--config-accent-darkest-color-rgb` +* `--config-accent-darker-color` +* `--config-accent-darker-color-rgb` +* `--config-accent-dark-color` +* `--config-accent-dark-color-rgb` +* `--config-accent-color` +* `--config-accent-color-rgb` +* `--config-accent-light-color` +* `--config-accent-light-color-rgb` +* `--config-accent-lighter-color` +* `--config-accent-lighter-color-rgb` +* `--config-accent-lightest-color` +* `--config-accent-lightest-color-rgb` + +All these are variants of the accent color set in your system settings. + +![alt text](images/colors.png) + +## Other Colors + +All the colors listed in the following [Gist](https://gist.github.com/eythaann/cd9a3cda0206ce23a17f5ea00ec2ba06) are also exposed for use in your themes. diff --git a/documentation/toolbar.md b/documentation/toolbar.md index 74ea7141..9d0cef04 100644 --- a/documentation/toolbar.md +++ b/documentation/toolbar.md @@ -1,55 +1,55 @@ -# Seelen UI - Toolbar - -## Placeholders -The toolbar layout, also known as "placeholder," can be defined in a YAML file, adhering to the [placeholder schema](./schemas/placeholder.schema.json) and customized using Themes. - -To create a Toolbar module, follow this structure: - -```yaml -left: - - type: text - template: concat("@", env.USERNAME) - onClick: open -> env.USERPROFILE - tooltip: '"Open user folder"' -``` - -Note that `template`, `tooltip` and `onClick` function bodies are defined as code. This code will be evaluated at runtime using the [mathjs](https://mathjs.org/) evaluate function, similar to how Conditional Layouts work. - -Also, observe that to write literal strings, you must use double quotes. - -```yaml - tooltip: '"Open user folder"' -``` - -## Evaluation Scope - -When we say "each type has its own evaluation scope," we refer to how variables and functions within each type are accessible and interact during runtime. - -In the context of the Toolbar Widget documentation, each type (such as generic or text, date, and power) has its own set of variables that it can access and manipulate. These variables and functions are defined within the scope of each type, meaning they are accessible and meaningful only within that particular type. - -Therefore, by stating that "each type has its own evaluation scope," we emphasize that the variables and functions defined within each type are isolated and tailored to the specific functionality and requirements of that type within the Toolbar Widget. - -| Type | Scope | -| ---- | ----- | -| `generic` or `text` | `icon`, `window`, `env` | -| `date` | `icon`, `window`, `env`, `date` | -| `power` | `icon`, `window`, `env`, `power` | - -### Generic Module -**Scope:** `icon` is a object of all available icons in [react-icons](https://react-icons.github.io/react-icons/), `env` is the current environment, and `window` is the current focused window. - - -### Date Module -**Scope:** The `date` variable represents the current date and time as a string, formatted according to the specified format in the `format` property of the Module. - -**Format:** is a string to parse the date in a specific format, follow the next guide of [moment-js](https://momentjscom.readthedocs.io/en/latest/moment/04-displaying/01-format/) - -### Power Module -**Scope:** The `power` variable has available the same properties exposed in the [win32 SYSTEM_POWER_STATUS interface](https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-system_power_status) - -## Icons in Templates -### `icon.Name` vs `"[ICON:Name:12]"` - -When it comes to icons, you have two options: using the variable `icon.Name` or the string `"[ICON:Name:12]"`. - -It's important to note that `icon.Name` will be internally converted to `"[ICON:Name]"`. You can use whichever you prefer; the only difference is that with the quoted version, you can specify the size of the icon in pixels. +# Seelen UI - Toolbar + +## Placeholders +The toolbar layout, also known as "placeholder," can be defined in a YAML file, adhering to the [placeholder schema](./schemas/placeholder.schema.json) and customized using Themes. + +To create a Toolbar module, follow this structure: + +```yaml +left: + - type: text + template: concat("@", env.USERNAME) + onClick: open -> env.USERPROFILE + tooltip: '"Open user folder"' +``` + +Note that `template`, `tooltip` and `onClick` function bodies are defined as code. This code will be evaluated at runtime using the [mathjs](https://mathjs.org/) evaluate function, similar to how Conditional Layouts work. + +Also, observe that to write literal strings, you must use double quotes. + +```yaml + tooltip: '"Open user folder"' +``` + +## Evaluation Scope + +When we say "each type has its own evaluation scope," we refer to how variables and functions within each type are accessible and interact during runtime. + +In the context of the Toolbar Widget documentation, each type (such as generic or text, date, and power) has its own set of variables that it can access and manipulate. These variables and functions are defined within the scope of each type, meaning they are accessible and meaningful only within that particular type. + +Therefore, by stating that "each type has its own evaluation scope," we emphasize that the variables and functions defined within each type are isolated and tailored to the specific functionality and requirements of that type within the Toolbar Widget. + +| Type | Scope | +| ---- | ----- | +| `generic` or `text` | `icon`, `window`, `env` | +| `date` | `icon`, `window`, `env`, `date` | +| `power` | `icon`, `window`, `env`, `power` | + +### Generic Module +**Scope:** `icon` is a object of all available icons in [react-icons](https://react-icons.github.io/react-icons/), `env` is the current environment, and `window` is the current focused window. + + +### Date Module +**Scope:** The `date` variable represents the current date and time as a string, formatted according to the specified format in the `format` property of the Module. + +**Format:** is a string to parse the date in a specific format, follow the next guide of [moment-js](https://momentjscom.readthedocs.io/en/latest/moment/04-displaying/01-format/) + +### Power Module +**Scope:** The `power` variable has available the same properties exposed in the [win32 SYSTEM_POWER_STATUS interface](https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-system_power_status) + +## Icons in Templates +### `icon.Name` vs `"[ICON:Name:12]"` + +When it comes to icons, you have two options: using the variable `icon.Name` or the string `"[ICON:Name:12]"`. + +It's important to note that `icon.Name` will be internally converted to `"[ICON:Name]"`. You can use whichever you prefer; the only difference is that with the quoted version, you can specify the size of the icon in pixels. diff --git a/documentation/window_manager.md b/documentation/window_manager.md index 3aefc321..bb03fc5a 100644 --- a/documentation/window_manager.md +++ b/documentation/window_manager.md @@ -1,19 +1,19 @@ -# Tiling Window Manager - -Seelen UI desktop - -## What is a Tiling Window Manager? - -A Tiling Window Manager (TWM) is a window manager that automatically organizes applications into non-overlapping tiles instead of overlapping them. This optimizes screen space and simplifies application navigation through keyboard shortcuts. - -### Why Should You Consider Using It? - -- **Spatial Efficiency:** Maximize your screen real estate, allowing you to work with multiple applications without overlapping. - -- **Enhanced Productivity:** Quickly navigate between applications with keyboard shortcuts and easily split the screen for efficient multitasking. - -- **Total Customization:** Tailor window arrangement and keyboard shortcuts according to your preferences. - -- **Seamless Experience:** Eliminate visual distractions by avoiding overlapping windows. - -In summary, a Tiling Window Manager can transform your computing experience, offering spatial efficiency, enhanced productivity, and an interface tailored to your needs. If you value space optimization and agility in navigating between applications, consider making the switch! +# Tiling Window Manager + +Seelen UI desktop + +## What is a Tiling Window Manager? + +A Tiling Window Manager (TWM) is a window manager that automatically organizes applications into non-overlapping tiles instead of overlapping them. This optimizes screen space and simplifies application navigation through keyboard shortcuts. + +### Why Should You Consider Using It? + +- **Spatial Efficiency:** Maximize your screen real estate, allowing you to work with multiple applications without overlapping. + +- **Enhanced Productivity:** Quickly navigate between applications with keyboard shortcuts and easily split the screen for efficient multitasking. + +- **Total Customization:** Tailor window arrangement and keyboard shortcuts according to your preferences. + +- **Seamless Experience:** Eliminate visual distractions by avoiding overlapping windows. + +In summary, a Tiling Window Manager can transform your computing experience, offering spatial efficiency, enhanced productivity, and an interface tailored to your needs. If you value space optimization and agility in navigating between applications, consider making the switch! diff --git a/eslint.config.js b/eslint.config.js index bbc35447..c1db8154 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,96 +1,96 @@ -const stylistic = require('@stylistic/eslint-plugin'); -const simpleImportSort = require('eslint-plugin-simple-import-sort'); -const tsEslint = require('typescript-eslint'); - -module.exports = [ - { - ignores: ['node_modules/', '.git/', 'dist/', 'target/'], - }, - { - files: ['**/*.{js,jsx,ts,tsx,mjs}'], - plugins: { - '@stylistic': stylistic, - 'simple-import-sort': simpleImportSort, - '@ts': tsEslint.plugin, - }, - languageOptions: { - parser: tsEslint.parser, - }, - rules: { - 'simple-import-sort/imports': [ - 'error', - { - groups: [ - [''], - ['.*/(infra|infrastructure).*'], - ['.*/app'], - ['.*/domain.*'], - ['.*.module.css$'], - ['.*.css$'], - ], - }, - ], - 'no-dupe-keys': 'error', - '@stylistic/key-spacing': ['error', { beforeColon: false }], - '@stylistic/block-spacing': 'error', - '@stylistic/arrow-spacing': 'error', - '@stylistic/one-var-declaration-per-line': ['error', 'always'], - '@stylistic/object-curly-spacing': ['error', 'always'], - - '@stylistic/brace-style': ['error', '1tbs'], - '@stylistic/jsx-quotes': ['error', 'prefer-double'], - 'no-nested-ternary': 'error', - - '@stylistic/comma-dangle': ['error', 'always-multiline'], - '@stylistic/comma-spacing': [ - 'error', - { - before: false, - after: true, - }, - ], - '@stylistic/keyword-spacing': 'error', - '@stylistic/space-before-blocks': 'error', - '@stylistic/no-multiple-empty-lines': [ - 'error', - { - max: 1, - maxEOF: 1, - }, - ], - '@stylistic/lines-between-class-members': [ - 'error', - 'always', - { exceptAfterSingleLine: true }, - ], - '@stylistic/padded-blocks': ['error', 'never'], - '@stylistic/arrow-parens': ['error', 'always'], - '@stylistic/space-before-function-paren': [ - 'error', - { - anonymous: 'always', - named: 'never', - asyncArrow: 'always', - }, - ], - '@stylistic/quotes': ['error', 'single'], - '@stylistic/semi': 'error', - '@stylistic/no-multi-spaces': ['error'], - '@stylistic/no-trailing-spaces': ['error'], - '@stylistic/space-infix-ops': ['error'], - '@stylistic/indent': ['error', 2], - '@stylistic/jsx-indent': ['error', 2], - '@stylistic/member-delimiter-style': ['error'], - '@stylistic/type-annotation-spacing': ['error'], - '@ts/no-unused-vars': [ - 'warn', - { - varsIgnorePattern: '^_', - argsIgnorePattern: '^_', - caughtErrorsIgnorePattern: '^_', - destructuredArrayIgnorePattern: '^_', - }, - ], - }, - }, -]; +const stylistic = require('@stylistic/eslint-plugin'); +const simpleImportSort = require('eslint-plugin-simple-import-sort'); +const tsEslint = require('typescript-eslint'); + +module.exports = [ + { + ignores: ['node_modules/', '.git/', 'dist/', 'target/'], + }, + { + files: ['**/*.{js,jsx,ts,tsx,mjs}'], + plugins: { + '@stylistic': stylistic, + 'simple-import-sort': simpleImportSort, + '@ts': tsEslint.plugin, + }, + languageOptions: { + parser: tsEslint.parser, + }, + rules: { + 'simple-import-sort/imports': [ + 'error', + { + groups: [ + [''], + ['.*/(infra|infrastructure).*'], + ['.*/app'], + ['.*/domain.*'], + ['.*.module.css$'], + ['.*.css$'], + ], + }, + ], + 'no-dupe-keys': 'error', + '@stylistic/key-spacing': ['error', { beforeColon: false }], + '@stylistic/block-spacing': 'error', + '@stylistic/arrow-spacing': 'error', + '@stylistic/one-var-declaration-per-line': ['error', 'always'], + '@stylistic/object-curly-spacing': ['error', 'always'], + + '@stylistic/brace-style': ['error', '1tbs'], + '@stylistic/jsx-quotes': ['error', 'prefer-double'], + 'no-nested-ternary': 'error', + + '@stylistic/comma-dangle': ['error', 'always-multiline'], + '@stylistic/comma-spacing': [ + 'error', + { + before: false, + after: true, + }, + ], + '@stylistic/keyword-spacing': 'error', + '@stylistic/space-before-blocks': 'error', + '@stylistic/no-multiple-empty-lines': [ + 'error', + { + max: 1, + maxEOF: 1, + }, + ], + '@stylistic/lines-between-class-members': [ + 'error', + 'always', + { exceptAfterSingleLine: true }, + ], + '@stylistic/padded-blocks': ['error', 'never'], + '@stylistic/arrow-parens': ['error', 'always'], + '@stylistic/space-before-function-paren': [ + 'error', + { + anonymous: 'always', + named: 'never', + asyncArrow: 'always', + }, + ], + '@stylistic/quotes': ['error', 'single'], + '@stylistic/semi': 'error', + '@stylistic/no-multi-spaces': ['error'], + '@stylistic/no-trailing-spaces': ['error'], + '@stylistic/space-infix-ops': ['error'], + '@stylistic/indent': ['error', 2], + '@stylistic/jsx-indent': ['error', 2], + '@stylistic/member-delimiter-style': ['error'], + '@stylistic/type-annotation-spacing': ['error'], + '@ts/no-unused-vars': [ + 'warn', + { + varsIgnorePattern: '^_', + argsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + }, + ], + }, + }, +]; diff --git a/jest.config.js b/jest.config.js index b413e106..c8f5f212 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,5 +1,5 @@ -/** @type {import('ts-jest').JestConfigWithTsJest} */ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', }; \ No newline at end of file diff --git a/lefthook.yml b/lefthook.yml index f07b3a1a..651697e4 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -1,26 +1,26 @@ -commit-msg: - commands: - lint-commit-msg: - run: npx commitlint --edit - -pre-commit: - commands: - js-linter: - glob: "**/*.{js,jsx,ts,tsx}" - run: npm run lint - rust-linter: - glob: "**/*.rs" - run: cargo fmt -- --check - rust-code-check: - glob: "**/*.rs" - run: cargo clippy -- -D warnings - -pre-push: - parallel: true - commands: - js-test: - glob: "**/*.{js,jsx,ts,tsx}" - run: npm run test - rust-test: - glob: "**/*.rs" - run: cargo test +commit-msg: + commands: + lint-commit-msg: + run: npx commitlint --edit + +pre-commit: + commands: + js-linter: + glob: "**/*.{js,jsx,ts,tsx}" + run: npm run lint + rust-linter: + glob: "**/*.rs" + run: cargo fmt -- --check + rust-code-check: + glob: "**/*.rs" + run: cargo clippy -- -D warnings + +pre-push: + parallel: true + commands: + js-test: + glob: "**/*.{js,jsx,ts,tsx}" + run: npm run test + rust-test: + glob: "**/*.rs" + run: cargo test diff --git a/nodemon.json b/nodemon.json index 9eb2427d..a42185d5 100644 --- a/nodemon.json +++ b/nodemon.json @@ -1,15 +1,15 @@ -{ - "$schema": "https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/nodemon.json", - "ignore": [ - "src/JsonSettings.interface.ts", - "src/YamlSettings.interface.ts" - ], - "watch": [ - "src", - "scripts", - "static", - "tauri.conf.json" - ], - "ext": "ts,tsx,css,ps1,yml,rs,json,html", - "exec": "npm run build:ui && npx tauri dev" +{ + "$schema": "https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/nodemon.json", + "ignore": [ + "src/JsonSettings.interface.ts", + "src/YamlSettings.interface.ts" + ], + "watch": [ + "src", + "scripts", + "static", + "tauri.conf.json" + ], + "ext": "ts,tsx,css,ps1,yml,rs,json,html", + "exec": "npm run build:ui && npx tauri dev" } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f8d80d8e..6b14b94a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9577 +1,9577 @@ -{ - "name": "seelen-ui", - "version": "1.9.4", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "seelen-ui", - "version": "1.9.4", - "hasInstallScript": true, - "license": "Polyform Strict License", - "dependencies": { - "@tauri-apps/plugin-autostart": "^2.0.0-beta.2", - "@tauri-apps/plugin-deep-link": "^2.0.0-beta.10", - "@tauri-apps/plugin-dialog": "^2.0.0-beta.2", - "@tauri-apps/plugin-fs": "^2.0.0-beta.2", - "@tauri-apps/plugin-log": "^2.0.0-beta.2", - "@tauri-apps/plugin-process": "^2.0.0-beta.2", - "@tauri-apps/plugin-shell": "^2.0.0-beta.2", - "@tauri-apps/plugin-updater": "^2.0.0-beta.2" - }, - "devDependencies": { - "@commitlint/cli": "^19.3.0", - "@commitlint/config-conventional": "^19.2.2", - "@reduxjs/toolkit": "^2.2.1", - "@stylistic/eslint-plugin": "^1.6.2", - "@tauri-apps/api": "^2.0.0-beta.4", - "@tauri-apps/cli": "^2.0.0-beta.8", - "@types/jest": "^29.5.12", - "@types/js-yaml": "^4.0.9", - "@types/node": "^20.11.19", - "@types/react": "^18.2.56", - "@types/react-dom": "^18.2.19", - "antd": "^5.14.1", - "esbuild": "^0.20.1", - "eslint": "^8.56.0", - "eslint-plugin-simple-import-sort": "^12.0.0", - "framer-motion": "11.3.6", - "glob": "^7.2.3", - "google-translate-api-x": "^10.6.8", - "i18next": "^23.12.2", - "jest": "^29.7.0", - "js-yaml": "^4.1.0", - "json-schema-to-typescript": "^13.1.2", - "lefthook": "^1.6.18", - "lodash": "^4.17.21", - "mathjs": "^12.4.2", - "moment": "^2.30.1", - "nodemon": "^3.0.3", - "react": "18.2.0", - "react-dom": "18.2.0", - "react-i18next": "^15.0.0", - "react-icons": "^5.3.0", - "react-redux": "^9.1.0", - "readable-types": "^4.0.0", - "redux": "^5.0.1", - "toml": "^3.0.0", - "ts-jest": "^29.1.2", - "ts-node": "^10.9.2", - "typescript": "5.3.3", - "typescript-eslint": "^7.0.1", - "zod": "^3.23.4", - "zod-to-json-schema": "^3.23.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@ant-design/colors": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.0.2.tgz", - "integrity": "sha512-7KJkhTiPiLHSu+LmMJnehfJ6242OCxSlR3xHVBecYxnMW8MS/878NXct1GqYARyL59fyeFdKRxXTfvR9SnDgJg==", - "dev": true, - "dependencies": { - "@ctrl/tinycolor": "^3.6.1" - } - }, - "node_modules/@ant-design/cssinjs": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@ant-design/cssinjs/-/cssinjs-1.21.0.tgz", - "integrity": "sha512-gIilraPl+9EoKdYxnupxjHB/Q6IHNRjEXszKbDxZdsgv4sAZ9pjkCq8yanDWNvyfjp4leir2OVAJm0vxwKK8YA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.11.1", - "@emotion/hash": "^0.8.0", - "@emotion/unitless": "^0.7.5", - "classnames": "^2.3.1", - "csstype": "^3.1.3", - "rc-util": "^5.35.0", - "stylis": "^4.0.13" - }, - "peerDependencies": { - "react": ">=16.0.0", - "react-dom": ">=16.0.0" - } - }, - "node_modules/@ant-design/icons": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.3.7.tgz", - "integrity": "sha512-bCPXTAg66f5bdccM4TT21SQBDO1Ek2gho9h3nO9DAKXJP4sq+5VBjrQMSxMVXSB3HyEz+cUbHQ5+6ogxCOpaew==", - "dev": true, - "dependencies": { - "@ant-design/colors": "^7.0.0", - "@ant-design/icons-svg": "^4.4.0", - "@babel/runtime": "^7.11.2", - "classnames": "^2.2.6", - "rc-util": "^5.31.1" - }, - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "react": ">=16.0.0", - "react-dom": ">=16.0.0" - } - }, - "node_modules/@ant-design/icons-svg": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz", - "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==", - "dev": true - }, - "node_modules/@ant-design/react-slick": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-1.1.2.tgz", - "integrity": "sha512-EzlvzE6xQUBrZuuhSAFTdsr4P2bBBHGZwKFemEfq8gIGyIQCxalYfZW/T2ORbtQx5rU69o+WycP3exY/7T1hGA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.4", - "classnames": "^2.2.5", - "json2mq": "^0.2.0", - "resize-observer-polyfill": "^1.5.1", - "throttle-debounce": "^5.0.0" - }, - "peerDependencies": { - "react": ">=16.9.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", - "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcherny/json-schema-ref-parser": { - "version": "10.0.5-fork", - "resolved": "https://registry.npmjs.org/@bcherny/json-schema-ref-parser/-/json-schema-ref-parser-10.0.5-fork.tgz", - "integrity": "sha512-E/jKbPoca1tfUPj3iSbitDZTGnq6FUFjkH6L8U2oDwSuwK1WhnnVtCG7oFOTg/DDnyoXbQYUiUiGOibHqaGVnw==", - "dev": true, - "dependencies": { - "@jsdevtools/ono": "^7.1.3", - "@types/json-schema": "^7.0.6", - "call-me-maybe": "^1.0.1", - "js-yaml": "^4.1.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/philsturgeon" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "node_modules/@commitlint/cli": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.3.0.tgz", - "integrity": "sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==", - "dev": true, - "dependencies": { - "@commitlint/format": "^19.3.0", - "@commitlint/lint": "^19.2.2", - "@commitlint/load": "^19.2.0", - "@commitlint/read": "^19.2.1", - "@commitlint/types": "^19.0.3", - "execa": "^8.0.1", - "yargs": "^17.0.0" - }, - "bin": { - "commitlint": "cli.js" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/cli/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/@commitlint/cli/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/cli/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/@commitlint/cli/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/cli/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/cli/node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/cli/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/cli/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/cli/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@commitlint/cli/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/config-conventional": { - "version": "19.2.2", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.2.2.tgz", - "integrity": "sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==", - "dev": true, - "dependencies": { - "@commitlint/types": "^19.0.3", - "conventional-changelog-conventionalcommits": "^7.0.2" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/config-validator": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.0.3.tgz", - "integrity": "sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==", - "dev": true, - "dependencies": { - "@commitlint/types": "^19.0.3", - "ajv": "^8.11.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/config-validator/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@commitlint/config-validator/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/@commitlint/ensure": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.0.3.tgz", - "integrity": "sha512-SZEpa/VvBLoT+EFZVb91YWbmaZ/9rPH3ESrINOl0HD2kMYsjvl0tF7nMHh0EpTcv4+gTtZBAe1y/SS6/OhfZzQ==", - "dev": true, - "dependencies": { - "@commitlint/types": "^19.0.3", - "lodash.camelcase": "^4.3.0", - "lodash.kebabcase": "^4.1.1", - "lodash.snakecase": "^4.1.1", - "lodash.startcase": "^4.4.0", - "lodash.upperfirst": "^4.3.1" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/execute-rule": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.0.0.tgz", - "integrity": "sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==", - "dev": true, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/format": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.3.0.tgz", - "integrity": "sha512-luguk5/aF68HiF4H23ACAfk8qS8AHxl4LLN5oxPc24H+2+JRPsNr1OS3Gaea0CrH7PKhArBMKBz5RX9sA5NtTg==", - "dev": true, - "dependencies": { - "@commitlint/types": "^19.0.3", - "chalk": "^5.3.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/format/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@commitlint/is-ignored": { - "version": "19.2.2", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.2.2.tgz", - "integrity": "sha512-eNX54oXMVxncORywF4ZPFtJoBm3Tvp111tg1xf4zWXGfhBPKpfKG6R+G3G4v5CPlRROXpAOpQ3HMhA9n1Tck1g==", - "dev": true, - "dependencies": { - "@commitlint/types": "^19.0.3", - "semver": "^7.6.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/lint": { - "version": "19.2.2", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.2.2.tgz", - "integrity": "sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==", - "dev": true, - "dependencies": { - "@commitlint/is-ignored": "^19.2.2", - "@commitlint/parse": "^19.0.3", - "@commitlint/rules": "^19.0.3", - "@commitlint/types": "^19.0.3" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/load": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.2.0.tgz", - "integrity": "sha512-XvxxLJTKqZojCxaBQ7u92qQLFMMZc4+p9qrIq/9kJDy8DOrEa7P1yx7Tjdc2u2JxIalqT4KOGraVgCE7eCYJyQ==", - "dev": true, - "dependencies": { - "@commitlint/config-validator": "^19.0.3", - "@commitlint/execute-rule": "^19.0.0", - "@commitlint/resolve-extends": "^19.1.0", - "@commitlint/types": "^19.0.3", - "chalk": "^5.3.0", - "cosmiconfig": "^9.0.0", - "cosmiconfig-typescript-loader": "^5.0.0", - "lodash.isplainobject": "^4.0.6", - "lodash.merge": "^4.6.2", - "lodash.uniq": "^4.5.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/load/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@commitlint/message": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.0.0.tgz", - "integrity": "sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==", - "dev": true, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/parse": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.0.3.tgz", - "integrity": "sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==", - "dev": true, - "dependencies": { - "@commitlint/types": "^19.0.3", - "conventional-changelog-angular": "^7.0.0", - "conventional-commits-parser": "^5.0.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/read": { - "version": "19.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.2.1.tgz", - "integrity": "sha512-qETc4+PL0EUv7Q36lJbPG+NJiBOGg7SSC7B5BsPWOmei+Dyif80ErfWQ0qXoW9oCh7GTpTNRoaVhiI8RbhuaNw==", - "dev": true, - "dependencies": { - "@commitlint/top-level": "^19.0.0", - "@commitlint/types": "^19.0.3", - "execa": "^8.0.1", - "git-raw-commits": "^4.0.0", - "minimist": "^1.2.8" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/read/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/@commitlint/read/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/read/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/@commitlint/read/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/read/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/read/node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/read/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/read/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/read/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@commitlint/read/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/resolve-extends": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.1.0.tgz", - "integrity": "sha512-z2riI+8G3CET5CPgXJPlzftH+RiWYLMYv4C9tSLdLXdr6pBNimSKukYP9MS27ejmscqCTVA4almdLh0ODD2KYg==", - "dev": true, - "dependencies": { - "@commitlint/config-validator": "^19.0.3", - "@commitlint/types": "^19.0.3", - "global-directory": "^4.0.1", - "import-meta-resolve": "^4.0.0", - "lodash.mergewith": "^4.6.2", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/resolve-extends/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@commitlint/rules": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.0.3.tgz", - "integrity": "sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==", - "dev": true, - "dependencies": { - "@commitlint/ensure": "^19.0.3", - "@commitlint/message": "^19.0.0", - "@commitlint/to-lines": "^19.0.0", - "@commitlint/types": "^19.0.3", - "execa": "^8.0.1" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/rules/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/@commitlint/rules/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/rules/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/@commitlint/rules/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/rules/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/rules/node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/rules/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/rules/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/rules/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@commitlint/rules/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/to-lines": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.0.0.tgz", - "integrity": "sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==", - "dev": true, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/top-level": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.0.0.tgz", - "integrity": "sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==", - "dev": true, - "dependencies": { - "find-up": "^7.0.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/top-level/node_modules/find-up": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", - "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", - "dev": true, - "dependencies": { - "locate-path": "^7.2.0", - "path-exists": "^5.0.0", - "unicorn-magic": "^0.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/top-level/node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dev": true, - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/top-level/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/top-level/node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/top-level/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/@commitlint/top-level/node_modules/yocto-queue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@commitlint/types": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.0.3.tgz", - "integrity": "sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==", - "dev": true, - "dependencies": { - "@types/conventional-commits-parser": "^5.0.0", - "chalk": "^5.3.0" - }, - "engines": { - "node": ">=v18" - } - }, - "node_modules/@commitlint/types/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@ctrl/tinycolor": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", - "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@emotion/hash": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==", - "dev": true - }, - "node_modules/@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", - "dev": true - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", - "dev": true, - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", - "dev": true, - "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, - "dependencies": { - "jest-get-type": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", - "dev": true, - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", - "dev": true, - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", - "dev": true, - "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@jsdevtools/ono": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", - "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", - "dev": true - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@rc-component/async-validator": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@rc-component/async-validator/-/async-validator-5.0.4.tgz", - "integrity": "sha512-qgGdcVIF604M9EqjNF0hbUTz42bz/RDtxWdWuU5EQe3hi7M8ob54B6B35rOsvX5eSvIHIzT9iH1R3n+hk3CGfg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.24.4" - }, - "engines": { - "node": ">=14.x" - } - }, - "node_modules/@rc-component/color-picker": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-1.5.3.tgz", - "integrity": "sha512-+tGGH3nLmYXTalVe0L8hSZNs73VTP5ueSHwUlDC77KKRaN7G4DS4wcpG5DTDzdcV/Yas+rzA6UGgIyzd8fS4cw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.23.6", - "@ctrl/tinycolor": "^3.6.1", - "classnames": "^2.2.6", - "rc-util": "^5.38.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/context": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@rc-component/context/-/context-1.4.0.tgz", - "integrity": "sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "rc-util": "^5.27.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/mini-decimal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rc-component/mini-decimal/-/mini-decimal-1.1.0.tgz", - "integrity": "sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.18.0" - }, - "engines": { - "node": ">=8.x" - } - }, - "node_modules/@rc-component/mutate-observer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rc-component/mutate-observer/-/mutate-observer-1.1.0.tgz", - "integrity": "sha512-QjrOsDXQusNwGZPf4/qRQasg7UFEj06XiCJ8iuiq/Io7CrHrgVi6Uuetw60WAMG1799v+aM8kyc+1L/GBbHSlw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.18.0", - "classnames": "^2.3.2", - "rc-util": "^5.24.4" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/portal": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@rc-component/portal/-/portal-1.1.2.tgz", - "integrity": "sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.18.0", - "classnames": "^2.3.2", - "rc-util": "^5.24.4" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/tour": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-1.15.0.tgz", - "integrity": "sha512-h6hyILDwL+In9GAgRobwRWihLqqsD7Uft3fZGrJ7L4EiyCoxbnNYwzPXDfz7vNDhWeVyvAWQJj9fJCzpI4+b4g==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.18.0", - "@rc-component/portal": "^1.0.0-9", - "@rc-component/trigger": "^2.0.0", - "classnames": "^2.3.2", - "rc-util": "^5.24.4" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@rc-component/trigger": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.2.0.tgz", - "integrity": "sha512-QarBCji02YE9aRFhZgRZmOpXBj0IZutRippsVBv85sxvG4FGk/vRxwAlkn3MS9zK5mwbETd86mAVg2tKqTkdJA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.23.2", - "@rc-component/portal": "^1.1.0", - "classnames": "^2.3.2", - "rc-motion": "^2.0.0", - "rc-resize-observer": "^1.3.1", - "rc-util": "^5.38.0" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/@reduxjs/toolkit": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.5.tgz", - "integrity": "sha512-aeFA/s5NCG7NoJe/MhmwREJxRkDs0ZaSqt0MxhWUrwCf1UQXpwR87RROJEql0uAkLI6U7snBOYOcKw83ew3FPg==", - "dev": true, - "dependencies": { - "immer": "^10.0.3", - "redux": "^5.0.1", - "redux-thunk": "^3.1.0", - "reselect": "^5.1.0" - }, - "peerDependencies": { - "react": "^16.9.0 || ^17.0.0 || ^18", - "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - }, - "react-redux": { - "optional": true - } - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/@stylistic/eslint-plugin": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.8.1.tgz", - "integrity": "sha512-64My6I7uCcmSQ//427Pfg2vjSf9SDzfsGIWohNFgISMLYdC5BzJqDo647iDDJzSxINh3WTC0Ql46ifiKuOoTyA==", - "dev": true, - "dependencies": { - "@stylistic/eslint-plugin-js": "1.8.1", - "@stylistic/eslint-plugin-jsx": "1.8.1", - "@stylistic/eslint-plugin-plus": "1.8.1", - "@stylistic/eslint-plugin-ts": "1.8.1", - "@types/eslint": "^8.56.10" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@stylistic/eslint-plugin-js": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.8.1.tgz", - "integrity": "sha512-c5c2C8Mos5tTQd+NWpqwEu7VT6SSRooAguFPMj1cp2RkTYl1ynKoXo8MWy3k4rkbzoeYHrqC2UlUzsroAN7wtQ==", - "dev": true, - "dependencies": { - "@types/eslint": "^8.56.10", - "acorn": "^8.11.3", - "escape-string-regexp": "^4.0.0", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@stylistic/eslint-plugin-jsx": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.8.1.tgz", - "integrity": "sha512-k1Eb6rcjMP+mmjvj+vd9y5KUdWn1OBkkPLHXhsrHt5lCDFZxJEs0aVQzE5lpYrtVZVkpc5esTtss/cPJux0lfA==", - "dev": true, - "dependencies": { - "@stylistic/eslint-plugin-js": "^1.8.1", - "@types/eslint": "^8.56.10", - "estraverse": "^5.3.0", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@stylistic/eslint-plugin-plus": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.8.1.tgz", - "integrity": "sha512-4+40H3lHYTN8OWz+US8CamVkO+2hxNLp9+CAjorI7top/lHqemhpJvKA1LD9Uh+WMY9DYWiWpL2+SZ2wAXY9fQ==", - "dev": true, - "dependencies": { - "@types/eslint": "^8.56.10", - "@typescript-eslint/utils": "^6.21.0" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/@stylistic/eslint-plugin-ts": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.8.1.tgz", - "integrity": "sha512-/q1m+ZuO1JHfiSF16EATFzv7XSJkc5W6DocfvH5o9oB6WWYFMF77fVoBWnKT3wGptPOc2hkRupRKhmeFROdfWA==", - "dev": true, - "dependencies": { - "@stylistic/eslint-plugin-js": "1.8.1", - "@types/eslint": "^8.56.10", - "@typescript-eslint/utils": "^6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@tauri-apps/api": { - "version": "2.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-rc.0.tgz", - "integrity": "sha512-v454Qs3REHc3Za59U+/eSmBsdmF+3NE5+76+lFDaitVqN4ZglDHENDaMARYKGJVZuxiSkzyqG0SeG7lLQjVkPA==", - "engines": { - "node": ">= 18.18", - "npm": ">= 6.6.0", - "yarn": ">= 1.19.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/tauri" - } - }, - "node_modules/@tauri-apps/cli": { - "version": "2.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.0.0-rc.3.tgz", - "integrity": "sha512-iNF95pieBmverl1EmQyqh+fhcIClS544fN5Ex5lAbYLTiHZ/gm3lOfVBhF6NPaKd/sfLuy7K1tfDXlHztBfANw==", - "dev": true, - "bin": { - "tauri": "tauri.js" - }, - "engines": { - "node": ">= 10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/tauri" - }, - "optionalDependencies": { - "@tauri-apps/cli-darwin-arm64": "2.0.0-rc.3", - "@tauri-apps/cli-darwin-x64": "2.0.0-rc.3", - "@tauri-apps/cli-linux-arm-gnueabihf": "2.0.0-rc.3", - "@tauri-apps/cli-linux-arm64-gnu": "2.0.0-rc.3", - "@tauri-apps/cli-linux-arm64-musl": "2.0.0-rc.3", - "@tauri-apps/cli-linux-x64-gnu": "2.0.0-rc.3", - "@tauri-apps/cli-linux-x64-musl": "2.0.0-rc.3", - "@tauri-apps/cli-win32-arm64-msvc": "2.0.0-rc.3", - "@tauri-apps/cli-win32-ia32-msvc": "2.0.0-rc.3", - "@tauri-apps/cli-win32-x64-msvc": "2.0.0-rc.3" - } - }, - "node_modules/@tauri-apps/cli-darwin-arm64": { - "version": "2.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.0.0-rc.3.tgz", - "integrity": "sha512-szYCSr/ChbCF+S6Wnr15TYpI2cZR07d+AQOiFGuScP0preM8Pbsk/sb0hfLwqzepjVFFNVWQba9sG7FEW2Y2XA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-darwin-x64": { - "version": "2.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.0.0-rc.3.tgz", - "integrity": "sha512-BJv6EJOY1DJbRzVtfg8CcBAlnS5OjhBAc5YKjh4BT7EyOcop8HStBSxhL6yjWrUP7eLR1iIsW/uSehVJwzYIdQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { - "version": "2.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.0.0-rc.3.tgz", - "integrity": "sha512-fwx805/xL4sF/EdMYqcUHQHzMYwo+OVTBTz5x/JWK8D57rnmLHAP+ZhnfFsZQLRo2QRT2l1Ye3bDyU+QRA1JFA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-linux-arm64-gnu": { - "version": "2.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.0.0-rc.3.tgz", - "integrity": "sha512-3KauzO1Ls4kuY0nr82S4X8XFxlQAMN+Mqp8LLqvQ+PPMp92XQAkPH7osQdoHIEoW5gsE69U2JaiQ5tHSqNM9og==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-linux-arm64-musl": { - "version": "2.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.0-rc.3.tgz", - "integrity": "sha512-ngHS0foffm1xO5gqnDKGeYMKj8ceGmrFP5dDldoaaMQubw1SyFa0pRUjb7fZSYiO7F4SOSa8NYeMqlF9peZmnQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-linux-x64-gnu": { - "version": "2.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.0.0-rc.3.tgz", - "integrity": "sha512-0/am9pVvuUHGmz32M8ffz1fpLnc08j3nzcRe5wUdL2AxfT+wKMII+Dn99GtCVgcdDW4jSXDMRUwrBkGocGC2OA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-linux-x64-musl": { - "version": "2.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.0-rc.3.tgz", - "integrity": "sha512-r7mRi8q8TqTFVjb9kAsU7IgwUgno2s8Ip4xwq9psQhlRE3JGEZQmSEcy1jqTjfl6KFh6lJcDR7l+9/EMhL/D3Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-win32-arm64-msvc": { - "version": "2.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.0.0-rc.3.tgz", - "integrity": "sha512-2J6KjmDIQCw6HF1X6/yPcd+JLl7pxrH2zVMGmNllaoWhHeByvRobqFWnT7gcdHaA3dGTo432CwWvOgTgrINQpQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-win32-ia32-msvc": { - "version": "2.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.0.0-rc.3.tgz", - "integrity": "sha512-8q75CsHDSEDdgi6xPwim+BaQZFCswK2Dn/qL38V3Mh9kmVvC8oGJMPC66bC20dF+v3KWeFm2FNNGQqOSXCveHg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/cli-win32-x64-msvc": { - "version": "2.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.0.0-rc.3.tgz", - "integrity": "sha512-qeBRJYalahxEXolekcpZJ/HBrIJacG2NWJBGhhi797mIwnbmlpbHMc8blIJtNNNwVUb2BjXuxKQVfojQ5YYrcg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tauri-apps/plugin-autostart": { - "version": "2.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-autostart/-/plugin-autostart-2.0.0-rc.0.tgz", - "integrity": "sha512-V49lm++vhrMPPDGMtmOcbJLF4TYu78ZmAiMhyd4FFnbYlgin6ZTjiMCFEl4JKVy2lqP3C8DQvXf/gkUMuER7Iw==", - "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.0" - } - }, - "node_modules/@tauri-apps/plugin-deep-link": { - "version": "2.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-deep-link/-/plugin-deep-link-2.0.0-rc.0.tgz", - "integrity": "sha512-LdwxGeQAkxbOYBcamfOT6hAokstkhKz7t5mZcm5wCoUSTPIzMX/+7lNS8hsQouiTg7EXCXGaLW3nzwF9qwMA6g==", - "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.0" - } - }, - "node_modules/@tauri-apps/plugin-dialog": { - "version": "2.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.0-rc.0.tgz", - "integrity": "sha512-DPOXYe8SQ6Radk/67EOdaomlxL7oF99JO/ZUaPp1IBEs3Wro7lhlz63CfdKIBfKIZTLJLzP1R7/EiPL/GTA3Bg==", - "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.0" - } - }, - "node_modules/@tauri-apps/plugin-fs": { - "version": "2.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.0.0-rc.0.tgz", - "integrity": "sha512-74VCXEZlzTJ+Jv1V3KrV0qIHhSePpE/ljsF78rcEuvSfyTxLtt/Sb5CIUmVhFlKTRFOH9dX50T4dTZ3qFLyRnA==", - "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.0" - } - }, - "node_modules/@tauri-apps/plugin-log": { - "version": "2.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-log/-/plugin-log-2.0.0-rc.0.tgz", - "integrity": "sha512-ztKfzUcq03dtr08vBu+xcwIEPusP6mCpuLAt6kpXEwG+HvYsC8e1/KFFokn3xvfwD+oBJ3UTL1h4kdM30GAqGw==", - "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.0" - } - }, - "node_modules/@tauri-apps/plugin-process": { - "version": "2.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-process/-/plugin-process-2.0.0-rc.0.tgz", - "integrity": "sha512-Z12D/kmQzG1vCVf+jLXPhPDUA0pEjFrsg4p0uwO2sotVLM9287IuTM+aIz9cuAYOxFLKcsnDG7amSCL9IfA1gw==", - "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.0" - } - }, - "node_modules/@tauri-apps/plugin-shell": { - "version": "2.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.0-rc.0.tgz", - "integrity": "sha512-bhUcQcrqZoK8H1DFXapr5r1Z75oh6Kd5Tltz97XpZFLREEqp+KhN2Fvyh8r/fKAyenYsTYUIsDsyGdjdueuF9g==", - "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.0" - } - }, - "node_modules/@tauri-apps/plugin-updater": { - "version": "2.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-updater/-/plugin-updater-2.0.0-rc.0.tgz", - "integrity": "sha512-EKajf/sBpFif0cwXhTo3BmNvTZ2t2DDLRyhA8FFKugZNoOeqU97bHhPT5DIqMUPRE1tyDk9o7sXm8dKf7oz+EA==", - "dependencies": { - "@tauri-apps/api": "^2.0.0-rc.0" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/conventional-commits-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", - "integrity": "sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "29.5.12", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", - "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", - "dev": true, - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "node_modules/@types/js-yaml": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", - "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "node_modules/@types/lodash": { - "version": "4.17.6", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.6.tgz", - "integrity": "sha512-OpXEVoCKSS3lQqjx9GGGOapBeuW5eUboYHRlHP9urXPX25IKZ6AnP5ZRxtVf63iieUbsHxLn8NQ5Nlftc6yzAA==", - "dev": true - }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", - "dev": true - }, - "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "dev": true - }, - "node_modules/@types/react": { - "version": "18.3.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", - "dev": true, - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true - }, - "node_modules/@types/use-sync-external-store": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", - "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==", - "dev": true - }, - "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz", - "integrity": "sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/type-utils": "7.14.1", - "@typescript-eslint/utils": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", - "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", - "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", - "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/typescript-estree": "7.14.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz", - "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/typescript-estree": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", - "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", - "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.14.1.tgz", - "integrity": "sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "7.14.1", - "@typescript-eslint/utils": "7.14.1", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", - "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", - "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", - "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/typescript-estree": "7.14.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", - "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "dev": true, - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/antd": { - "version": "5.18.3", - "resolved": "https://registry.npmjs.org/antd/-/antd-5.18.3.tgz", - "integrity": "sha512-Dm3P8HBxoo/DiR/QZLj5Mk+rQZsSXxCCArSZACHGiklkkjW6klzlebAElOUr9NyDeFX7UnQ6LVk7vznXlnjTqQ==", - "dev": true, - "dependencies": { - "@ant-design/colors": "^7.0.2", - "@ant-design/cssinjs": "^1.21.0", - "@ant-design/icons": "^5.3.7", - "@ant-design/react-slick": "~1.1.2", - "@babel/runtime": "^7.24.7", - "@ctrl/tinycolor": "^3.6.1", - "@rc-component/color-picker": "~1.5.3", - "@rc-component/mutate-observer": "^1.1.0", - "@rc-component/tour": "~1.15.0", - "@rc-component/trigger": "^2.2.0", - "classnames": "^2.5.1", - "copy-to-clipboard": "^3.3.3", - "dayjs": "^1.11.11", - "qrcode.react": "^3.1.0", - "rc-cascader": "~3.26.0", - "rc-checkbox": "~3.3.0", - "rc-collapse": "~3.7.3", - "rc-dialog": "~9.5.2", - "rc-drawer": "~7.2.0", - "rc-dropdown": "~4.2.0", - "rc-field-form": "~2.2.1", - "rc-image": "~7.9.0", - "rc-input": "~1.5.1", - "rc-input-number": "~9.1.0", - "rc-mentions": "~2.14.0", - "rc-menu": "~9.14.0", - "rc-motion": "^2.9.2", - "rc-notification": "~5.6.0", - "rc-pagination": "~4.0.4", - "rc-picker": "~4.5.0", - "rc-progress": "~4.0.0", - "rc-rate": "~2.13.0", - "rc-resize-observer": "^1.4.0", - "rc-segmented": "~2.3.0", - "rc-select": "~14.14.0", - "rc-slider": "~10.6.2", - "rc-steps": "~6.0.1", - "rc-switch": "~4.1.0", - "rc-table": "~7.45.7", - "rc-tabs": "~15.1.1", - "rc-textarea": "~1.7.0", - "rc-tooltip": "~6.2.0", - "rc-tree": "~5.8.8", - "rc-tree-select": "~5.21.0", - "rc-upload": "~4.5.2", - "rc-util": "^5.43.0", - "scroll-into-view-if-needed": "^3.1.0", - "throttle-debounce": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/ant-design" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true - }, - "node_modules/array-tree-filter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz", - "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==", - "dev": true - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "dev": true, - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/call-me-maybe": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", - "dev": true - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001638", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001638.tgz", - "integrity": "sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", - "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", - "dev": true - }, - "node_modules/classnames": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", - "dev": true - }, - "node_modules/cli-color": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", - "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.64", - "es6-iterator": "^2.0.3", - "memoizee": "^0.4.15", - "timers-ext": "^0.1.7" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": true, - "dependencies": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" - } - }, - "node_modules/complex.js": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.1.1.tgz", - "integrity": "sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==", - "dev": true, - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://www.patreon.com/infusion" - } - }, - "node_modules/compute-scroll-into-view": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz", - "integrity": "sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/conventional-changelog-angular": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", - "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/conventional-changelog-conventionalcommits": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz", - "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/conventional-commits-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", - "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", - "dev": true, - "dependencies": { - "is-text-path": "^2.0.0", - "JSONStream": "^1.3.5", - "meow": "^12.0.1", - "split2": "^4.0.0" - }, - "bin": { - "conventional-commits-parser": "cli.mjs" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "dev": true, - "dependencies": { - "toggle-selection": "^1.0.6" - } - }, - "node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", - "dev": true, - "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/cosmiconfig-typescript-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz", - "integrity": "sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==", - "dev": true, - "dependencies": { - "jiti": "^1.19.1" - }, - "engines": { - "node": ">=v16" - }, - "peerDependencies": { - "@types/node": "*", - "cosmiconfig": ">=8.2", - "typescript": ">=4" - } - }, - "node_modules/create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true - }, - "node_modules/d": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", - "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", - "dev": true, - "dependencies": { - "es5-ext": "^0.10.64", - "type": "^2.7.2" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/dargs": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz", - "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dayjs": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", - "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==", - "dev": true - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true - }, - "node_modules/dedent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", - "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", - "dev": true, - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.814", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.814.tgz", - "integrity": "sha512-GVulpHjFu1Y9ZvikvbArHmAhZXtm3wHlpjTMcXNGKl4IQ4jMQjlnz8yMQYYqdLHKi/jEL2+CBC2akWVCoIGUdw==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es5-ext": { - "version": "0.10.64", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", - "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "esniff": "^2.0.1", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", - "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", - "dev": true, - "dependencies": { - "d": "^1.0.2", - "ext": "^1.7.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-latex": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", - "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==", - "dev": true - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-simple-import-sort": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.0.tgz", - "integrity": "sha512-Y2fqAfC11TcG/WP3TrI1Gi3p3nc8XJyEOJYHyEPEGI/UAgNx6akxxlX74p7SbAQdLcgASKhj8M0GKvH3vq/+ig==", - "dev": true, - "peerDependencies": { - "eslint": ">=5.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/esniff": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", - "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.62", - "event-emitter": "^0.3.5", - "type": "^2.7.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, - "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "dependencies": { - "type": "^2.7.2" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/fraction.js": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.4.tgz", - "integrity": "sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q==", - "dev": true, - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/framer-motion": { - "version": "11.3.6", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.3.6.tgz", - "integrity": "sha512-olpX48qfoSIDjhw0RbolhOGBQmdMAXHHpSI0PFdTj5LeXChcf5F4ApShs0mQ6FPEPOj7dnEvSyB07UgRK5G9Jw==", - "dev": true, - "dependencies": { - "tslib": "^2.4.0" - }, - "peerDependencies": { - "@emotion/is-prop-valid": "*", - "react": "^18.0.0", - "react-dom": "^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/is-prop-valid": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - } - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/git-raw-commits": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz", - "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==", - "dev": true, - "dependencies": { - "dargs": "^8.0.0", - "meow": "^12.0.1", - "split2": "^4.0.0" - }, - "bin": { - "git-raw-commits": "cli.mjs" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-promise": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-4.2.2.tgz", - "integrity": "sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.3" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "type": "individual", - "url": "https://github.com/sponsors/ahmadnassri" - }, - "peerDependencies": { - "glob": "^7.1.6" - } - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/global-directory": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", - "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", - "dev": true, - "dependencies": { - "ini": "4.1.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/google-translate-api-x": { - "version": "10.6.8", - "resolved": "https://registry.npmjs.org/google-translate-api-x/-/google-translate-api-x-10.6.8.tgz", - "integrity": "sha512-vlXnCQhMcy00P2uX/mK3NzJb4HBMhoKo39PSmupiiVKLgsAZp8b22OV48dcAUxykAuPxQreyBYz4P6jFCzeZjA==", - "dev": true, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/AidanWelch" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/html-parse-stringify": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", - "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", - "dev": true, - "dependencies": { - "void-elements": "3.1.0" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/i18next": { - "version": "23.12.2", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.12.2.tgz", - "integrity": "sha512-XIeh5V+bi8SJSWGL3jqbTEBW5oD6rbP5L+E7dVQh1MNTxxYef0x15rhJVcRb7oiuq4jLtgy2SD8eFlf6P2cmqg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://locize.com" - }, - { - "type": "individual", - "url": "https://locize.com/i18next.html" - }, - { - "type": "individual", - "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" - } - ], - "dependencies": { - "@babel/runtime": "^7.23.2" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "dev": true - }, - "node_modules/immer": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz", - "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-meta-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", - "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", - "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", - "dev": true, - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-text-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", - "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", - "dev": true, - "dependencies": { - "text-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", - "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/javascript-natural-sort": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", - "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", - "dev": true - }, - "node_modules/jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", - "dev": true, - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", - "dev": true, - "dependencies": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-cli": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", - "dev": true, - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-each": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-leak-detector": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", - "dev": true, - "dependencies": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", - "dev": true, - "dependencies": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runner": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", - "dev": true, - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", - "dev": true, - "dependencies": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", - "dev": true, - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-to-typescript": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-13.1.2.tgz", - "integrity": "sha512-17G+mjx4nunvOpkPvcz7fdwUwYCEwyH8vR3Ym3rFiQ8uzAL3go+c1306Kk7iGRk8HuXBXqy+JJJmpYl0cvOllw==", - "dev": true, - "dependencies": { - "@bcherny/json-schema-ref-parser": "10.0.5-fork", - "@types/json-schema": "^7.0.11", - "@types/lodash": "^4.14.182", - "@types/prettier": "^2.6.1", - "cli-color": "^2.0.2", - "get-stdin": "^8.0.0", - "glob": "^7.1.6", - "glob-promise": "^4.2.2", - "is-glob": "^4.0.3", - "lodash": "^4.17.21", - "minimist": "^1.2.6", - "mkdirp": "^1.0.4", - "mz": "^2.7.0", - "prettier": "^2.6.2" - }, - "bin": { - "json2ts": "dist/src/cli.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json2mq": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", - "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==", - "dev": true, - "dependencies": { - "string-convert": "^0.2.0" - } - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true, - "engines": [ - "node >= 0.2.0" - ] - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/lefthook": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/lefthook/-/lefthook-1.6.18.tgz", - "integrity": "sha512-Ftr/NkU1P1EsEyphsCqCX7lesGZA+QDXyUx4dS1RlSKB72xKtGW9VPjbGLK2kSQkONG5M+XYfbJkGA/r9NLTYQ==", - "dev": true, - "hasInstallScript": true, - "bin": { - "lefthook": "bin/index.js" - }, - "optionalDependencies": { - "lefthook-darwin-arm64": "1.6.18", - "lefthook-darwin-x64": "1.6.18", - "lefthook-freebsd-arm64": "1.6.18", - "lefthook-freebsd-x64": "1.6.18", - "lefthook-linux-arm64": "1.6.18", - "lefthook-linux-x64": "1.6.18", - "lefthook-windows-arm64": "1.6.18", - "lefthook-windows-x64": "1.6.18" - } - }, - "node_modules/lefthook-darwin-arm64": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/lefthook-darwin-arm64/-/lefthook-darwin-arm64-1.6.18.tgz", - "integrity": "sha512-AkpsTeO7aLZIIy6CKQ7Chx8RltE8a9uItbwQWoeaCkIdzpV8TFjq7/Pw4F5CkoJ2315sHtB8k+VFkgipQMBw1w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/lefthook-darwin-x64": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/lefthook-darwin-x64/-/lefthook-darwin-x64-1.6.18.tgz", - "integrity": "sha512-qwKa+PaNIYjZ2PVrRRLq+HjNjQsjEItXN21byvSD89r7EYCULsIC8aW4H6aniOP2A6X1DIZ+djpg+3hNJ/94NA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/lefthook-freebsd-arm64": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/lefthook-freebsd-arm64/-/lefthook-freebsd-arm64-1.6.18.tgz", - "integrity": "sha512-UIOzQ+okwB7Ah9p8sNqomOiU6cPfmJnyW3HDPutRsdoHRD8udIap9d+ja4Kg4m/PkoYtkcLO78omANqAgA5wxQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/lefthook-freebsd-x64": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/lefthook-freebsd-x64/-/lefthook-freebsd-x64-1.6.18.tgz", - "integrity": "sha512-UQANUgyNpaAh0+2/PjPFiJ7yd6aF15yyJxKZCXyna5cQF7VU8pSHu5tiDDquNpjToXOg+6TmiIAJKyfrrwTF3w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/lefthook-linux-arm64": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/lefthook-linux-arm64/-/lefthook-linux-arm64-1.6.18.tgz", - "integrity": "sha512-4erletIa2HKUgY17/1ROvndAj6xn/9wkqO2GhBT3C0vFwIv6ycy5wpFzXOwKRZpFYv7UacN7iXhAZSK+vSOZZg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/lefthook-linux-x64": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/lefthook-linux-x64/-/lefthook-linux-x64-1.6.18.tgz", - "integrity": "sha512-l5SRqYMYygw9RjZncEg8uh29wShYN8kiYr53sp74DkntrlCttqWhLILBUlIr3fxH5s0ZyrmqUEjtMBryMk7b/g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/lefthook-windows-arm64": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/lefthook-windows-arm64/-/lefthook-windows-arm64-1.6.18.tgz", - "integrity": "sha512-jeNBRoya3+mOEsKyT4wXf29Kng1nkJD7Uv/dqGBszoGMktGVNUFdIjWoxx6HSfhUssucs5pKRZpXSMgK/KCP+Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/lefthook-windows-x64": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/lefthook-windows-x64/-/lefthook-windows-x64-1.6.18.tgz", - "integrity": "sha512-iEG8PbFOwMqlpAgCiqzANTxutERjwlwMx6WF6HDGEYwFJSCJsvi06TehDxaPIFbhmLLYYlbVrfSBlttWGoN0dg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true - }, - "node_modules/lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", - "dev": true - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.mergewith": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true - }, - "node_modules/lodash.snakecase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", - "dev": true - }, - "node_modules/lodash.startcase": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", - "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", - "dev": true - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", - "dev": true - }, - "node_modules/lodash.upperfirst": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", - "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", - "dev": true - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", - "dev": true, - "dependencies": { - "es5-ext": "~0.10.2" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/mathjs": { - "version": "12.4.3", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-12.4.3.tgz", - "integrity": "sha512-oHdGPDbp7gO873xxG90RLq36IuicuKvbpr/bBG5g9c8Obm/VsKVrK9uoRZZHUodohzlnmCEqfDzbR3LH6m+aAQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.24.4", - "complex.js": "^2.1.1", - "decimal.js": "^10.4.3", - "escape-latex": "^1.2.0", - "fraction.js": "4.3.4", - "javascript-natural-sort": "^0.7.1", - "seedrandom": "^3.0.5", - "tiny-emitter": "^2.1.0", - "typed-function": "^4.1.1" - }, - "bin": { - "mathjs": "bin/cli.js" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/memoizee": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", - "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", - "dev": true, - "dependencies": { - "d": "^1.0.2", - "es5-ext": "^0.10.64", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/meow": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", - "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", - "dev": true, - "engines": { - "node": ">=16.10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dev": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, - "node_modules/nodemon": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz", - "integrity": "sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==", - "dev": true, - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^4", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^7.5.3", - "simple-update-notifier": "^2.0.0", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/nodemon/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/nodemon/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/nodemon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true - }, - "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pure-rand": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", - "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ] - }, - "node_modules/qrcode.react": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz", - "integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==", - "dev": true, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/rc-cascader": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.26.0.tgz", - "integrity": "sha512-L1dml383TPSJD1I11YwxuVbmqaJY64psZqFp1ETlgl3LEOwDu76Cyl11fw5dmjJhMlUWwM5dECQfqJgfebhUjg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.12.5", - "array-tree-filter": "^2.1.0", - "classnames": "^2.3.1", - "rc-select": "~14.14.0", - "rc-tree": "~5.8.1", - "rc-util": "^5.37.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-checkbox": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-3.3.0.tgz", - "integrity": "sha512-Ih3ZaAcoAiFKJjifzwsGiT/f/quIkxJoklW4yKGho14Olulwn8gN7hOBve0/WGDg5o/l/5mL0w7ff7/YGvefVw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "^2.3.2", - "rc-util": "^5.25.2" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-collapse": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.7.3.tgz", - "integrity": "sha512-60FJcdTRn0X5sELF18TANwtVi7FtModq649H11mYF1jh83DniMoM4MqY627sEKRCTm4+WXfGDcB7hY5oW6xhyw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "2.x", - "rc-motion": "^2.3.4", - "rc-util": "^5.27.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-dialog": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-9.5.2.tgz", - "integrity": "sha512-qVUjc8JukG+j/pNaHVSRa2GO2/KbV2thm7yO4hepQ902eGdYK913sGkwg/fh9yhKYV1ql3BKIN2xnud3rEXAPw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "@rc-component/portal": "^1.0.0-8", - "classnames": "^2.2.6", - "rc-motion": "^2.3.0", - "rc-util": "^5.21.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-drawer": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-7.2.0.tgz", - "integrity": "sha512-9lOQ7kBekEJRdEpScHvtmEtXnAsy+NGDXiRWc2ZVC7QXAazNVbeT4EraQKYwCME8BJLa8Bxqxvs5swwyOepRwg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.23.9", - "@rc-component/portal": "^1.1.1", - "classnames": "^2.2.6", - "rc-motion": "^2.6.1", - "rc-util": "^5.38.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-dropdown": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-4.2.0.tgz", - "integrity": "sha512-odM8Ove+gSh0zU27DUj5cG1gNKg7mLWBYzB5E4nNLrLwBmYEgYP43vHKDGOVZcJSVElQBI0+jTQgjnq0NfLjng==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.18.3", - "@rc-component/trigger": "^2.0.0", - "classnames": "^2.2.6", - "rc-util": "^5.17.0" - }, - "peerDependencies": { - "react": ">=16.11.0", - "react-dom": ">=16.11.0" - } - }, - "node_modules/rc-field-form": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-2.2.1.tgz", - "integrity": "sha512-uoNqDoR7A4tn4QTSqoWPAzrR7ZwOK5I+vuZ/qdcHtbKx+ZjEsTg7QXm2wk/jalDiSksAQmATxL0T5LJkRREdIA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.18.0", - "@rc-component/async-validator": "^5.0.3", - "rc-util": "^5.32.2" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-image": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-7.9.0.tgz", - "integrity": "sha512-l4zqO5E0quuLMCtdKfBgj4Suv8tIS011F5k1zBBlK25iMjjiNHxA0VeTzGFtUZERSA45gvpXDg8/P6qNLjR25g==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.11.2", - "@rc-component/portal": "^1.0.2", - "classnames": "^2.2.6", - "rc-dialog": "~9.5.2", - "rc-motion": "^2.6.2", - "rc-util": "^5.34.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-input": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.5.1.tgz", - "integrity": "sha512-+nOzQJDeIfIpNP/SgY45LXSKbuMlp4Yap2y8c+ZpU7XbLmNzUd6+d5/S75sA/52jsVE6S/AkhkkDEAOjIu7i6g==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.11.1", - "classnames": "^2.2.1", - "rc-util": "^5.18.1" - }, - "peerDependencies": { - "react": ">=16.0.0", - "react-dom": ">=16.0.0" - } - }, - "node_modules/rc-input-number": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-9.1.0.tgz", - "integrity": "sha512-NqJ6i25Xn/AgYfVxynlevIhX3FuKlMwIFpucGG1h98SlK32wQwDK0zhN9VY32McOmuaqzftduNYWWooWz8pXQA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "@rc-component/mini-decimal": "^1.0.1", - "classnames": "^2.2.5", - "rc-input": "~1.5.0", - "rc-util": "^5.40.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-mentions": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.14.0.tgz", - "integrity": "sha512-qKR59FMuF8PK4ZqsbWX3UuA5P1M/snzyqV6Yt3y1DCFbCEdqUGIBgQp6vEfLCO6Z0RoRFlzXtCeSlBTcDDpg1A==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.22.5", - "@rc-component/trigger": "^2.0.0", - "classnames": "^2.2.6", - "rc-input": "~1.5.0", - "rc-menu": "~9.14.0", - "rc-textarea": "~1.7.0", - "rc-util": "^5.34.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-menu": { - "version": "9.14.1", - "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.14.1.tgz", - "integrity": "sha512-5wlRb3M8S4yGlWhSoEYJ7ZVRElyScdcpUHxgiLxkeig1tEdyKrnED3B2fhpN0Rrpdp9jyhnmZR/Lwq2fH5VvDQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "@rc-component/trigger": "^2.0.0", - "classnames": "2.x", - "rc-motion": "^2.4.3", - "rc-overflow": "^1.3.1", - "rc-util": "^5.27.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-motion": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.2.tgz", - "integrity": "sha512-fUAhHKLDdkAXIDLH0GYwof3raS58dtNUmzLF2MeiR8o6n4thNpSDQhOqQzWE4WfFZDCi9VEN8n7tiB7czREcyw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.11.1", - "classnames": "^2.2.1", - "rc-util": "^5.43.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-notification": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-5.6.0.tgz", - "integrity": "sha512-TGQW5T7waOxLwgJG7fXcw8l7AQiFOjaZ7ISF5PrU526nunHRNcTMuzKihQHaF4E/h/KfOCDk3Mv8eqzbu2e28w==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "2.x", - "rc-motion": "^2.9.0", - "rc-util": "^5.20.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-overflow": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/rc-overflow/-/rc-overflow-1.3.2.tgz", - "integrity": "sha512-nsUm78jkYAoPygDAcGZeC2VwIg/IBGSodtOY3pMof4W3M9qRJgqaDYm03ZayHlde3I6ipliAxbN0RUcGf5KOzw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.11.1", - "classnames": "^2.2.1", - "rc-resize-observer": "^1.0.0", - "rc-util": "^5.37.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-pagination": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-4.0.4.tgz", - "integrity": "sha512-GGrLT4NgG6wgJpT/hHIpL9nELv27A1XbSZzECIuQBQTVSf4xGKxWr6I/jhpRPauYEWEbWVw22ObG6tJQqwJqWQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "^2.3.2", - "rc-util": "^5.38.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-picker": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-4.5.0.tgz", - "integrity": "sha512-suqz9bzuhBQlf7u+bZd1bJLPzhXpk12w6AjQ9BTPTiFwexVZgUKViG1KNLyfFvW6tCUZZK0HmCCX7JAyM+JnCg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "@rc-component/trigger": "^2.0.0", - "classnames": "^2.2.1", - "rc-overflow": "^1.3.2", - "rc-resize-observer": "^1.4.0", - "rc-util": "^5.38.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "date-fns": ">= 2.x", - "dayjs": ">= 1.x", - "luxon": ">= 3.x", - "moment": ">= 2.x", - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - }, - "peerDependenciesMeta": { - "date-fns": { - "optional": true - }, - "dayjs": { - "optional": true - }, - "luxon": { - "optional": true - }, - "moment": { - "optional": true - } - } - }, - "node_modules/rc-progress": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-4.0.0.tgz", - "integrity": "sha512-oofVMMafOCokIUIBnZLNcOZFsABaUw8PPrf1/y0ZBvKZNpOiu5h4AO9vv11Sw0p4Hb3D0yGWuEattcQGtNJ/aw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "^2.2.6", - "rc-util": "^5.16.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-rate": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.13.0.tgz", - "integrity": "sha512-oxvx1Q5k5wD30sjN5tqAyWTvJfLNNJn7Oq3IeS4HxWfAiC4BOXMITNAsw7u/fzdtO4MS8Ki8uRLOzcnEuoQiAw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "^2.2.5", - "rc-util": "^5.0.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-resize-observer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.4.0.tgz", - "integrity": "sha512-PnMVyRid9JLxFavTjeDXEXo65HCRqbmLBw9xX9gfC4BZiSzbLXKzW3jPz+J0P71pLbD5tBMTT+mkstV5gD0c9Q==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.7", - "classnames": "^2.2.1", - "rc-util": "^5.38.0", - "resize-observer-polyfill": "^1.5.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-segmented": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/rc-segmented/-/rc-segmented-2.3.0.tgz", - "integrity": "sha512-I3FtM5Smua/ESXutFfb8gJ8ZPcvFR+qUgeeGFQHBOvRiRKyAk4aBE5nfqrxXx+h8/vn60DQjOt6i4RNtrbOobg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.11.1", - "classnames": "^2.2.1", - "rc-motion": "^2.4.4", - "rc-util": "^5.17.0" - }, - "peerDependencies": { - "react": ">=16.0.0", - "react-dom": ">=16.0.0" - } - }, - "node_modules/rc-select": { - "version": "14.14.0", - "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.14.0.tgz", - "integrity": "sha512-Uo2wulrjoPPRLCPd7zlK4ZFVJxlTN//yp1xWP/U+TUOQCyXrT+Duvq/Si5OzVcmQyWAUSbsplc2OwNNhvbOeKQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "@rc-component/trigger": "^2.1.1", - "classnames": "2.x", - "rc-motion": "^2.0.1", - "rc-overflow": "^1.3.1", - "rc-util": "^5.16.1", - "rc-virtual-list": "^3.5.2" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/rc-slider": { - "version": "10.6.2", - "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-10.6.2.tgz", - "integrity": "sha512-FjkoFjyvUQWcBo1F3RgSglky3ar0+qHLM41PlFVYB4Bj3RD8E/Mv7kqMouLFBU+3aFglMzzctAIWRwajEuueSw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "^2.2.5", - "rc-util": "^5.36.0" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-steps": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/rc-steps/-/rc-steps-6.0.1.tgz", - "integrity": "sha512-lKHL+Sny0SeHkQKKDJlAjV5oZ8DwCdS2hFhAkIjuQt1/pB81M0cA0ErVFdHq9+jmPmFw1vJB2F5NBzFXLJxV+g==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.7", - "classnames": "^2.2.3", - "rc-util": "^5.16.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-switch": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-4.1.0.tgz", - "integrity": "sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.21.0", - "classnames": "^2.2.1", - "rc-util": "^5.30.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-table": { - "version": "7.45.7", - "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.45.7.tgz", - "integrity": "sha512-wi9LetBL1t1csxyGkMB2p3mCiMt+NDexMlPbXHvQFmBBAsMxrgNSAPwUci2zDLUq9m8QdWc1Nh8suvrpy9mXrg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "@rc-component/context": "^1.4.0", - "classnames": "^2.2.5", - "rc-resize-observer": "^1.1.0", - "rc-util": "^5.37.0", - "rc-virtual-list": "^3.14.2" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-tabs": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-15.1.1.tgz", - "integrity": "sha512-Tc7bJvpEdkWIVCUL7yQrMNBJY3j44NcyWS48jF/UKMXuUlzaXK+Z/pEL5LjGcTadtPvVmNqA40yv7hmr+tCOAw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.11.2", - "classnames": "2.x", - "rc-dropdown": "~4.2.0", - "rc-menu": "~9.14.0", - "rc-motion": "^2.6.2", - "rc-resize-observer": "^1.0.0", - "rc-util": "^5.34.1" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-textarea": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.7.0.tgz", - "integrity": "sha512-UxizYJkWkmxP3zofXgc487QiGyDmhhheDLLjIWbFtDmiru1ls30KpO8odDaPyqNUIy9ugj5djxTEuezIn6t3Jg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "^2.2.1", - "rc-input": "~1.5.0", - "rc-resize-observer": "^1.0.0", - "rc-util": "^5.27.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-tooltip": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-6.2.0.tgz", - "integrity": "sha512-iS/3iOAvtDh9GIx1ulY7EFUXUtktFccNLsARo3NPgLf0QW9oT0w3dA9cYWlhqAKmD+uriEwdWz1kH0Qs4zk2Aw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.11.2", - "@rc-component/trigger": "^2.0.0", - "classnames": "^2.3.1" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-tree": { - "version": "5.8.8", - "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.8.8.tgz", - "integrity": "sha512-S+mCMWo91m5AJqjz3PdzKilGgbFm7fFJRFiTDOcoRbD7UfMOPnerXwMworiga0O2XIo383UoWuEfeHs1WOltag==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "2.x", - "rc-motion": "^2.0.1", - "rc-util": "^5.16.1", - "rc-virtual-list": "^3.5.1" - }, - "engines": { - "node": ">=10.x" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/rc-tree-select": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.21.0.tgz", - "integrity": "sha512-w+9qEu6zh0G3wt9N/hzWNSnqYH1i9mH1Nqxo0caxLRRFXF5yZWYmpCDoDTMdQM1Y4z3Q5yj08qyrPH/d4AtumA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.1", - "classnames": "2.x", - "rc-select": "~14.14.0", - "rc-tree": "~5.8.1", - "rc-util": "^5.16.1" - }, - "peerDependencies": { - "react": "*", - "react-dom": "*" - } - }, - "node_modules/rc-upload": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.5.2.tgz", - "integrity": "sha512-QO3ne77DwnAPKFn0bA5qJM81QBjQi0e0NHdkvpFyY73Bea2NfITiotqJqVjHgeYPOJu5lLVR32TNGP084aSoXA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.18.3", - "classnames": "^2.2.5", - "rc-util": "^5.2.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-util": { - "version": "5.43.0", - "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.43.0.tgz", - "integrity": "sha512-AzC7KKOXFqAdIBqdGWepL9Xn7cm3vnAmjlHqUnoQaTMZYhM4VlXGLkkHHxj/BZ7Td0+SOPKB4RGPboBVKT9htw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.18.3", - "react-is": "^18.2.0" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/rc-virtual-list": { - "version": "3.14.5", - "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.14.5.tgz", - "integrity": "sha512-ZMOnkCLv2wUN8Jz7yI4XiSLa9THlYvf00LuMhb1JlsQCewuU7ydPuHw1rGVPhe9VZYl/5UqODtNd7QKJ2DMGfg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.20.0", - "classnames": "^2.2.6", - "rc-resize-observer": "^1.0.0", - "rc-util": "^5.36.0" - }, - "engines": { - "node": ">=8.x" - }, - "peerDependencies": { - "react": ">=16.9.0", - "react-dom": ">=16.9.0" - } - }, - "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/react-i18next": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.0.0.tgz", - "integrity": "sha512-2O3IgF4zivg57Q6p6i+ChDgJ371IDcEWbuWC6gvoh5NbkDMs0Q+O7RPr4v61+Se32E0V+LmtwePAeqWZW0bi6g==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.24.8", - "html-parse-stringify": "^3.0.1" - }, - "peerDependencies": { - "i18next": ">= 23.2.3", - "react": ">= 16.8.0" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - } - } - }, - "node_modules/react-icons": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", - "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", - "dev": true, - "peerDependencies": { - "react": "*" - } - }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true - }, - "node_modules/react-redux": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz", - "integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==", - "dev": true, - "dependencies": { - "@types/use-sync-external-store": "^0.0.3", - "use-sync-external-store": "^1.0.0" - }, - "peerDependencies": { - "@types/react": "^18.2.25", - "react": "^18.0", - "redux": "^5.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "redux": { - "optional": true - } - } - }, - "node_modules/readable-test-for-types": { - "resolved": "node_modules/readable-types/rtt-plugin", - "link": true - }, - "node_modules/readable-types": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/readable-types/-/readable-types-4.0.3.tgz", - "integrity": "sha512-1cwEnwK0iXY1h/4f5bTGr2cE3w3y21BNLF2XiZcB235u+soALHRqyDEGzh/VQrzf8E7dCzImsjo5maH7FEaLeg==", - "dev": true, - "dependencies": { - "readable-test-for-types": "file:./rtt-plugin", - "typescript": "^4.2 || ^5.0" - }, - "bin": { - "rtft": "rtt-plugin/dist/run-tests.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/readable-types/rtt-plugin": { - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4" - }, - "bin": { - "rtft": "dist/run-tests.js" - }, - "peerDependencies": { - "typescript": "^4.2 || ^5.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/redux": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", - "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", - "dev": true - }, - "node_modules/redux-thunk": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", - "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", - "dev": true, - "peerDependencies": { - "redux": "^5.0.0" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/reselect": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", - "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", - "dev": true - }, - "node_modules/resize-observer-polyfill": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", - "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/scroll-into-view-if-needed": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz", - "integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==", - "dev": true, - "dependencies": { - "compute-scroll-into-view": "^3.0.2" - } - }, - "node_modules/seedrandom": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", - "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", - "dev": true - }, - "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "dev": true, - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-convert": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", - "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==", - "dev": true - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stylis": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", - "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", - "dev": true - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/text-extensions": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", - "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/throttle-debounce": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz", - "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==", - "dev": true, - "engines": { - "node": ">=12.22" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/timers-ext": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz", - "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==", - "dev": true, - "dependencies": { - "es5-ext": "^0.10.64", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", - "dev": true - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", - "dev": true - }, - "node_modules/toml": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", - "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", - "dev": true - }, - "node_modules/touch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", - "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", - "dev": true, - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-jest": { - "version": "29.1.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.5.tgz", - "integrity": "sha512-UuClSYxM7byvvYfyWdFI+/2UxMmwNyJb0NPkZPQE2hew3RurV7l7zURgOHAd/1I1ZdPpe3GUsXNXAcN8TFKSIg==", - "dev": true, - "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", - "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "^7.5.3", - "yargs-parser": "^21.0.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/transform": "^29.0.0", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3 <6" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/transform": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", - "dev": true - }, - "node_modules/type": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", - "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-function": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.1.tgz", - "integrity": "sha512-EGjWssW7Tsk4DGfE+5yluuljS1OGYWiI1J6e8puZz9nTMM51Oug8CD5Zo4gWMsOhq5BI+1bF+rWTm4Vbj3ivRA==", - "dev": true, - "engines": { - "node": ">= 18" - } - }, - "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.14.1.tgz", - "integrity": "sha512-Eo1X+Y0JgGPspcANKjeR6nIqXl4VL5ldXLc15k4m9upq+eY5fhU2IueiEZL6jmHrKH8aCfbIvM/v3IrX5Hg99w==", - "dev": true, - "dependencies": { - "@typescript-eslint/eslint-plugin": "7.14.1", - "@typescript-eslint/parser": "7.14.1", - "@typescript-eslint/utils": "7.14.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", - "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", - "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", - "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/typescript-estree": "7.14.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "node_modules/unicorn-magic": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/use-sync-external-store": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", - "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", - "dev": true, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "node_modules/v8-to-istanbul": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", - "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/void-elements": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", - "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zod": { - "version": "3.23.8", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.23.1", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.23.1.tgz", - "integrity": "sha512-oT9INvydob1XV0v1d2IadrR74rLtDInLvDFfAa1CG0Pmg/vxATk7I2gSelfj271mbzeM4Da0uuDQE/Nkj3DWNw==", - "dev": true, - "peerDependencies": { - "zod": "^3.23.3" - } - } - } -} +{ + "name": "seelen-ui", + "version": "1.9.4", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "seelen-ui", + "version": "1.9.4", + "hasInstallScript": true, + "license": "Polyform Strict License", + "dependencies": { + "@tauri-apps/plugin-autostart": "^2.0.0-beta.2", + "@tauri-apps/plugin-deep-link": "^2.0.0-beta.10", + "@tauri-apps/plugin-dialog": "^2.0.0-beta.2", + "@tauri-apps/plugin-fs": "^2.0.0-beta.2", + "@tauri-apps/plugin-log": "^2.0.0-beta.2", + "@tauri-apps/plugin-process": "^2.0.0-beta.2", + "@tauri-apps/plugin-shell": "^2.0.0-beta.2", + "@tauri-apps/plugin-updater": "^2.0.0-beta.2" + }, + "devDependencies": { + "@commitlint/cli": "^19.3.0", + "@commitlint/config-conventional": "^19.2.2", + "@reduxjs/toolkit": "^2.2.1", + "@stylistic/eslint-plugin": "^1.6.2", + "@tauri-apps/api": "^2.0.0-beta.4", + "@tauri-apps/cli": "^2.0.0-beta.8", + "@types/jest": "^29.5.12", + "@types/js-yaml": "^4.0.9", + "@types/node": "^20.11.19", + "@types/react": "^18.2.56", + "@types/react-dom": "^18.2.19", + "antd": "^5.14.1", + "esbuild": "^0.20.1", + "eslint": "^8.56.0", + "eslint-plugin-simple-import-sort": "^12.0.0", + "framer-motion": "11.3.6", + "glob": "^7.2.3", + "google-translate-api-x": "^10.6.8", + "i18next": "^23.12.2", + "jest": "^29.7.0", + "js-yaml": "^4.1.0", + "json-schema-to-typescript": "^13.1.2", + "lefthook": "^1.6.18", + "lodash": "^4.17.21", + "mathjs": "^12.4.2", + "moment": "^2.30.1", + "nodemon": "^3.0.3", + "react": "18.2.0", + "react-dom": "18.2.0", + "react-i18next": "^15.0.0", + "react-icons": "^5.3.0", + "react-redux": "^9.1.0", + "readable-types": "^4.0.0", + "redux": "^5.0.1", + "toml": "^3.0.0", + "ts-jest": "^29.1.2", + "ts-node": "^10.9.2", + "typescript": "5.3.3", + "typescript-eslint": "^7.0.1", + "zod": "^3.23.4", + "zod-to-json-schema": "^3.23.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@ant-design/colors": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.0.2.tgz", + "integrity": "sha512-7KJkhTiPiLHSu+LmMJnehfJ6242OCxSlR3xHVBecYxnMW8MS/878NXct1GqYARyL59fyeFdKRxXTfvR9SnDgJg==", + "dev": true, + "dependencies": { + "@ctrl/tinycolor": "^3.6.1" + } + }, + "node_modules/@ant-design/cssinjs": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@ant-design/cssinjs/-/cssinjs-1.21.0.tgz", + "integrity": "sha512-gIilraPl+9EoKdYxnupxjHB/Q6IHNRjEXszKbDxZdsgv4sAZ9pjkCq8yanDWNvyfjp4leir2OVAJm0vxwKK8YA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.11.1", + "@emotion/hash": "^0.8.0", + "@emotion/unitless": "^0.7.5", + "classnames": "^2.3.1", + "csstype": "^3.1.3", + "rc-util": "^5.35.0", + "stylis": "^4.0.13" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/@ant-design/icons": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.3.7.tgz", + "integrity": "sha512-bCPXTAg66f5bdccM4TT21SQBDO1Ek2gho9h3nO9DAKXJP4sq+5VBjrQMSxMVXSB3HyEz+cUbHQ5+6ogxCOpaew==", + "dev": true, + "dependencies": { + "@ant-design/colors": "^7.0.0", + "@ant-design/icons-svg": "^4.4.0", + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-util": "^5.31.1" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/@ant-design/icons-svg": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz", + "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==", + "dev": true + }, + "node_modules/@ant-design/react-slick": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-1.1.2.tgz", + "integrity": "sha512-EzlvzE6xQUBrZuuhSAFTdsr4P2bBBHGZwKFemEfq8gIGyIQCxalYfZW/T2ORbtQx5rU69o+WycP3exY/7T1hGA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.4", + "classnames": "^2.2.5", + "json2mq": "^0.2.0", + "resize-observer-polyfill": "^1.5.1", + "throttle-debounce": "^5.0.0" + }, + "peerDependencies": { + "react": ">=16.9.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", + "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", + "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcherny/json-schema-ref-parser": { + "version": "10.0.5-fork", + "resolved": "https://registry.npmjs.org/@bcherny/json-schema-ref-parser/-/json-schema-ref-parser-10.0.5-fork.tgz", + "integrity": "sha512-E/jKbPoca1tfUPj3iSbitDZTGnq6FUFjkH6L8U2oDwSuwK1WhnnVtCG7oFOTg/DDnyoXbQYUiUiGOibHqaGVnw==", + "dev": true, + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@commitlint/cli": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.3.0.tgz", + "integrity": "sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==", + "dev": true, + "dependencies": { + "@commitlint/format": "^19.3.0", + "@commitlint/lint": "^19.2.2", + "@commitlint/load": "^19.2.0", + "@commitlint/read": "^19.2.1", + "@commitlint/types": "^19.0.3", + "execa": "^8.0.1", + "yargs": "^17.0.0" + }, + "bin": { + "commitlint": "cli.js" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/cli/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@commitlint/cli/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/@commitlint/cli/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/cli/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@commitlint/cli/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/config-conventional": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.2.2.tgz", + "integrity": "sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==", + "dev": true, + "dependencies": { + "@commitlint/types": "^19.0.3", + "conventional-changelog-conventionalcommits": "^7.0.2" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/config-validator": { + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.0.3.tgz", + "integrity": "sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==", + "dev": true, + "dependencies": { + "@commitlint/types": "^19.0.3", + "ajv": "^8.11.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/config-validator/node_modules/ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@commitlint/config-validator/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/@commitlint/ensure": { + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.0.3.tgz", + "integrity": "sha512-SZEpa/VvBLoT+EFZVb91YWbmaZ/9rPH3ESrINOl0HD2kMYsjvl0tF7nMHh0EpTcv4+gTtZBAe1y/SS6/OhfZzQ==", + "dev": true, + "dependencies": { + "@commitlint/types": "^19.0.3", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/execute-rule": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.0.0.tgz", + "integrity": "sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==", + "dev": true, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/format": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.3.0.tgz", + "integrity": "sha512-luguk5/aF68HiF4H23ACAfk8qS8AHxl4LLN5oxPc24H+2+JRPsNr1OS3Gaea0CrH7PKhArBMKBz5RX9sA5NtTg==", + "dev": true, + "dependencies": { + "@commitlint/types": "^19.0.3", + "chalk": "^5.3.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/format/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@commitlint/is-ignored": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.2.2.tgz", + "integrity": "sha512-eNX54oXMVxncORywF4ZPFtJoBm3Tvp111tg1xf4zWXGfhBPKpfKG6R+G3G4v5CPlRROXpAOpQ3HMhA9n1Tck1g==", + "dev": true, + "dependencies": { + "@commitlint/types": "^19.0.3", + "semver": "^7.6.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/lint": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.2.2.tgz", + "integrity": "sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==", + "dev": true, + "dependencies": { + "@commitlint/is-ignored": "^19.2.2", + "@commitlint/parse": "^19.0.3", + "@commitlint/rules": "^19.0.3", + "@commitlint/types": "^19.0.3" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/load": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.2.0.tgz", + "integrity": "sha512-XvxxLJTKqZojCxaBQ7u92qQLFMMZc4+p9qrIq/9kJDy8DOrEa7P1yx7Tjdc2u2JxIalqT4KOGraVgCE7eCYJyQ==", + "dev": true, + "dependencies": { + "@commitlint/config-validator": "^19.0.3", + "@commitlint/execute-rule": "^19.0.0", + "@commitlint/resolve-extends": "^19.1.0", + "@commitlint/types": "^19.0.3", + "chalk": "^5.3.0", + "cosmiconfig": "^9.0.0", + "cosmiconfig-typescript-loader": "^5.0.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/load/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@commitlint/message": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.0.0.tgz", + "integrity": "sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==", + "dev": true, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/parse": { + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.0.3.tgz", + "integrity": "sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==", + "dev": true, + "dependencies": { + "@commitlint/types": "^19.0.3", + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-parser": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/read": { + "version": "19.2.1", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.2.1.tgz", + "integrity": "sha512-qETc4+PL0EUv7Q36lJbPG+NJiBOGg7SSC7B5BsPWOmei+Dyif80ErfWQ0qXoW9oCh7GTpTNRoaVhiI8RbhuaNw==", + "dev": true, + "dependencies": { + "@commitlint/top-level": "^19.0.0", + "@commitlint/types": "^19.0.3", + "execa": "^8.0.1", + "git-raw-commits": "^4.0.0", + "minimist": "^1.2.8" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/read/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@commitlint/read/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/@commitlint/read/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/read/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@commitlint/read/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/resolve-extends": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.1.0.tgz", + "integrity": "sha512-z2riI+8G3CET5CPgXJPlzftH+RiWYLMYv4C9tSLdLXdr6pBNimSKukYP9MS27ejmscqCTVA4almdLh0ODD2KYg==", + "dev": true, + "dependencies": { + "@commitlint/config-validator": "^19.0.3", + "@commitlint/types": "^19.0.3", + "global-directory": "^4.0.1", + "import-meta-resolve": "^4.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/resolve-extends/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@commitlint/rules": { + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.0.3.tgz", + "integrity": "sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==", + "dev": true, + "dependencies": { + "@commitlint/ensure": "^19.0.3", + "@commitlint/message": "^19.0.0", + "@commitlint/to-lines": "^19.0.0", + "@commitlint/types": "^19.0.3", + "execa": "^8.0.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/rules/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@commitlint/rules/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/@commitlint/rules/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/rules/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@commitlint/rules/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/to-lines": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.0.0.tgz", + "integrity": "sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==", + "dev": true, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/top-level": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.0.0.tgz", + "integrity": "sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==", + "dev": true, + "dependencies": { + "find-up": "^7.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/top-level/node_modules/find-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", + "dev": true, + "dependencies": { + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/@commitlint/top-level/node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/types": { + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.0.3.tgz", + "integrity": "sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==", + "dev": true, + "dependencies": { + "@types/conventional-commits-parser": "^5.0.0", + "chalk": "^5.3.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/types/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==", + "dev": true + }, + "node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", + "dev": true + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rc-component/async-validator": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@rc-component/async-validator/-/async-validator-5.0.4.tgz", + "integrity": "sha512-qgGdcVIF604M9EqjNF0hbUTz42bz/RDtxWdWuU5EQe3hi7M8ob54B6B35rOsvX5eSvIHIzT9iH1R3n+hk3CGfg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.24.4" + }, + "engines": { + "node": ">=14.x" + } + }, + "node_modules/@rc-component/color-picker": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-1.5.3.tgz", + "integrity": "sha512-+tGGH3nLmYXTalVe0L8hSZNs73VTP5ueSHwUlDC77KKRaN7G4DS4wcpG5DTDzdcV/Yas+rzA6UGgIyzd8fS4cw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.6", + "@ctrl/tinycolor": "^3.6.1", + "classnames": "^2.2.6", + "rc-util": "^5.38.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/context": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@rc-component/context/-/context-1.4.0.tgz", + "integrity": "sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/mini-decimal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rc-component/mini-decimal/-/mini-decimal-1.1.0.tgz", + "integrity": "sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.18.0" + }, + "engines": { + "node": ">=8.x" + } + }, + "node_modules/@rc-component/mutate-observer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rc-component/mutate-observer/-/mutate-observer-1.1.0.tgz", + "integrity": "sha512-QjrOsDXQusNwGZPf4/qRQasg7UFEj06XiCJ8iuiq/Io7CrHrgVi6Uuetw60WAMG1799v+aM8kyc+1L/GBbHSlw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.18.0", + "classnames": "^2.3.2", + "rc-util": "^5.24.4" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/portal": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rc-component/portal/-/portal-1.1.2.tgz", + "integrity": "sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.18.0", + "classnames": "^2.3.2", + "rc-util": "^5.24.4" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/tour": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-1.15.0.tgz", + "integrity": "sha512-h6hyILDwL+In9GAgRobwRWihLqqsD7Uft3fZGrJ7L4EiyCoxbnNYwzPXDfz7vNDhWeVyvAWQJj9fJCzpI4+b4g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.18.0", + "@rc-component/portal": "^1.0.0-9", + "@rc-component/trigger": "^2.0.0", + "classnames": "^2.3.2", + "rc-util": "^5.24.4" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/trigger": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-2.2.0.tgz", + "integrity": "sha512-QarBCji02YE9aRFhZgRZmOpXBj0IZutRippsVBv85sxvG4FGk/vRxwAlkn3MS9zK5mwbETd86mAVg2tKqTkdJA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "@rc-component/portal": "^1.1.0", + "classnames": "^2.3.2", + "rc-motion": "^2.0.0", + "rc-resize-observer": "^1.3.1", + "rc-util": "^5.38.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.5.tgz", + "integrity": "sha512-aeFA/s5NCG7NoJe/MhmwREJxRkDs0ZaSqt0MxhWUrwCf1UQXpwR87RROJEql0uAkLI6U7snBOYOcKw83ew3FPg==", + "dev": true, + "dependencies": { + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.8.1.tgz", + "integrity": "sha512-64My6I7uCcmSQ//427Pfg2vjSf9SDzfsGIWohNFgISMLYdC5BzJqDo647iDDJzSxINh3WTC0Ql46ifiKuOoTyA==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "1.8.1", + "@stylistic/eslint-plugin-jsx": "1.8.1", + "@stylistic/eslint-plugin-plus": "1.8.1", + "@stylistic/eslint-plugin-ts": "1.8.1", + "@types/eslint": "^8.56.10" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin-js": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.8.1.tgz", + "integrity": "sha512-c5c2C8Mos5tTQd+NWpqwEu7VT6SSRooAguFPMj1cp2RkTYl1ynKoXo8MWy3k4rkbzoeYHrqC2UlUzsroAN7wtQ==", + "dev": true, + "dependencies": { + "@types/eslint": "^8.56.10", + "acorn": "^8.11.3", + "escape-string-regexp": "^4.0.0", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin-jsx": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.8.1.tgz", + "integrity": "sha512-k1Eb6rcjMP+mmjvj+vd9y5KUdWn1OBkkPLHXhsrHt5lCDFZxJEs0aVQzE5lpYrtVZVkpc5esTtss/cPJux0lfA==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "^1.8.1", + "@types/eslint": "^8.56.10", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/eslint-plugin-plus": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.8.1.tgz", + "integrity": "sha512-4+40H3lHYTN8OWz+US8CamVkO+2hxNLp9+CAjorI7top/lHqemhpJvKA1LD9Uh+WMY9DYWiWpL2+SZ2wAXY9fQ==", + "dev": true, + "dependencies": { + "@types/eslint": "^8.56.10", + "@typescript-eslint/utils": "^6.21.0" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@stylistic/eslint-plugin-ts": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.8.1.tgz", + "integrity": "sha512-/q1m+ZuO1JHfiSF16EATFzv7XSJkc5W6DocfvH5o9oB6WWYFMF77fVoBWnKT3wGptPOc2hkRupRKhmeFROdfWA==", + "dev": true, + "dependencies": { + "@stylistic/eslint-plugin-js": "1.8.1", + "@types/eslint": "^8.56.10", + "@typescript-eslint/utils": "^6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@tauri-apps/api": { + "version": "2.0.0-rc.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-rc.0.tgz", + "integrity": "sha512-v454Qs3REHc3Za59U+/eSmBsdmF+3NE5+76+lFDaitVqN4ZglDHENDaMARYKGJVZuxiSkzyqG0SeG7lLQjVkPA==", + "engines": { + "node": ">= 18.18", + "npm": ">= 6.6.0", + "yarn": ">= 1.19.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/cli": { + "version": "2.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.0.0-rc.3.tgz", + "integrity": "sha512-iNF95pieBmverl1EmQyqh+fhcIClS544fN5Ex5lAbYLTiHZ/gm3lOfVBhF6NPaKd/sfLuy7K1tfDXlHztBfANw==", + "dev": true, + "bin": { + "tauri": "tauri.js" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + }, + "optionalDependencies": { + "@tauri-apps/cli-darwin-arm64": "2.0.0-rc.3", + "@tauri-apps/cli-darwin-x64": "2.0.0-rc.3", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.0.0-rc.3", + "@tauri-apps/cli-linux-arm64-gnu": "2.0.0-rc.3", + "@tauri-apps/cli-linux-arm64-musl": "2.0.0-rc.3", + "@tauri-apps/cli-linux-x64-gnu": "2.0.0-rc.3", + "@tauri-apps/cli-linux-x64-musl": "2.0.0-rc.3", + "@tauri-apps/cli-win32-arm64-msvc": "2.0.0-rc.3", + "@tauri-apps/cli-win32-ia32-msvc": "2.0.0-rc.3", + "@tauri-apps/cli-win32-x64-msvc": "2.0.0-rc.3" + } + }, + "node_modules/@tauri-apps/cli-darwin-arm64": { + "version": "2.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.0.0-rc.3.tgz", + "integrity": "sha512-szYCSr/ChbCF+S6Wnr15TYpI2cZR07d+AQOiFGuScP0preM8Pbsk/sb0hfLwqzepjVFFNVWQba9sG7FEW2Y2XA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-darwin-x64": { + "version": "2.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.0.0-rc.3.tgz", + "integrity": "sha512-BJv6EJOY1DJbRzVtfg8CcBAlnS5OjhBAc5YKjh4BT7EyOcop8HStBSxhL6yjWrUP7eLR1iIsW/uSehVJwzYIdQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { + "version": "2.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.0.0-rc.3.tgz", + "integrity": "sha512-fwx805/xL4sF/EdMYqcUHQHzMYwo+OVTBTz5x/JWK8D57rnmLHAP+ZhnfFsZQLRo2QRT2l1Ye3bDyU+QRA1JFA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-gnu": { + "version": "2.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.0.0-rc.3.tgz", + "integrity": "sha512-3KauzO1Ls4kuY0nr82S4X8XFxlQAMN+Mqp8LLqvQ+PPMp92XQAkPH7osQdoHIEoW5gsE69U2JaiQ5tHSqNM9og==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-musl": { + "version": "2.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.0-rc.3.tgz", + "integrity": "sha512-ngHS0foffm1xO5gqnDKGeYMKj8ceGmrFP5dDldoaaMQubw1SyFa0pRUjb7fZSYiO7F4SOSa8NYeMqlF9peZmnQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-gnu": { + "version": "2.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.0.0-rc.3.tgz", + "integrity": "sha512-0/am9pVvuUHGmz32M8ffz1fpLnc08j3nzcRe5wUdL2AxfT+wKMII+Dn99GtCVgcdDW4jSXDMRUwrBkGocGC2OA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-musl": { + "version": "2.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.0-rc.3.tgz", + "integrity": "sha512-r7mRi8q8TqTFVjb9kAsU7IgwUgno2s8Ip4xwq9psQhlRE3JGEZQmSEcy1jqTjfl6KFh6lJcDR7l+9/EMhL/D3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-arm64-msvc": { + "version": "2.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.0.0-rc.3.tgz", + "integrity": "sha512-2J6KjmDIQCw6HF1X6/yPcd+JLl7pxrH2zVMGmNllaoWhHeByvRobqFWnT7gcdHaA3dGTo432CwWvOgTgrINQpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-ia32-msvc": { + "version": "2.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.0.0-rc.3.tgz", + "integrity": "sha512-8q75CsHDSEDdgi6xPwim+BaQZFCswK2Dn/qL38V3Mh9kmVvC8oGJMPC66bC20dF+v3KWeFm2FNNGQqOSXCveHg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-x64-msvc": { + "version": "2.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.0.0-rc.3.tgz", + "integrity": "sha512-qeBRJYalahxEXolekcpZJ/HBrIJacG2NWJBGhhi797mIwnbmlpbHMc8blIJtNNNwVUb2BjXuxKQVfojQ5YYrcg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/plugin-autostart": { + "version": "2.0.0-rc.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-autostart/-/plugin-autostart-2.0.0-rc.0.tgz", + "integrity": "sha512-V49lm++vhrMPPDGMtmOcbJLF4TYu78ZmAiMhyd4FFnbYlgin6ZTjiMCFEl4JKVy2lqP3C8DQvXf/gkUMuER7Iw==", + "dependencies": { + "@tauri-apps/api": "^2.0.0-rc.0" + } + }, + "node_modules/@tauri-apps/plugin-deep-link": { + "version": "2.0.0-rc.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-deep-link/-/plugin-deep-link-2.0.0-rc.0.tgz", + "integrity": "sha512-LdwxGeQAkxbOYBcamfOT6hAokstkhKz7t5mZcm5wCoUSTPIzMX/+7lNS8hsQouiTg7EXCXGaLW3nzwF9qwMA6g==", + "dependencies": { + "@tauri-apps/api": "^2.0.0-rc.0" + } + }, + "node_modules/@tauri-apps/plugin-dialog": { + "version": "2.0.0-rc.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.0-rc.0.tgz", + "integrity": "sha512-DPOXYe8SQ6Radk/67EOdaomlxL7oF99JO/ZUaPp1IBEs3Wro7lhlz63CfdKIBfKIZTLJLzP1R7/EiPL/GTA3Bg==", + "dependencies": { + "@tauri-apps/api": "^2.0.0-rc.0" + } + }, + "node_modules/@tauri-apps/plugin-fs": { + "version": "2.0.0-rc.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.0.0-rc.0.tgz", + "integrity": "sha512-74VCXEZlzTJ+Jv1V3KrV0qIHhSePpE/ljsF78rcEuvSfyTxLtt/Sb5CIUmVhFlKTRFOH9dX50T4dTZ3qFLyRnA==", + "dependencies": { + "@tauri-apps/api": "^2.0.0-rc.0" + } + }, + "node_modules/@tauri-apps/plugin-log": { + "version": "2.0.0-rc.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-log/-/plugin-log-2.0.0-rc.0.tgz", + "integrity": "sha512-ztKfzUcq03dtr08vBu+xcwIEPusP6mCpuLAt6kpXEwG+HvYsC8e1/KFFokn3xvfwD+oBJ3UTL1h4kdM30GAqGw==", + "dependencies": { + "@tauri-apps/api": "^2.0.0-rc.0" + } + }, + "node_modules/@tauri-apps/plugin-process": { + "version": "2.0.0-rc.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-process/-/plugin-process-2.0.0-rc.0.tgz", + "integrity": "sha512-Z12D/kmQzG1vCVf+jLXPhPDUA0pEjFrsg4p0uwO2sotVLM9287IuTM+aIz9cuAYOxFLKcsnDG7amSCL9IfA1gw==", + "dependencies": { + "@tauri-apps/api": "^2.0.0-rc.0" + } + }, + "node_modules/@tauri-apps/plugin-shell": { + "version": "2.0.0-rc.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.0-rc.0.tgz", + "integrity": "sha512-bhUcQcrqZoK8H1DFXapr5r1Z75oh6Kd5Tltz97XpZFLREEqp+KhN2Fvyh8r/fKAyenYsTYUIsDsyGdjdueuF9g==", + "dependencies": { + "@tauri-apps/api": "^2.0.0-rc.0" + } + }, + "node_modules/@tauri-apps/plugin-updater": { + "version": "2.0.0-rc.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-updater/-/plugin-updater-2.0.0-rc.0.tgz", + "integrity": "sha512-EKajf/sBpFif0cwXhTo3BmNvTZ2t2DDLRyhA8FFKugZNoOeqU97bHhPT5DIqMUPRE1tyDk9o7sXm8dKf7oz+EA==", + "dependencies": { + "@tauri-apps/api": "^2.0.0-rc.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/lodash": { + "version": "4.17.6", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.6.tgz", + "integrity": "sha512-OpXEVoCKSS3lQqjx9GGGOapBeuW5eUboYHRlHP9urXPX25IKZ6AnP5ZRxtVf63iieUbsHxLn8NQ5Nlftc6yzAA==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", + "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz", + "integrity": "sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/type-utils": "7.14.1", + "@typescript-eslint/utils": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", + "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", + "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", + "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", + "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/typescript-estree": "7.14.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", + "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz", + "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/typescript-estree": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", + "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", + "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", + "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", + "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.14.1.tgz", + "integrity": "sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.14.1", + "@typescript-eslint/utils": "7.14.1", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", + "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", + "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", + "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", + "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/typescript-estree": "7.14.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", + "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/antd": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.18.3.tgz", + "integrity": "sha512-Dm3P8HBxoo/DiR/QZLj5Mk+rQZsSXxCCArSZACHGiklkkjW6klzlebAElOUr9NyDeFX7UnQ6LVk7vznXlnjTqQ==", + "dev": true, + "dependencies": { + "@ant-design/colors": "^7.0.2", + "@ant-design/cssinjs": "^1.21.0", + "@ant-design/icons": "^5.3.7", + "@ant-design/react-slick": "~1.1.2", + "@babel/runtime": "^7.24.7", + "@ctrl/tinycolor": "^3.6.1", + "@rc-component/color-picker": "~1.5.3", + "@rc-component/mutate-observer": "^1.1.0", + "@rc-component/tour": "~1.15.0", + "@rc-component/trigger": "^2.2.0", + "classnames": "^2.5.1", + "copy-to-clipboard": "^3.3.3", + "dayjs": "^1.11.11", + "qrcode.react": "^3.1.0", + "rc-cascader": "~3.26.0", + "rc-checkbox": "~3.3.0", + "rc-collapse": "~3.7.3", + "rc-dialog": "~9.5.2", + "rc-drawer": "~7.2.0", + "rc-dropdown": "~4.2.0", + "rc-field-form": "~2.2.1", + "rc-image": "~7.9.0", + "rc-input": "~1.5.1", + "rc-input-number": "~9.1.0", + "rc-mentions": "~2.14.0", + "rc-menu": "~9.14.0", + "rc-motion": "^2.9.2", + "rc-notification": "~5.6.0", + "rc-pagination": "~4.0.4", + "rc-picker": "~4.5.0", + "rc-progress": "~4.0.0", + "rc-rate": "~2.13.0", + "rc-resize-observer": "^1.4.0", + "rc-segmented": "~2.3.0", + "rc-select": "~14.14.0", + "rc-slider": "~10.6.2", + "rc-steps": "~6.0.1", + "rc-switch": "~4.1.0", + "rc-table": "~7.45.7", + "rc-tabs": "~15.1.1", + "rc-textarea": "~1.7.0", + "rc-tooltip": "~6.2.0", + "rc-tree": "~5.8.8", + "rc-tree-select": "~5.21.0", + "rc-upload": "~4.5.2", + "rc-util": "^5.43.0", + "scroll-into-view-if-needed": "^3.1.0", + "throttle-debounce": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ant-design" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true + }, + "node_modules/array-tree-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz", + "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001638", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001638.tgz", + "integrity": "sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", + "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "dev": true + }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "dev": true + }, + "node_modules/cli-color": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", + "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.64", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/complex.js": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.1.1.tgz", + "integrity": "sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, + "node_modules/compute-scroll-into-view": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz", + "integrity": "sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/conventional-changelog-angular": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/conventional-changelog-conventionalcommits": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz", + "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", + "dev": true, + "dependencies": { + "is-text-path": "^2.0.0", + "JSONStream": "^1.3.5", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "dev": true, + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig-typescript-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz", + "integrity": "sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==", + "dev": true, + "dependencies": { + "jiti": "^1.19.1" + }, + "engines": { + "node": ">=v16" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=8.2", + "typescript": ">=4" + } + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, + "node_modules/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/dargs": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz", + "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dayjs": { + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, + "node_modules/dedent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.814", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.814.tgz", + "integrity": "sha512-GVulpHjFu1Y9ZvikvbArHmAhZXtm3wHlpjTMcXNGKl4IQ4jMQjlnz8yMQYYqdLHKi/jEL2+CBC2akWVCoIGUdw==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "dev": true, + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-latex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-simple-import-sort": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.0.tgz", + "integrity": "sha512-Y2fqAfC11TcG/WP3TrI1Gi3p3nc8XJyEOJYHyEPEGI/UAgNx6akxxlX74p7SbAQdLcgASKhj8M0GKvH3vq/+ig==", + "dev": true, + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/fraction.js": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.4.tgz", + "integrity": "sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/framer-motion": { + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.3.6.tgz", + "integrity": "sha512-olpX48qfoSIDjhw0RbolhOGBQmdMAXHHpSI0PFdTj5LeXChcf5F4ApShs0mQ6FPEPOj7dnEvSyB07UgRK5G9Jw==", + "dev": true, + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/git-raw-commits": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz", + "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==", + "dev": true, + "dependencies": { + "dargs": "^8.0.0", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-promise": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-4.2.2.tgz", + "integrity": "sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.3" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/ahmadnassri" + }, + "peerDependencies": { + "glob": "^7.1.6" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "dev": true, + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/google-translate-api-x": { + "version": "10.6.8", + "resolved": "https://registry.npmjs.org/google-translate-api-x/-/google-translate-api-x-10.6.8.tgz", + "integrity": "sha512-vlXnCQhMcy00P2uX/mK3NzJb4HBMhoKo39PSmupiiVKLgsAZp8b22OV48dcAUxykAuPxQreyBYz4P6jFCzeZjA==", + "dev": true, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/AidanWelch" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "dev": true, + "dependencies": { + "void-elements": "3.1.0" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/i18next": { + "version": "23.12.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.12.2.tgz", + "integrity": "sha512-XIeh5V+bi8SJSWGL3jqbTEBW5oD6rbP5L+E7dVQh1MNTxxYef0x15rhJVcRb7oiuq4jLtgy2SD8eFlf6P2cmqg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/immer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz", + "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", + "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-text-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", + "dev": true, + "dependencies": { + "text-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", + "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", + "dev": true + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-to-typescript": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-13.1.2.tgz", + "integrity": "sha512-17G+mjx4nunvOpkPvcz7fdwUwYCEwyH8vR3Ym3rFiQ8uzAL3go+c1306Kk7iGRk8HuXBXqy+JJJmpYl0cvOllw==", + "dev": true, + "dependencies": { + "@bcherny/json-schema-ref-parser": "10.0.5-fork", + "@types/json-schema": "^7.0.11", + "@types/lodash": "^4.14.182", + "@types/prettier": "^2.6.1", + "cli-color": "^2.0.2", + "get-stdin": "^8.0.0", + "glob": "^7.1.6", + "glob-promise": "^4.2.2", + "is-glob": "^4.0.3", + "lodash": "^4.17.21", + "minimist": "^1.2.6", + "mkdirp": "^1.0.4", + "mz": "^2.7.0", + "prettier": "^2.6.2" + }, + "bin": { + "json2ts": "dist/src/cli.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json2mq": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", + "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==", + "dev": true, + "dependencies": { + "string-convert": "^0.2.0" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/lefthook": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/lefthook/-/lefthook-1.6.18.tgz", + "integrity": "sha512-Ftr/NkU1P1EsEyphsCqCX7lesGZA+QDXyUx4dS1RlSKB72xKtGW9VPjbGLK2kSQkONG5M+XYfbJkGA/r9NLTYQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "lefthook": "bin/index.js" + }, + "optionalDependencies": { + "lefthook-darwin-arm64": "1.6.18", + "lefthook-darwin-x64": "1.6.18", + "lefthook-freebsd-arm64": "1.6.18", + "lefthook-freebsd-x64": "1.6.18", + "lefthook-linux-arm64": "1.6.18", + "lefthook-linux-x64": "1.6.18", + "lefthook-windows-arm64": "1.6.18", + "lefthook-windows-x64": "1.6.18" + } + }, + "node_modules/lefthook-darwin-arm64": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/lefthook-darwin-arm64/-/lefthook-darwin-arm64-1.6.18.tgz", + "integrity": "sha512-AkpsTeO7aLZIIy6CKQ7Chx8RltE8a9uItbwQWoeaCkIdzpV8TFjq7/Pw4F5CkoJ2315sHtB8k+VFkgipQMBw1w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/lefthook-darwin-x64": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/lefthook-darwin-x64/-/lefthook-darwin-x64-1.6.18.tgz", + "integrity": "sha512-qwKa+PaNIYjZ2PVrRRLq+HjNjQsjEItXN21byvSD89r7EYCULsIC8aW4H6aniOP2A6X1DIZ+djpg+3hNJ/94NA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/lefthook-freebsd-arm64": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/lefthook-freebsd-arm64/-/lefthook-freebsd-arm64-1.6.18.tgz", + "integrity": "sha512-UIOzQ+okwB7Ah9p8sNqomOiU6cPfmJnyW3HDPutRsdoHRD8udIap9d+ja4Kg4m/PkoYtkcLO78omANqAgA5wxQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/lefthook-freebsd-x64": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/lefthook-freebsd-x64/-/lefthook-freebsd-x64-1.6.18.tgz", + "integrity": "sha512-UQANUgyNpaAh0+2/PjPFiJ7yd6aF15yyJxKZCXyna5cQF7VU8pSHu5tiDDquNpjToXOg+6TmiIAJKyfrrwTF3w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/lefthook-linux-arm64": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/lefthook-linux-arm64/-/lefthook-linux-arm64-1.6.18.tgz", + "integrity": "sha512-4erletIa2HKUgY17/1ROvndAj6xn/9wkqO2GhBT3C0vFwIv6ycy5wpFzXOwKRZpFYv7UacN7iXhAZSK+vSOZZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/lefthook-linux-x64": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/lefthook-linux-x64/-/lefthook-linux-x64-1.6.18.tgz", + "integrity": "sha512-l5SRqYMYygw9RjZncEg8uh29wShYN8kiYr53sp74DkntrlCttqWhLILBUlIr3fxH5s0ZyrmqUEjtMBryMk7b/g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/lefthook-windows-arm64": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/lefthook-windows-arm64/-/lefthook-windows-arm64-1.6.18.tgz", + "integrity": "sha512-jeNBRoya3+mOEsKyT4wXf29Kng1nkJD7Uv/dqGBszoGMktGVNUFdIjWoxx6HSfhUssucs5pKRZpXSMgK/KCP+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/lefthook-windows-x64": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/lefthook-windows-x64/-/lefthook-windows-x64-1.6.18.tgz", + "integrity": "sha512-iEG8PbFOwMqlpAgCiqzANTxutERjwlwMx6WF6HDGEYwFJSCJsvi06TehDxaPIFbhmLLYYlbVrfSBlttWGoN0dg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dev": true, + "dependencies": { + "es5-ext": "~0.10.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/mathjs": { + "version": "12.4.3", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-12.4.3.tgz", + "integrity": "sha512-oHdGPDbp7gO873xxG90RLq36IuicuKvbpr/bBG5g9c8Obm/VsKVrK9uoRZZHUodohzlnmCEqfDzbR3LH6m+aAQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.24.4", + "complex.js": "^2.1.1", + "decimal.js": "^10.4.3", + "escape-latex": "^1.2.0", + "fraction.js": "4.3.4", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^4.1.1" + }, + "bin": { + "mathjs": "bin/cli.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/memoizee": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", + "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", + "dev": true, + "dependencies": { + "d": "^1.0.2", + "es5-ext": "^0.10.64", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true, + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/nodemon": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz", + "integrity": "sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/nodemon/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/nodemon/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/qrcode.react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz", + "integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==", + "dev": true, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/rc-cascader": { + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.26.0.tgz", + "integrity": "sha512-L1dml383TPSJD1I11YwxuVbmqaJY64psZqFp1ETlgl3LEOwDu76Cyl11fw5dmjJhMlUWwM5dECQfqJgfebhUjg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "array-tree-filter": "^2.1.0", + "classnames": "^2.3.1", + "rc-select": "~14.14.0", + "rc-tree": "~5.8.1", + "rc-util": "^5.37.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-checkbox": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-3.3.0.tgz", + "integrity": "sha512-Ih3ZaAcoAiFKJjifzwsGiT/f/quIkxJoklW4yKGho14Olulwn8gN7hOBve0/WGDg5o/l/5mL0w7ff7/YGvefVw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.3.2", + "rc-util": "^5.25.2" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-collapse": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.7.3.tgz", + "integrity": "sha512-60FJcdTRn0X5sELF18TANwtVi7FtModq649H11mYF1jh83DniMoM4MqY627sEKRCTm4+WXfGDcB7hY5oW6xhyw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.3.4", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-dialog": { + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-9.5.2.tgz", + "integrity": "sha512-qVUjc8JukG+j/pNaHVSRa2GO2/KbV2thm7yO4hepQ902eGdYK913sGkwg/fh9yhKYV1ql3BKIN2xnud3rEXAPw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/portal": "^1.0.0-8", + "classnames": "^2.2.6", + "rc-motion": "^2.3.0", + "rc-util": "^5.21.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-drawer": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-7.2.0.tgz", + "integrity": "sha512-9lOQ7kBekEJRdEpScHvtmEtXnAsy+NGDXiRWc2ZVC7QXAazNVbeT4EraQKYwCME8BJLa8Bxqxvs5swwyOepRwg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.9", + "@rc-component/portal": "^1.1.1", + "classnames": "^2.2.6", + "rc-motion": "^2.6.1", + "rc-util": "^5.38.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-dropdown": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-4.2.0.tgz", + "integrity": "sha512-odM8Ove+gSh0zU27DUj5cG1gNKg7mLWBYzB5E4nNLrLwBmYEgYP43vHKDGOVZcJSVElQBI0+jTQgjnq0NfLjng==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "@rc-component/trigger": "^2.0.0", + "classnames": "^2.2.6", + "rc-util": "^5.17.0" + }, + "peerDependencies": { + "react": ">=16.11.0", + "react-dom": ">=16.11.0" + } + }, + "node_modules/rc-field-form": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-2.2.1.tgz", + "integrity": "sha512-uoNqDoR7A4tn4QTSqoWPAzrR7ZwOK5I+vuZ/qdcHtbKx+ZjEsTg7QXm2wk/jalDiSksAQmATxL0T5LJkRREdIA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.18.0", + "@rc-component/async-validator": "^5.0.3", + "rc-util": "^5.32.2" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-image": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-7.9.0.tgz", + "integrity": "sha512-l4zqO5E0quuLMCtdKfBgj4Suv8tIS011F5k1zBBlK25iMjjiNHxA0VeTzGFtUZERSA45gvpXDg8/P6qNLjR25g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.11.2", + "@rc-component/portal": "^1.0.2", + "classnames": "^2.2.6", + "rc-dialog": "~9.5.2", + "rc-motion": "^2.6.2", + "rc-util": "^5.34.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-input": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.5.1.tgz", + "integrity": "sha512-+nOzQJDeIfIpNP/SgY45LXSKbuMlp4Yap2y8c+ZpU7XbLmNzUd6+d5/S75sA/52jsVE6S/AkhkkDEAOjIu7i6g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.18.1" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/rc-input-number": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-9.1.0.tgz", + "integrity": "sha512-NqJ6i25Xn/AgYfVxynlevIhX3FuKlMwIFpucGG1h98SlK32wQwDK0zhN9VY32McOmuaqzftduNYWWooWz8pXQA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/mini-decimal": "^1.0.1", + "classnames": "^2.2.5", + "rc-input": "~1.5.0", + "rc-util": "^5.40.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-mentions": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.14.0.tgz", + "integrity": "sha512-qKR59FMuF8PK4ZqsbWX3UuA5P1M/snzyqV6Yt3y1DCFbCEdqUGIBgQp6vEfLCO6Z0RoRFlzXtCeSlBTcDDpg1A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.22.5", + "@rc-component/trigger": "^2.0.0", + "classnames": "^2.2.6", + "rc-input": "~1.5.0", + "rc-menu": "~9.14.0", + "rc-textarea": "~1.7.0", + "rc-util": "^5.34.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-menu": { + "version": "9.14.1", + "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.14.1.tgz", + "integrity": "sha512-5wlRb3M8S4yGlWhSoEYJ7ZVRElyScdcpUHxgiLxkeig1tEdyKrnED3B2fhpN0Rrpdp9jyhnmZR/Lwq2fH5VvDQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/trigger": "^2.0.0", + "classnames": "2.x", + "rc-motion": "^2.4.3", + "rc-overflow": "^1.3.1", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-motion": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.2.tgz", + "integrity": "sha512-fUAhHKLDdkAXIDLH0GYwof3raS58dtNUmzLF2MeiR8o6n4thNpSDQhOqQzWE4WfFZDCi9VEN8n7tiB7czREcyw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.43.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-notification": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-5.6.0.tgz", + "integrity": "sha512-TGQW5T7waOxLwgJG7fXcw8l7AQiFOjaZ7ISF5PrU526nunHRNcTMuzKihQHaF4E/h/KfOCDk3Mv8eqzbu2e28w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.9.0", + "rc-util": "^5.20.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-overflow": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/rc-overflow/-/rc-overflow-1.3.2.tgz", + "integrity": "sha512-nsUm78jkYAoPygDAcGZeC2VwIg/IBGSodtOY3pMof4W3M9qRJgqaDYm03ZayHlde3I6ipliAxbN0RUcGf5KOzw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.37.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-pagination": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-4.0.4.tgz", + "integrity": "sha512-GGrLT4NgG6wgJpT/hHIpL9nELv27A1XbSZzECIuQBQTVSf4xGKxWr6I/jhpRPauYEWEbWVw22ObG6tJQqwJqWQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.3.2", + "rc-util": "^5.38.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-picker": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-4.5.0.tgz", + "integrity": "sha512-suqz9bzuhBQlf7u+bZd1bJLPzhXpk12w6AjQ9BTPTiFwexVZgUKViG1KNLyfFvW6tCUZZK0HmCCX7JAyM+JnCg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/trigger": "^2.0.0", + "classnames": "^2.2.1", + "rc-overflow": "^1.3.2", + "rc-resize-observer": "^1.4.0", + "rc-util": "^5.38.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "date-fns": ">= 2.x", + "dayjs": ">= 1.x", + "luxon": ">= 3.x", + "moment": ">= 2.x", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + }, + "peerDependenciesMeta": { + "date-fns": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + } + } + }, + "node_modules/rc-progress": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-4.0.0.tgz", + "integrity": "sha512-oofVMMafOCokIUIBnZLNcOZFsABaUw8PPrf1/y0ZBvKZNpOiu5h4AO9vv11Sw0p4Hb3D0yGWuEattcQGtNJ/aw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-util": "^5.16.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-rate": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.13.0.tgz", + "integrity": "sha512-oxvx1Q5k5wD30sjN5tqAyWTvJfLNNJn7Oq3IeS4HxWfAiC4BOXMITNAsw7u/fzdtO4MS8Ki8uRLOzcnEuoQiAw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.0.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-resize-observer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.4.0.tgz", + "integrity": "sha512-PnMVyRid9JLxFavTjeDXEXo65HCRqbmLBw9xX9gfC4BZiSzbLXKzW3jPz+J0P71pLbD5tBMTT+mkstV5gD0c9Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.20.7", + "classnames": "^2.2.1", + "rc-util": "^5.38.0", + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-segmented": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/rc-segmented/-/rc-segmented-2.3.0.tgz", + "integrity": "sha512-I3FtM5Smua/ESXutFfb8gJ8ZPcvFR+qUgeeGFQHBOvRiRKyAk4aBE5nfqrxXx+h8/vn60DQjOt6i4RNtrbOobg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-motion": "^2.4.4", + "rc-util": "^5.17.0" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/rc-select": { + "version": "14.14.0", + "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.14.0.tgz", + "integrity": "sha512-Uo2wulrjoPPRLCPd7zlK4ZFVJxlTN//yp1xWP/U+TUOQCyXrT+Duvq/Si5OzVcmQyWAUSbsplc2OwNNhvbOeKQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/trigger": "^2.1.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-overflow": "^1.3.1", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.5.2" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-slider": { + "version": "10.6.2", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-10.6.2.tgz", + "integrity": "sha512-FjkoFjyvUQWcBo1F3RgSglky3ar0+qHLM41PlFVYB4Bj3RD8E/Mv7kqMouLFBU+3aFglMzzctAIWRwajEuueSw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.36.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-steps": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rc-steps/-/rc-steps-6.0.1.tgz", + "integrity": "sha512-lKHL+Sny0SeHkQKKDJlAjV5oZ8DwCdS2hFhAkIjuQt1/pB81M0cA0ErVFdHq9+jmPmFw1vJB2F5NBzFXLJxV+g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.7", + "classnames": "^2.2.3", + "rc-util": "^5.16.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-switch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-4.1.0.tgz", + "integrity": "sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.21.0", + "classnames": "^2.2.1", + "rc-util": "^5.30.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-table": { + "version": "7.45.7", + "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.45.7.tgz", + "integrity": "sha512-wi9LetBL1t1csxyGkMB2p3mCiMt+NDexMlPbXHvQFmBBAsMxrgNSAPwUci2zDLUq9m8QdWc1Nh8suvrpy9mXrg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/context": "^1.4.0", + "classnames": "^2.2.5", + "rc-resize-observer": "^1.1.0", + "rc-util": "^5.37.0", + "rc-virtual-list": "^3.14.2" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tabs": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-15.1.1.tgz", + "integrity": "sha512-Tc7bJvpEdkWIVCUL7yQrMNBJY3j44NcyWS48jF/UKMXuUlzaXK+Z/pEL5LjGcTadtPvVmNqA40yv7hmr+tCOAw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.11.2", + "classnames": "2.x", + "rc-dropdown": "~4.2.0", + "rc-menu": "~9.14.0", + "rc-motion": "^2.6.2", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.34.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-textarea": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.7.0.tgz", + "integrity": "sha512-UxizYJkWkmxP3zofXgc487QiGyDmhhheDLLjIWbFtDmiru1ls30KpO8odDaPyqNUIy9ugj5djxTEuezIn6t3Jg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-input": "~1.5.0", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tooltip": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-6.2.0.tgz", + "integrity": "sha512-iS/3iOAvtDh9GIx1ulY7EFUXUtktFccNLsARo3NPgLf0QW9oT0w3dA9cYWlhqAKmD+uriEwdWz1kH0Qs4zk2Aw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.11.2", + "@rc-component/trigger": "^2.0.0", + "classnames": "^2.3.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tree": { + "version": "5.8.8", + "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.8.8.tgz", + "integrity": "sha512-S+mCMWo91m5AJqjz3PdzKilGgbFm7fFJRFiTDOcoRbD7UfMOPnerXwMworiga0O2XIo383UoWuEfeHs1WOltag==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.5.1" + }, + "engines": { + "node": ">=10.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-tree-select": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.21.0.tgz", + "integrity": "sha512-w+9qEu6zh0G3wt9N/hzWNSnqYH1i9mH1Nqxo0caxLRRFXF5yZWYmpCDoDTMdQM1Y4z3Q5yj08qyrPH/d4AtumA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-select": "~14.14.0", + "rc-tree": "~5.8.1", + "rc-util": "^5.16.1" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-upload": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.5.2.tgz", + "integrity": "sha512-QO3ne77DwnAPKFn0bA5qJM81QBjQi0e0NHdkvpFyY73Bea2NfITiotqJqVjHgeYPOJu5lLVR32TNGP084aSoXA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "classnames": "^2.2.5", + "rc-util": "^5.2.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-util": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.43.0.tgz", + "integrity": "sha512-AzC7KKOXFqAdIBqdGWepL9Xn7cm3vnAmjlHqUnoQaTMZYhM4VlXGLkkHHxj/BZ7Td0+SOPKB4RGPboBVKT9htw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "react-is": "^18.2.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-virtual-list": { + "version": "3.14.5", + "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.14.5.tgz", + "integrity": "sha512-ZMOnkCLv2wUN8Jz7yI4XiSLa9THlYvf00LuMhb1JlsQCewuU7ydPuHw1rGVPhe9VZYl/5UqODtNd7QKJ2DMGfg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.20.0", + "classnames": "^2.2.6", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.36.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-i18next": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.0.0.tgz", + "integrity": "sha512-2O3IgF4zivg57Q6p6i+ChDgJ371IDcEWbuWC6gvoh5NbkDMs0Q+O7RPr4v61+Se32E0V+LmtwePAeqWZW0bi6g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.24.8", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 23.2.3", + "react": ">= 16.8.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/react-icons": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.3.0.tgz", + "integrity": "sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg==", + "dev": true, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/react-redux": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz", + "integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==", + "dev": true, + "dependencies": { + "@types/use-sync-external-store": "^0.0.3", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25", + "react": "^18.0", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/readable-test-for-types": { + "resolved": "node_modules/readable-types/rtt-plugin", + "link": true + }, + "node_modules/readable-types": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/readable-types/-/readable-types-4.0.3.tgz", + "integrity": "sha512-1cwEnwK0iXY1h/4f5bTGr2cE3w3y21BNLF2XiZcB235u+soALHRqyDEGzh/VQrzf8E7dCzImsjo5maH7FEaLeg==", + "dev": true, + "dependencies": { + "readable-test-for-types": "file:./rtt-plugin", + "typescript": "^4.2 || ^5.0" + }, + "bin": { + "rtft": "rtt-plugin/dist/run-tests.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/readable-types/rtt-plugin": { + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4" + }, + "bin": { + "rtft": "dist/run-tests.js" + }, + "peerDependencies": { + "typescript": "^4.2 || ^5.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "dev": true + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "dev": true, + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "dev": true + }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/scroll-into-view-if-needed": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz", + "integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==", + "dev": true, + "dependencies": { + "compute-scroll-into-view": "^3.0.2" + } + }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", + "dev": true + }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==", + "dev": true + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "dev": true + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/text-extensions": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", + "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/throttle-debounce": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz", + "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==", + "dev": true, + "engines": { + "node": ">=12.22" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/timers-ext": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz", + "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.64", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "dev": true + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", + "dev": true + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", + "dev": true + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "dev": true, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-jest": { + "version": "29.1.5", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.5.tgz", + "integrity": "sha512-UuClSYxM7byvvYfyWdFI+/2UxMmwNyJb0NPkZPQE2hew3RurV7l7zURgOHAd/1I1ZdPpe3GUsXNXAcN8TFKSIg==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, + "node_modules/type": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-function": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.1.tgz", + "integrity": "sha512-EGjWssW7Tsk4DGfE+5yluuljS1OGYWiI1J6e8puZz9nTMM51Oug8CD5Zo4gWMsOhq5BI+1bF+rWTm4Vbj3ivRA==", + "dev": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.14.1.tgz", + "integrity": "sha512-Eo1X+Y0JgGPspcANKjeR6nIqXl4VL5ldXLc15k4m9upq+eY5fhU2IueiEZL6jmHrKH8aCfbIvM/v3IrX5Hg99w==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "7.14.1", + "@typescript-eslint/parser": "7.14.1", + "@typescript-eslint/utils": "7.14.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", + "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", + "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", + "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", + "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/typescript-estree": "7.14.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", + "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "dev": true, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.23.1.tgz", + "integrity": "sha512-oT9INvydob1XV0v1d2IadrR74rLtDInLvDFfAa1CG0Pmg/vxATk7I2gSelfj271mbzeM4Da0uuDQE/Nkj3DWNw==", + "dev": true, + "peerDependencies": { + "zod": "^3.23.3" + } + } + } +} diff --git a/package.json b/package.json index a05af19c..b5fbf26a 100644 --- a/package.json +++ b/package.json @@ -1,82 +1,82 @@ -{ - "name": "seelen-ui", - "productName": "seelen-ui", - "version": "1.9.4", - "description": "Seelen UI Project", - "scripts": { - "tauri": "tauri", - "tauri:update": "ts-node scripts/UpdateTauri.ts", - "dev": "nodemon --config nodemon.json", - "test": "jest", - "build:ui": "ts-node scripts/build.ts", - "build:schemas": "ts-node scripts/createJsonSchemas.ts", - "translate": "ts-node ./scripts/translate.ts", - "lint": "eslint . --max-warnings 0", - "lint:fix": "eslint . --fix --max-warnings 0", - "postversion": "ts-node scripts/postversion.ts", - "postinstall": "lefthook install" - }, - "keywords": [], - "author": { - "name": "eythaann", - "email": "eythan.cvt@gmail.com" - }, - "repository": { - "type": "git", - "url": "https://github.com/eythaann/seelen-ui.git" - }, - "license": "Polyform Strict License", - "dependencies": { - "@tauri-apps/plugin-autostart": "^2.0.0-beta.2", - "@tauri-apps/plugin-deep-link": "^2.0.0-beta.10", - "@tauri-apps/plugin-dialog": "^2.0.0-beta.2", - "@tauri-apps/plugin-fs": "^2.0.0-beta.2", - "@tauri-apps/plugin-log": "^2.0.0-beta.2", - "@tauri-apps/plugin-process": "^2.0.0-beta.2", - "@tauri-apps/plugin-shell": "^2.0.0-beta.2", - "@tauri-apps/plugin-updater": "^2.0.0-beta.2" - }, - "devDependencies": { - "@commitlint/cli": "^19.3.0", - "@commitlint/config-conventional": "^19.2.2", - "@reduxjs/toolkit": "^2.2.1", - "@stylistic/eslint-plugin": "^1.6.2", - "@tauri-apps/api": "^2.0.0-beta.4", - "@tauri-apps/cli": "^2.0.0-beta.8", - "@types/jest": "^29.5.12", - "@types/js-yaml": "^4.0.9", - "@types/node": "^20.11.19", - "@types/react": "^18.2.56", - "@types/react-dom": "^18.2.19", - "antd": "^5.14.1", - "esbuild": "^0.20.1", - "eslint": "^8.56.0", - "eslint-plugin-simple-import-sort": "^12.0.0", - "framer-motion": "11.3.6", - "glob": "^7.2.3", - "google-translate-api-x": "^10.6.8", - "i18next": "^23.12.2", - "jest": "^29.7.0", - "js-yaml": "^4.1.0", - "json-schema-to-typescript": "^13.1.2", - "lefthook": "^1.6.18", - "lodash": "^4.17.21", - "mathjs": "^12.4.2", - "moment": "^2.30.1", - "nodemon": "^3.0.3", - "react": "18.2.0", - "react-dom": "18.2.0", - "react-i18next": "^15.0.0", - "react-icons": "^5.3.0", - "react-redux": "^9.1.0", - "readable-types": "^4.0.0", - "redux": "^5.0.1", - "toml": "^3.0.0", - "ts-jest": "^29.1.2", - "ts-node": "^10.9.2", - "typescript": "5.3.3", - "typescript-eslint": "^7.0.1", - "zod": "^3.23.4", - "zod-to-json-schema": "^3.23.0" - } -} +{ + "name": "seelen-ui", + "productName": "seelen-ui", + "version": "1.9.4", + "description": "Seelen UI Project", + "scripts": { + "tauri": "tauri", + "tauri:update": "ts-node scripts/UpdateTauri.ts", + "dev": "nodemon --config nodemon.json", + "test": "jest", + "build:ui": "ts-node scripts/build.ts", + "build:schemas": "ts-node scripts/createJsonSchemas.ts", + "translate": "ts-node ./scripts/translate.ts", + "lint": "eslint . --max-warnings 0", + "lint:fix": "eslint . --fix --max-warnings 0", + "postversion": "ts-node scripts/postversion.ts", + "postinstall": "lefthook install" + }, + "keywords": [], + "author": { + "name": "eythaann", + "email": "eythan.cvt@gmail.com" + }, + "repository": { + "type": "git", + "url": "https://github.com/eythaann/seelen-ui.git" + }, + "license": "Polyform Strict License", + "dependencies": { + "@tauri-apps/plugin-autostart": "^2.0.0-beta.2", + "@tauri-apps/plugin-deep-link": "^2.0.0-beta.10", + "@tauri-apps/plugin-dialog": "^2.0.0-beta.2", + "@tauri-apps/plugin-fs": "^2.0.0-beta.2", + "@tauri-apps/plugin-log": "^2.0.0-beta.2", + "@tauri-apps/plugin-process": "^2.0.0-beta.2", + "@tauri-apps/plugin-shell": "^2.0.0-beta.2", + "@tauri-apps/plugin-updater": "^2.0.0-beta.2" + }, + "devDependencies": { + "@commitlint/cli": "^19.3.0", + "@commitlint/config-conventional": "^19.2.2", + "@reduxjs/toolkit": "^2.2.1", + "@stylistic/eslint-plugin": "^1.6.2", + "@tauri-apps/api": "^2.0.0-beta.4", + "@tauri-apps/cli": "^2.0.0-beta.8", + "@types/jest": "^29.5.12", + "@types/js-yaml": "^4.0.9", + "@types/node": "^20.11.19", + "@types/react": "^18.2.56", + "@types/react-dom": "^18.2.19", + "antd": "^5.14.1", + "esbuild": "^0.20.1", + "eslint": "^8.56.0", + "eslint-plugin-simple-import-sort": "^12.0.0", + "framer-motion": "11.3.6", + "glob": "^7.2.3", + "google-translate-api-x": "^10.6.8", + "i18next": "^23.12.2", + "jest": "^29.7.0", + "js-yaml": "^4.1.0", + "json-schema-to-typescript": "^13.1.2", + "lefthook": "^1.6.18", + "lodash": "^4.17.21", + "mathjs": "^12.4.2", + "moment": "^2.30.1", + "nodemon": "^3.0.3", + "react": "18.2.0", + "react-dom": "18.2.0", + "react-i18next": "^15.0.0", + "react-icons": "^5.3.0", + "react-redux": "^9.1.0", + "readable-types": "^4.0.0", + "redux": "^5.0.1", + "toml": "^3.0.0", + "ts-jest": "^29.1.2", + "ts-node": "^10.9.2", + "typescript": "5.3.3", + "typescript-eslint": "^7.0.1", + "zod": "^3.23.4", + "zod-to-json-schema": "^3.23.0" + } +} diff --git a/readme.md b/readme.md index a42f3b36..a38047d5 100644 --- a/readme.md +++ b/readme.md @@ -1,108 +1,108 @@ -

- - Seelen UI -

- -

- Fully Customizable Desktop Environment for Windows -
- Available in 70+ Languages -

- -
- -[![Contributors](https://img.shields.io/github/contributors/eythaann/seelen-ui.svg)](https://github.com/eythaann/seelen-ui/graphs/contributors) -[![Last Commit](https://img.shields.io/github/last-commit/eythaann/seelen-ui.svg)](https://github.com/eythaann/seelen-ui/commits/main) -[![Version](https://img.shields.io/github/v/release/eythaann/seelen-ui.svg)](https://github.com/eythaann/seelen-ui/releases) -[![Downloads](https://img.shields.io/github/downloads/eythaann/seelen-ui/total.svg)](https://github.com/eythaann/seelen-ui/releases) - -
- -Seelen UI desktop - - - - - - -
- - - - - - - -
- -## Overview -Welcome to Seelen UI, where customization meets productivity, revolutionizing your Windows desktop experience. Seamlessly integrated into your system, Seelen UI unlocks a world of possibilities, offering an extensive array of customization features to sculpt your desktop into a personalized masterpiece of efficiency and style. - -* **Unleash Your Creativity**: With Seelen UI, your desktop becomes a canvas, ready for your creative vision. From menus to widgets, every element can be tailored to reflect your unique style and workflow. - - Seelen UI Banner - -
- -* **Boost Your Productivity**: Say goodbye to clutter and hello to organization. Seelen UI empowers you to streamline your desktop layout, ensuring that essential tools and information are always at your fingertips. Plus, with a Tiling Windows Manager for Windows, productivity reaches new heights as windows automatically arrange themselves for optimal multitasking efficiency. - - Seelen UI desktop -
- -* **Easy and Very Customizable Configuration**: Seelen UI offers an easy and highly customizable configuration through an intuitive user interface. Tweak every aspect of your desktop experience with ease, from colors and fonts to taskbar layouts and icon arrangements, all within a few clicks. - - Seelen UI desktop -
- -## Getting Started & Installation -You can choose from different installation options based on your preference: - -### Microsoft Store (recommended) -Download the latest version from the [Store](https://www.microsoft.com/store/productId/9P67C2D4T9FB?ocid=pdpshare) page. This is the recommended option because you will receive updates and a secure version of the program. - -### Winget -Install the latest version using: - -``` pwsh -winget install --id Seelen.SeelenUI -``` -This option also uses the signed `.msix` package and ensures you have the latest secure version. - -### .msix Installer -Download the `.msix` installer from the [Releases](https://github.com/eythaann/seelen-ui/releases) page. This package is signed, ensuring a secure installation. - -### Setup.exe -Download the latest version from the [Releases](https://github.com/eythaann/seelen-ui/releases) page and run the `setup.exe` installer. This option is less recommended as the installer is not signed, which may cause it to be flagged as a potential threat by some antivirus programs. - - -## Usage - -Once installed or extracted, simply open the program. The easy-to-use and intuitive GUI will guide you through the configuration process. Customize your window management experience effortlessly. - -For more detailed information and advanced features, refer to the [Seelen UI Documentation](./documentation). - -## Contributing - -We welcome contributions! -* Read the [Contribution Guidelines](CONTRIBUTING) to get started with terms. -* Read the [Project Documentation](documentation/project.md) to understand the project structure and how to use it. - -## License - -See the [LICENSE](LICENSE) file for details. - -## Contact - -For inquiries and support, please contact me on [Discord](https://discord.gg/ABfASx5ZAJ). - -## Thank You - -Happy window managing and customization with Seelen UI! +

+ + Seelen UI +

+ +

+ Fully Customizable Desktop Environment for Windows +
+ Available in 70+ Languages +

+ +
+ +[![Contributors](https://img.shields.io/github/contributors/eythaann/seelen-ui.svg)](https://github.com/eythaann/seelen-ui/graphs/contributors) +[![Last Commit](https://img.shields.io/github/last-commit/eythaann/seelen-ui.svg)](https://github.com/eythaann/seelen-ui/commits/main) +[![Version](https://img.shields.io/github/v/release/eythaann/seelen-ui.svg)](https://github.com/eythaann/seelen-ui/releases) +[![Downloads](https://img.shields.io/github/downloads/eythaann/seelen-ui/total.svg)](https://github.com/eythaann/seelen-ui/releases) + +
+ +Seelen UI desktop + + + + + + +
+ + + + + + + +
+ +## Overview +Welcome to Seelen UI, where customization meets productivity, revolutionizing your Windows desktop experience. Seamlessly integrated into your system, Seelen UI unlocks a world of possibilities, offering an extensive array of customization features to sculpt your desktop into a personalized masterpiece of efficiency and style. + +* **Unleash Your Creativity**: With Seelen UI, your desktop becomes a canvas, ready for your creative vision. From menus to widgets, every element can be tailored to reflect your unique style and workflow. + + Seelen UI Banner + +
+ +* **Boost Your Productivity**: Say goodbye to clutter and hello to organization. Seelen UI empowers you to streamline your desktop layout, ensuring that essential tools and information are always at your fingertips. Plus, with a Tiling Windows Manager for Windows, productivity reaches new heights as windows automatically arrange themselves for optimal multitasking efficiency. + + Seelen UI desktop +
+ +* **Easy and Very Customizable Configuration**: Seelen UI offers an easy and highly customizable configuration through an intuitive user interface. Tweak every aspect of your desktop experience with ease, from colors and fonts to taskbar layouts and icon arrangements, all within a few clicks. + + Seelen UI desktop +
+ +## Getting Started & Installation +You can choose from different installation options based on your preference: + +### Microsoft Store (recommended) +Download the latest version from the [Store](https://www.microsoft.com/store/productId/9P67C2D4T9FB?ocid=pdpshare) page. This is the recommended option because you will receive updates and a secure version of the program. + +### Winget +Install the latest version using: + +``` pwsh +winget install --id Seelen.SeelenUI +``` +This option also uses the signed `.msix` package and ensures you have the latest secure version. + +### .msix Installer +Download the `.msix` installer from the [Releases](https://github.com/eythaann/seelen-ui/releases) page. This package is signed, ensuring a secure installation. + +### Setup.exe +Download the latest version from the [Releases](https://github.com/eythaann/seelen-ui/releases) page and run the `setup.exe` installer. This option is less recommended as the installer is not signed, which may cause it to be flagged as a potential threat by some antivirus programs. + + +## Usage + +Once installed or extracted, simply open the program. The easy-to-use and intuitive GUI will guide you through the configuration process. Customize your window management experience effortlessly. + +For more detailed information and advanced features, refer to the [Seelen UI Documentation](./documentation). + +## Contributing + +We welcome contributions! +* Read the [Contribution Guidelines](CONTRIBUTING) to get started with terms. +* Read the [Project Documentation](documentation/project.md) to understand the project structure and how to use it. + +## License + +See the [LICENSE](LICENSE) file for details. + +## Contact + +For inquiries and support, please contact me on [Discord](https://discord.gg/ABfASx5ZAJ). + +## Thank You + +Happy window managing and customization with Seelen UI! diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 126ece36..c25ecf51 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ -[toolchain] +[toolchain] channel = "nightly-2024-06-25" \ No newline at end of file diff --git a/scripts/SubmitToStore.ps1 b/scripts/SubmitToStore.ps1 index 2681d162..a3de1edc 100644 --- a/scripts/SubmitToStore.ps1 +++ b/scripts/SubmitToStore.ps1 @@ -1,38 +1,38 @@ -Set-ExecutionPolicy RemoteSigned -Force - -# Prepare materials from previous steps and runner environment variables -$jsonContent = Get-Content -Path ".\package.json" -Raw -$jsonObject = $jsonContent | ConvertFrom-Json -$version = $jsonObject.version -$appxUploadFilePath = ".\target\release\bundle\msix\Seelen.SeelenUI_${version}.0_x64__p6yyn03m1894e.msix" - -Write-Host "MSIX file: $appxUploadFilePath" - -# $appxUploadFilePath = $PSBoundParameters["appxPathParam"] -$username = $env:PartnerCenterClientId -$password = ConvertTo-SecureString $env:PartnerCenterClientSecret -AsPlainText -Force -$appStoreId = $env:PartnerCenterStoreId -$tenantId = $env:PartnerCenterTenantId - -$scriptPath = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent - -# ********* Create temporary directory for submission artifacts ********* -$sbTempFolderPath = New-Item -Type Directory -Force -Path (Join-Path -Path $scriptPath -ChildPath 'SBTemp') - -# ********* Install StoreBroker and import PowerShell Module ********* -Set-PSRepository -Name "PSGallery" -InstallationPolicy Trusted -Install-Module -Name StoreBroker - -# ********* Authenticate Store Broker ********* -$cred = New-Object System.Management.Automation.PSCredential ($username, $password) -Set-StoreBrokerAuthentication -TenantId $tenantId -Credential $cred - -# ********* Prepare Submission Package ********* -$configFilePath = (Join-Path -Path $scriptPath -ChildPath 'submission.json') -New-SubmissionPackage -ConfigPath $configFilePath -AppxPath $appxUploadFilePath -OutPath $sbTempFolderPath -OutName 'submission' - -# ********* UPDATE SUBMISSION ********* -$submissionDataPath = Join-Path -Path $sbTempFolderPath -ChildPath 'submission.json' -$submissionPackagePath = Join-Path -Path $sbTempFolderPath -ChildPath 'submission.zip' - +Set-ExecutionPolicy RemoteSigned -Force + +# Prepare materials from previous steps and runner environment variables +$jsonContent = Get-Content -Path ".\package.json" -Raw +$jsonObject = $jsonContent | ConvertFrom-Json +$version = $jsonObject.version +$appxUploadFilePath = ".\target\release\bundle\msix\Seelen.SeelenUI_${version}.0_x64__p6yyn03m1894e.msix" + +Write-Host "MSIX file: $appxUploadFilePath" + +# $appxUploadFilePath = $PSBoundParameters["appxPathParam"] +$username = $env:PartnerCenterClientId +$password = ConvertTo-SecureString $env:PartnerCenterClientSecret -AsPlainText -Force +$appStoreId = $env:PartnerCenterStoreId +$tenantId = $env:PartnerCenterTenantId + +$scriptPath = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent + +# ********* Create temporary directory for submission artifacts ********* +$sbTempFolderPath = New-Item -Type Directory -Force -Path (Join-Path -Path $scriptPath -ChildPath 'SBTemp') + +# ********* Install StoreBroker and import PowerShell Module ********* +Set-PSRepository -Name "PSGallery" -InstallationPolicy Trusted +Install-Module -Name StoreBroker + +# ********* Authenticate Store Broker ********* +$cred = New-Object System.Management.Automation.PSCredential ($username, $password) +Set-StoreBrokerAuthentication -TenantId $tenantId -Credential $cred + +# ********* Prepare Submission Package ********* +$configFilePath = (Join-Path -Path $scriptPath -ChildPath 'submission.json') +New-SubmissionPackage -ConfigPath $configFilePath -AppxPath $appxUploadFilePath -OutPath $sbTempFolderPath -OutName 'submission' + +# ********* UPDATE SUBMISSION ********* +$submissionDataPath = Join-Path -Path $sbTempFolderPath -ChildPath 'submission.json' +$submissionPackagePath = Join-Path -Path $sbTempFolderPath -ChildPath 'submission.zip' + Update-ApplicationSubmission -Verbose -Force -ReplacePackages -AutoCommit -AppId $appStoreId -SubmissionDataPath $submissionDataPath -PackagePath $submissionPackagePath -NoStatus \ No newline at end of file diff --git a/scripts/UpdateTauri.ts b/scripts/UpdateTauri.ts index 8059f4c3..62a3f06b 100644 --- a/scripts/UpdateTauri.ts +++ b/scripts/UpdateTauri.ts @@ -1,31 +1,31 @@ -import packageJson from '../package.json'; -import { execSync } from 'child_process'; -import { readFileSync } from 'fs'; -import toml from 'toml'; - -let dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies }; -let toUpdate: string[] = []; - -for (let key in dependencies) { - if (key.startsWith('@tauri-apps/')) { - toUpdate.push(key); - } -} - -let command = `npm update ${toUpdate.join(' ')}`; -console.log(`${command}\n`); -execSync(command, { stdio: 'inherit' }); - -const cargoToml = toml.parse(readFileSync('Cargo.toml', 'utf-8')); -dependencies = { ...cargoToml['build-dependencies'], ...cargoToml.dependencies }; -toUpdate = []; - -for (let key in dependencies) { - if (key.startsWith('tauri')) { - toUpdate.push(key); - } -} - -command = `cargo update ${toUpdate.join(' ')}`; -console.log(`${command}\n`); -execSync(command, { stdio: 'inherit' }); +import packageJson from '../package.json'; +import { execSync } from 'child_process'; +import { readFileSync } from 'fs'; +import toml from 'toml'; + +let dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies }; +let toUpdate: string[] = []; + +for (let key in dependencies) { + if (key.startsWith('@tauri-apps/')) { + toUpdate.push(key); + } +} + +let command = `npm update ${toUpdate.join(' ')}`; +console.log(`${command}\n`); +execSync(command, { stdio: 'inherit' }); + +const cargoToml = toml.parse(readFileSync('Cargo.toml', 'utf-8')); +dependencies = { ...cargoToml['build-dependencies'], ...cargoToml.dependencies }; +toUpdate = []; + +for (let key in dependencies) { + if (key.startsWith('tauri')) { + toUpdate.push(key); + } +} + +command = `cargo update ${toUpdate.join(' ')}`; +console.log(`${command}\n`); +execSync(command, { stdio: 'inherit' }); diff --git a/scripts/build.rs b/scripts/build.rs index 261851f6..158c0512 100644 --- a/scripts/build.rs +++ b/scripts/build.rs @@ -1,3 +1,3 @@ -fn main() { - tauri_build::build(); -} +fn main() { + tauri_build::build(); +} diff --git a/scripts/build.ts b/scripts/build.ts index 27d5bf10..d8aaa7bf 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -1,32 +1,32 @@ -import esbuild from 'esbuild'; -import fs from 'fs'; -import path from 'path'; - -async function main() { - const appFolders = fs - .readdirSync('src/apps') - .filter((item) => item !== 'shared' && fs.statSync(path.join('src/apps', item)).isDirectory()); - - await esbuild.build({ - entryPoints: appFolders.map((folder) => `./src/apps/${folder}/index.tsx`), - bundle: true, - minify: false, - sourcemap: true, - outdir: './dist', - jsx: 'automatic', - define: { - 'process.env': JSON.stringify({ - packageVersion: JSON.parse(fs.readFileSync('package.json', 'utf-8')).version, - }), - }, - loader: { - '.yml': 'text', - }, - }); - - appFolders.forEach((folder) => { - fs.cpSync(`src/apps/${folder}/index.html`, `dist/${folder}/index.html`); - }); -} - -main(); +import esbuild from 'esbuild'; +import fs from 'fs'; +import path from 'path'; + +async function main() { + const appFolders = fs + .readdirSync('src/apps') + .filter((item) => item !== 'shared' && fs.statSync(path.join('src/apps', item)).isDirectory()); + + await esbuild.build({ + entryPoints: appFolders.map((folder) => `./src/apps/${folder}/index.tsx`), + bundle: true, + minify: false, + sourcemap: true, + outdir: './dist', + jsx: 'automatic', + define: { + 'process.env': JSON.stringify({ + packageVersion: JSON.parse(fs.readFileSync('package.json', 'utf-8')).version, + }), + }, + loader: { + '.yml': 'text', + }, + }); + + appFolders.forEach((folder) => { + fs.cpSync(`src/apps/${folder}/index.html`, `dist/${folder}/index.html`); + }); +} + +main(); diff --git a/scripts/bundle.msix.ts b/scripts/bundle.msix.ts index 40f47cd1..b2217108 100644 --- a/scripts/bundle.msix.ts +++ b/scripts/bundle.msix.ts @@ -1,52 +1,52 @@ -import packageJson from '../package.json'; -import tauriConfig from '../tauri.conf.json'; -import { execSync } from 'child_process'; -import fs from 'fs'; -import glob from 'glob'; -import path from 'path'; - -console.info('Building MSIX...'); -const msixCmdsPath = path.resolve('target/release/msix/commands.txt'); -const msixTemplatePath = path.resolve('templates/installer.msix'); - -const packageVersion = packageJson.version + '.0'; -const installer_msix_path = path.resolve( - `target/release/bundle/msix/Seelen.SeelenUI_${packageVersion}_x64__p6yyn03m1894e.msix`, -); - -if (fs.existsSync(msixCmdsPath)) { - fs.rmSync(msixCmdsPath); -} else { - fs.mkdirSync(path.dirname(msixCmdsPath)); -} - -fs.appendFileSync(msixCmdsPath, `setIdentity --packageVersion ${packageVersion}\n`); - -fs.appendFileSync( - msixCmdsPath, - `addFile --target "${packageJson.productName}.exe" --source "${path.resolve( - `target/release/${packageJson.productName}.exe`, - )}"\n`, -); - -tauriConfig.bundle.resources.forEach((pattern) => { - let files = glob.sync(pattern, { nodir: true }); - files.forEach((file) => { - fs.appendFileSync( - msixCmdsPath, - `addFile --target "${file}" --source "${path.resolve(`target/release/${file}`)}"\n`, - ); - }); -}); - -try { - fs.mkdirSync(installer_msix_path.split(path.sep).slice(0, -1).join(path.sep), { - recursive: true, - }); - fs.copyFileSync(msixTemplatePath, installer_msix_path); - - const buffer = execSync(`msixHeroCli edit "${installer_msix_path}" list "${msixCmdsPath}"`); - console.info(buffer.toString()); -} catch (error) { - console.error('\n', error); -} +import packageJson from '../package.json'; +import tauriConfig from '../tauri.conf.json'; +import { execSync } from 'child_process'; +import fs from 'fs'; +import glob from 'glob'; +import path from 'path'; + +console.info('Building MSIX...'); +const msixCmdsPath = path.resolve('target/release/msix/commands.txt'); +const msixTemplatePath = path.resolve('templates/installer.msix'); + +const packageVersion = packageJson.version + '.0'; +const installer_msix_path = path.resolve( + `target/release/bundle/msix/Seelen.SeelenUI_${packageVersion}_x64__p6yyn03m1894e.msix`, +); + +if (fs.existsSync(msixCmdsPath)) { + fs.rmSync(msixCmdsPath); +} else { + fs.mkdirSync(path.dirname(msixCmdsPath)); +} + +fs.appendFileSync(msixCmdsPath, `setIdentity --packageVersion ${packageVersion}\n`); + +fs.appendFileSync( + msixCmdsPath, + `addFile --target "${packageJson.productName}.exe" --source "${path.resolve( + `target/release/${packageJson.productName}.exe`, + )}"\n`, +); + +tauriConfig.bundle.resources.forEach((pattern) => { + let files = glob.sync(pattern, { nodir: true }); + files.forEach((file) => { + fs.appendFileSync( + msixCmdsPath, + `addFile --target "${file}" --source "${path.resolve(`target/release/${file}`)}"\n`, + ); + }); +}); + +try { + fs.mkdirSync(installer_msix_path.split(path.sep).slice(0, -1).join(path.sep), { + recursive: true, + }); + fs.copyFileSync(msixTemplatePath, installer_msix_path); + + const buffer = execSync(`msixHeroCli edit "${installer_msix_path}" list "${msixCmdsPath}"`); + console.info(buffer.toString()); +} catch (error) { + console.error('\n', error); +} diff --git a/scripts/createJsonSchemas.ts b/scripts/createJsonSchemas.ts index 3dae6439..46481b67 100644 --- a/scripts/createJsonSchemas.ts +++ b/scripts/createJsonSchemas.ts @@ -1,29 +1,29 @@ -import { writeFileSync } from 'fs'; -import { zodToJsonSchema } from 'zod-to-json-schema'; - -import { LayoutSchema } from '../src/apps/shared/schemas/Layout'; -import { PlaceholderSchema } from '../src/apps/shared/schemas/Placeholders'; -import { SettingsSchema } from '../src/apps/shared/schemas/Settings'; -import { ThemeSchema } from '../src/apps/shared/schemas/Theme'; - -(async function main() { - writeFileSync( - 'documentation/schemas/layout.schema.json', - JSON.stringify(zodToJsonSchema(LayoutSchema), null, 2), - ); - - writeFileSync( - 'documentation/schemas/settings.schema.json', - JSON.stringify(zodToJsonSchema(SettingsSchema), null, 2), - ); - - writeFileSync( - 'documentation/schemas/theme.schema.json', - JSON.stringify(zodToJsonSchema(ThemeSchema), null, 2), - ); - - writeFileSync( - 'documentation/schemas/placeholder.schema.json', - JSON.stringify(zodToJsonSchema(PlaceholderSchema), null, 2), - ); -})(); +import { writeFileSync } from 'fs'; +import { zodToJsonSchema } from 'zod-to-json-schema'; + +import { LayoutSchema } from '../src/apps/shared/schemas/Layout'; +import { PlaceholderSchema } from '../src/apps/shared/schemas/Placeholders'; +import { SettingsSchema } from '../src/apps/shared/schemas/Settings'; +import { ThemeSchema } from '../src/apps/shared/schemas/Theme'; + +(async function main() { + writeFileSync( + 'documentation/schemas/layout.schema.json', + JSON.stringify(zodToJsonSchema(LayoutSchema), null, 2), + ); + + writeFileSync( + 'documentation/schemas/settings.schema.json', + JSON.stringify(zodToJsonSchema(SettingsSchema), null, 2), + ); + + writeFileSync( + 'documentation/schemas/theme.schema.json', + JSON.stringify(zodToJsonSchema(ThemeSchema), null, 2), + ); + + writeFileSync( + 'documentation/schemas/placeholder.schema.json', + JSON.stringify(zodToJsonSchema(PlaceholderSchema), null, 2), + ); +})(); diff --git a/scripts/postversion.ts b/scripts/postversion.ts index 56191255..b399a962 100644 --- a/scripts/postversion.ts +++ b/scripts/postversion.ts @@ -1,16 +1,16 @@ -import { execSync } from 'child_process'; -import fs from 'fs'; - -let changelogContent = fs.readFileSync('changelog.md', 'utf-8'); -changelogContent = changelogContent.replace(/## \[Unreleased\]/g, `## \[Unreleased\]\n## [${process.env.npm_new_version}]`); -fs.writeFileSync('changelog.md', changelogContent); - -execSync('git add changelog.md'); - -let cargoTomlContent = fs.readFileSync('Cargo.toml', 'utf-8'); -cargoTomlContent = cargoTomlContent.replace(/^version\s*=\s*".*"/m, `version = "${process.env.npm_new_version}"`); -fs.writeFileSync('Cargo.toml', cargoTomlContent); -execSync('cargo update -p seelen-ui'); - -execSync('git add Cargo.toml Cargo.lock'); +import { execSync } from 'child_process'; +import fs from 'fs'; + +let changelogContent = fs.readFileSync('changelog.md', 'utf-8'); +changelogContent = changelogContent.replace(/## \[Unreleased\]/g, `## \[Unreleased\]\n## [${process.env.npm_new_version}]`); +fs.writeFileSync('changelog.md', changelogContent); + +execSync('git add changelog.md'); + +let cargoTomlContent = fs.readFileSync('Cargo.toml', 'utf-8'); +cargoTomlContent = cargoTomlContent.replace(/^version\s*=\s*".*"/m, `version = "${process.env.npm_new_version}"`); +fs.writeFileSync('Cargo.toml', cargoTomlContent); +execSync('cargo update -p seelen-ui'); + +execSync('git add Cargo.toml Cargo.lock'); execSync('git commit --amend --no-edit'); \ No newline at end of file diff --git a/scripts/submission.json b/scripts/submission.json index 3d7f95b0..eea9d2b0 100644 --- a/scripts/submission.json +++ b/scripts/submission.json @@ -1,8 +1,8 @@ -{ - "packageParameters": { - "DisableAutoPackageNameFormatting": true - }, - "appSubmission": { - "appId": "9P67C2D4T9FB" - } +{ + "packageParameters": { + "DisableAutoPackageNameFormatting": true + }, + "appSubmission": { + "appId": "9P67C2D4T9FB" + } } \ No newline at end of file diff --git a/scripts/translate.ts b/scripts/translate.ts index ec5f6ec0..60a0135c 100644 --- a/scripts/translate.ts +++ b/scripts/translate.ts @@ -1,55 +1,55 @@ -import { existsSync, readFileSync, writeFileSync } from 'fs'; -import { translate } from 'google-translate-api-x'; -import yaml from 'js-yaml'; - -import { LanguageList } from '../src/apps/shared/lang'; - -const toTranslate = LanguageList.map((lang) => lang.value).filter((lang) => lang !== 'en'); - -async function translateObject(base: any, lang: string, mut_obj: any) { - await Promise.all( - Object.entries(base).map(async ([key, value]) => { - if (typeof value === 'object') { - mut_obj[key] ??= {}; - await translateObject(value, lang, mut_obj[key]); - } - - // avoid modify already translated values - if (typeof value === 'string' && !mut_obj[key]) { - const res = await translate(value, { - from: 'en', - to: lang, - forceTo: true, - }); - mut_obj[key] = res.text; - } - }), - ); -} - -async function completeTranslationsFor(app: string) { - const path = `./src/apps/${app}/i18n/translations`; - - const en = yaml.load(readFileSync(`${path}/en.yml`, 'utf8')); - for (const lang of toTranslate) { - const filePath = `${path}/${lang}.yml`; - console.log(filePath); - - if (!existsSync(filePath)) { - writeFileSync(filePath, yaml.dump({})); - } - - const trans = yaml.load(readFileSync(filePath, 'utf8')); - await translateObject(en, lang, trans); - writeFileSync(filePath, yaml.dump(trans)); - } -} - -async function main() { - await completeTranslationsFor('toolbar'); - await completeTranslationsFor('seelenweg'); - await completeTranslationsFor('settings'); - await completeTranslationsFor('update'); -} - -main().catch(console.error); +import { existsSync, readFileSync, writeFileSync } from 'fs'; +import { translate } from 'google-translate-api-x'; +import yaml from 'js-yaml'; + +import { LanguageList } from '../src/apps/shared/lang'; + +const toTranslate = LanguageList.map((lang) => lang.value).filter((lang) => lang !== 'en'); + +async function translateObject(base: any, lang: string, mut_obj: any) { + await Promise.all( + Object.entries(base).map(async ([key, value]) => { + if (typeof value === 'object') { + mut_obj[key] ??= {}; + await translateObject(value, lang, mut_obj[key]); + } + + // avoid modify already translated values + if (typeof value === 'string' && !mut_obj[key]) { + const res = await translate(value, { + from: 'en', + to: lang, + forceTo: true, + }); + mut_obj[key] = res.text; + } + }), + ); +} + +async function completeTranslationsFor(app: string) { + const path = `./src/apps/${app}/i18n/translations`; + + const en = yaml.load(readFileSync(`${path}/en.yml`, 'utf8')); + for (const lang of toTranslate) { + const filePath = `${path}/${lang}.yml`; + console.log(filePath); + + if (!existsSync(filePath)) { + writeFileSync(filePath, yaml.dump({})); + } + + const trans = yaml.load(readFileSync(filePath, 'utf8')); + await translateObject(en, lang, trans); + writeFileSync(filePath, yaml.dump(trans)); + } +} + +async function main() { + await completeTranslationsFor('toolbar'); + await completeTranslationsFor('seelenweg'); + await completeTranslationsFor('settings'); + await completeTranslationsFor('update'); +} + +main().catch(console.error); diff --git a/src/apps/seelen_wm/index.html b/src/apps/seelen_wm/index.html index 5f5b43cd..607ed66a 100644 --- a/src/apps/seelen_wm/index.html +++ b/src/apps/seelen_wm/index.html @@ -1,10 +1,10 @@ - - - - - - - -
- - + + + + + + + +
+ + diff --git a/src/apps/seelen_wm/index.tsx b/src/apps/seelen_wm/index.tsx index 3d1c0a11..05ae9fe4 100644 --- a/src/apps/seelen_wm/index.tsx +++ b/src/apps/seelen_wm/index.tsx @@ -1,46 +1,46 @@ -import { ErrorBoundary } from '../seelenweg/components/Error'; -import { wrapConsole } from '../shared/ConsoleWrapper'; -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; -import { useEffect } from 'react'; -import { createRoot } from 'react-dom/client'; -import { Provider } from 'react-redux'; - -import { Layout } from './modules/layout/infra'; -import { loadStore, registerStoreEvents, store } from './modules/shared/store/infra'; - -import './styles/colors.css'; -import './styles/variables.css'; -import './styles/global.css'; - -async function Main() { - wrapConsole(); - - const container = document.getElementById('root'); - if (!container) { - throw new Error('Root container not found'); - } - - await loadStore(); - await registerStoreEvents(); - - const WrappedRoot = () => { - useEffect(() => { - getCurrentWebviewWindow().show(); - let view = getCurrentWebviewWindow(); - view.emitTo(view.label, 'complete-setup'); - view.emit('register-colors-events'); - }, []); - - return ( - - Something went wrong}> - - - - ); - }; - - createRoot(container).render(); -} - -Main(); +import { ErrorBoundary } from '../seelenweg/components/Error'; +import { wrapConsole } from '../shared/ConsoleWrapper'; +import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; +import { useEffect } from 'react'; +import { createRoot } from 'react-dom/client'; +import { Provider } from 'react-redux'; + +import { Layout } from './modules/layout/infra'; +import { loadStore, registerStoreEvents, store } from './modules/shared/store/infra'; + +import './styles/colors.css'; +import './styles/variables.css'; +import './styles/global.css'; + +async function Main() { + wrapConsole(); + + const container = document.getElementById('root'); + if (!container) { + throw new Error('Root container not found'); + } + + await loadStore(); + await registerStoreEvents(); + + const WrappedRoot = () => { + useEffect(() => { + getCurrentWebviewWindow().show(); + let view = getCurrentWebviewWindow(); + view.emitTo(view.label, 'complete-setup'); + view.emit('register-colors-events'); + }, []); + + return ( + + Something went wrong}> + + + + ); + }; + + createRoot(container).render(); +} + +Main(); diff --git a/src/apps/seelen_wm/modules/layout/app.ts b/src/apps/seelen_wm/modules/layout/app.ts index a8259c30..128c0dea 100644 --- a/src/apps/seelen_wm/modules/layout/app.ts +++ b/src/apps/seelen_wm/modules/layout/app.ts @@ -1,505 +1,505 @@ -import { - FallbackNode, - HorizontalBranchNode, - LeafNode, - NodeSubtype, - NodeType, - StackNode, - VerticalBranchNode, -} from '../../../shared/schemas/Layout'; -import { clone } from 'lodash'; -import { evaluate } from 'mathjs'; - -import { FocusAction } from '../shared/store/domain'; -import { HWND } from '../shared/utils/domain'; -import { BranchNode, Node, Reservation, Sizing } from './domain'; - -export function clearContainer(container: Node): void { - switch (container.type) { - case NodeType.Stack: - case NodeType.Fallback: - container.handles = []; - container.active = null; - break; - - case NodeType.Leaf: - if (container.handle) { - container.handle = null; - } - break; - - case NodeType.Horizontal: - case NodeType.Vertical: - for (const child of container.children) { - clearContainer(child); - } - break; - - default: - console.error('Unknown container type'); - } -} - -export function reIndexContainer(container: Node, handles: HWND[]): void { - clearContainer(container); - const node = NodeImpl.from(container); - handles.forEach((handle) => { - node.addHandle(handle, handles.length); - }); -} - -export class NodeImpl { - private readonly ref: T; - - private constructor(node: T) { - this.ref = node; - } - - static from(node: T): NodeImpl { - return new NodeImpl(node); - } - - /** - * @param handle the handle of the node - * @param insertAfter the priority of the node to insert after - * @returns a new leaf node - */ - static newLeaf(handle: HWND | null, insertAfter: number = 0): LeafNode { - return { - type: NodeType.Leaf, - subtype: NodeSubtype.Temporal, - priority: insertAfter + 1, - growFactor: 1, - handle, - }; - } - - get length(): number { - if (this.isLeaf()) { - return this.ref.handle ? 1 : 0; - } - - if (this.isFallback() || this.isStack()) { - return this.ref.handles.length; - } - - if (this.isBranch()) { - return this.ref.children.reduce((acc, child) => acc + NodeImpl.from(child).length, 0); - } - - return 0; - } - - get inner(): T { - return this.ref; - } - - clone_ref(): T { - return clone(this.ref); - } - - private unreachable(): never { - console.error(`Node type ${this.ref.type} is not implemented`); - throw new Error(); - } - - get currentHandle(): HWND | null { - if (this.isFallback()) { - return this.ref.active; - } - if (this.isStack()) { - return this.ref.active; - } - if (this.isLeaf()) { - return this.ref.handle; - } - return null; - } - - isLeaf(): this is NodeImpl { - return this.ref.type === NodeType.Leaf; - } - - isFallback(): this is NodeImpl { - return this.ref.type === NodeType.Fallback; - } - - isStack(): this is NodeImpl { - return this.ref.type === NodeType.Stack; - } - - isBranch(): this is NodeImpl { - return this.ref.type === NodeType.Horizontal || this.ref.type === NodeType.Vertical; - } - - isHorizontal(): this is NodeImpl { - return this.ref.type === NodeType.Horizontal; - } - - isVertical(): this is NodeImpl { - return this.ref.type === NodeType.Vertical; - } - - isTemporal(): this is NodeImpl { - return this.ref.subtype === NodeSubtype.Temporal; - } - - isEmpty(): boolean { - if (this.isLeaf()) { - return !this.ref.handle; - } - - if (this.isFallback()) { - return this.ref.handles.length === 0; - } - - if (this.isBranch()) { - return this.ref.children.every((node) => NodeImpl.from(node).isEmpty()); - } - - this.unreachable(); - } - - isFull(): boolean { - if (this.isLeaf()) { - return !!this.ref.handle; - } - - if (this.isFallback()) { - // fallback nodes can not be fulled this allow infinite number of handles - return false; - } - - if (this.isBranch()) { - return this.ref.children.every((node) => NodeImpl.from(node).isFull()); - } - - this.unreachable(); - } - - // total will be length + 1 supposing that the node is not full - addHandle(handle: number, total = this.length + 1): boolean { - if (this.ref.condition && !evaluate(this.ref.condition, { total })) { - return false; - } - - if (this.isLeaf()) { - this.ref.handle = handle; - return true; - } - - if (this.isFallback()) { - this.ref.handles.push(handle); - this.ref.active = handle; - return true; - } - - if (this.isBranch()) { - const sortedByPriority = [...this.ref.children].sort((a, b) => a.priority - b.priority); - for (const child of sortedByPriority) { - const node = NodeImpl.from(child); - if (!node.isFull() && node.addHandle(handle, total)) { - return true; - } - } - return false; - } - - this.unreachable(); - } - - removeHandle(handle: number): boolean { - if (this.isFallback()) { - const index = this.ref.handles.indexOf(handle); - if (index !== -1) { - this.ref.handles.splice(index, 1); - if (handle === this.ref.active) { - this.ref.active = this.ref.handles[0] || null; - } - return true; - } - return false; - } - - if (this.isLeaf() && this.ref.handle === handle) { - this.ref.handle = null; - return true; - } - - if (this.isBranch()) { - for (let index = 0; index < this.ref.children.length; index++) { - const child = NodeImpl.from(this.ref.children[index]!); - if (child.removeHandle(handle)) { - if (child.isTemporal() && child.isEmpty() && (child.isLeaf() || child.isStack())) { - this.ref.children.splice(index, 1); - } - return true; - } - } - } - - return false; - } - - mutateToStacked(): NodeImpl { - if (this.isLeaf()) { - let ref = this.ref as any; - ref.type = NodeType.Fallback; - ref.subtype = NodeSubtype.Temporal; - ref.handles = []; - ref.active = null; - - if (this.ref.handle) { - ref.handles.push(this.ref.handle); - ref.active = this.ref.handle; - } - - delete ref.handle; - } - - if (this.isBranch()) { - throw new Error('Cannot mutate branch to stacked'); - } - - return this as NodeImpl; - } - - mutateToBranch(type: NodeType.Horizontal | NodeType.Vertical): NodeImpl { - if (this.isBranch()) { - throw new Error('Cannot mutate branch to branch'); - } - - let copy = this.clone_ref(); - let ref = this.ref as any; - ref.type = type; - ref.subtype = NodeSubtype.Temporal; - ref.children = [copy]; - - delete ref.handle; - // TODO(eythan) check priorities for stacked - delete ref.handles; - delete ref.active; - - return this as NodeImpl; - } - - concreteReservation(hwnd: HWND, reservation: Reservation, activeHandle: number): boolean { - console.trace(`Reserving ${reservation} for ${hwnd} on ${activeHandle}`); - - const found = this.getNodeContaining(activeHandle); - if (!found) { - console.error('Could not find node containing handle', activeHandle); - return false; - } - - const node = NodeImpl.from(found); - - switch (reservation) { - case Reservation.Stack: { - if (node.isFallback()) { - node.ref.handles.push(hwnd); - } - if (node.isLeaf()) { - const mutated = node.mutateToStacked(); - mutated.ref.handles.push(hwnd); - } - return true; - } - case Reservation.Left: { - const mutated = node.mutateToBranch(NodeType.Horizontal); - mutated.ref.children.unshift(NodeImpl.newLeaf(hwnd, mutated.ref.children[0]!.priority)); - return true; - } - case Reservation.Right: { - const mutated = node.mutateToBranch(NodeType.Horizontal); - mutated.ref.children.push(NodeImpl.newLeaf(hwnd, mutated.ref.children[0]!.priority)); - return true; - } - case Reservation.Top: { - const mutated = node.mutateToBranch(NodeType.Vertical); - mutated.ref.children.unshift(NodeImpl.newLeaf(hwnd, mutated.ref.children[0]!.priority)); - return true; - } - case Reservation.Bottom: { - const mutated = node.mutateToBranch(NodeType.Vertical); - mutated.ref.children.push(NodeImpl.newLeaf(hwnd, mutated.ref.children[0]!.priority)); - return true; - } - default: - console.error(`Unknown reservation ${reservation}`); - return false; - } - } - - getNodeContaining(searched: HWND): LeafNode | FallbackNode | null { - if (this.isLeaf()) { - return this.ref.handle === searched ? this.ref : null; - } - - if (this.isFallback()) { - return this.ref.handles.includes(searched) ? this.ref : null; - } - - if (this.isBranch()) { - for (const child of this.ref.children) { - const result = NodeImpl.from(child).getNodeContaining(searched); - if (result) { - return result; - } - } - return null; - } - - this.unreachable(); - } - - trace(to: Node, result: Node[] = []): Node[] { - if (this.isLeaf() && this.ref === to) { - result.push(this.ref); - } - - if (this.isFallback() && this.ref === to) { - result.push(this.ref); - } - - if (this.isBranch()) { - for (const child of this.ref.children) { - const traced = NodeImpl.from(child).trace(to); - if (traced.length) { - result.push(this.ref, ...traced); - } - } - } - - return result; - } - - resetGrowFactor() { - this.ref.growFactor = 1; - if (this.isBranch()) { - for (const child of this.ref.children) { - NodeImpl.from(child).resetGrowFactor(); - } - } - } - - reIndexingGrowFactor() { - if (this.isBranch()) { - const noEmptyChildren = this.ref.children.filter((child) => !NodeImpl.from(child).isEmpty()); - - const min = noEmptyChildren.reduce((acc, child) => Math.min(acc, child.growFactor), Infinity); - const scaleFactor = 1 / min; - - noEmptyChildren.forEach((child) => { - child.growFactor = Number((child.growFactor * scaleFactor).toFixed(2)); - }); - - for (const child of this.ref.children) { - NodeImpl.from(child).reIndexingGrowFactor(); - } - } - } - - updateGrowFactor(handle: HWND, axis: 'x' | 'y', action: Sizing) { - const result = this.getNodeContaining(handle); - if (!result) { - console.error('Could not find node containing handle', handle); - return; - } - - const trace = this.trace(result); - - const idx = trace.findLastIndex((_node) => { - const node = NodeImpl.from(_node); - if (!node.isBranch()) { - return false; - } - - if (node.ref.children.filter((child) => !NodeImpl.from(child).isEmpty()).length < 2) { - return false; - } - - return axis === 'x' - ? node.ref.type === NodeType.Horizontal - : node.ref.type === NodeType.Vertical; - }); - - if (idx === -1) { - console.error('Can\'t resize root'); - return; - } - - const parent = trace[idx] as BranchNode; - const nodeToResize = trace[idx + 1]!; - - const noEmptyChildren = parent.children.filter((child) => !NodeImpl.from(child).isEmpty()); - - const total = noEmptyChildren.reduce((acc, child) => acc + child.growFactor, 0); - const delta = 0.1; - - nodeToResize.growFactor = - action === Sizing.Increase - ? nodeToResize.growFactor + total * delta - : nodeToResize.growFactor - total * delta; - - this.reIndexingGrowFactor(); - } - - getLeafByPriority(): LeafNode | FallbackNode | StackNode | null { - if (this.isLeaf()) { - return this.ref.handle ? this.ref : null; - } - - if (this.isFallback() || this.isStack()) { - return this.ref.active ? this.ref : null; - } - - if (this.isBranch()) { - const sorted = [...this.ref.children].sort((a, b) => a.priority - b.priority); - for (const child of sorted) { - const node = NodeImpl.from(child); - const result = node.getLeafByPriority(); - if (result) { - return result; - } - } - } - - return null; - } - - getNodeAtSide(from: HWND, side: FocusAction): LeafNode | FallbackNode | StackNode | null { - const result = this.getNodeContaining(from); - if (!result) { - console.error('Could not find node containing handle', from); - return null; - } - - const trace = this.trace(result); - const axis = [FocusAction.Left, FocusAction.Right].includes(side) - ? NodeType.Horizontal - : NodeType.Vertical; - const after = [FocusAction.Right, FocusAction.Down].includes(side); - - let lastAncestor: Node = trace.at(-1)!; - for (const node of trace.reverse()) { - if (node.type != axis) { - lastAncestor = node; - continue; - } - - let idx = node.children.indexOf(lastAncestor); - if (idx === -1) { - console.error('Error in Trace algorithm'); - return null; - } - idx = after ? idx + 1 : idx - 1; - if (idx >= 0 && idx < node.children.length) { - let next = NodeImpl.from(node.children[idx]!); - return next.getLeafByPriority(); - } - } - - return null; - } -} +import { + FallbackNode, + HorizontalBranchNode, + LeafNode, + NodeSubtype, + NodeType, + StackNode, + VerticalBranchNode, +} from '../../../shared/schemas/Layout'; +import { clone } from 'lodash'; +import { evaluate } from 'mathjs'; + +import { FocusAction } from '../shared/store/domain'; +import { HWND } from '../shared/utils/domain'; +import { BranchNode, Node, Reservation, Sizing } from './domain'; + +export function clearContainer(container: Node): void { + switch (container.type) { + case NodeType.Stack: + case NodeType.Fallback: + container.handles = []; + container.active = null; + break; + + case NodeType.Leaf: + if (container.handle) { + container.handle = null; + } + break; + + case NodeType.Horizontal: + case NodeType.Vertical: + for (const child of container.children) { + clearContainer(child); + } + break; + + default: + console.error('Unknown container type'); + } +} + +export function reIndexContainer(container: Node, handles: HWND[]): void { + clearContainer(container); + const node = NodeImpl.from(container); + handles.forEach((handle) => { + node.addHandle(handle, handles.length); + }); +} + +export class NodeImpl { + private readonly ref: T; + + private constructor(node: T) { + this.ref = node; + } + + static from(node: T): NodeImpl { + return new NodeImpl(node); + } + + /** + * @param handle the handle of the node + * @param insertAfter the priority of the node to insert after + * @returns a new leaf node + */ + static newLeaf(handle: HWND | null, insertAfter: number = 0): LeafNode { + return { + type: NodeType.Leaf, + subtype: NodeSubtype.Temporal, + priority: insertAfter + 1, + growFactor: 1, + handle, + }; + } + + get length(): number { + if (this.isLeaf()) { + return this.ref.handle ? 1 : 0; + } + + if (this.isFallback() || this.isStack()) { + return this.ref.handles.length; + } + + if (this.isBranch()) { + return this.ref.children.reduce((acc, child) => acc + NodeImpl.from(child).length, 0); + } + + return 0; + } + + get inner(): T { + return this.ref; + } + + clone_ref(): T { + return clone(this.ref); + } + + private unreachable(): never { + console.error(`Node type ${this.ref.type} is not implemented`); + throw new Error(); + } + + get currentHandle(): HWND | null { + if (this.isFallback()) { + return this.ref.active; + } + if (this.isStack()) { + return this.ref.active; + } + if (this.isLeaf()) { + return this.ref.handle; + } + return null; + } + + isLeaf(): this is NodeImpl { + return this.ref.type === NodeType.Leaf; + } + + isFallback(): this is NodeImpl { + return this.ref.type === NodeType.Fallback; + } + + isStack(): this is NodeImpl { + return this.ref.type === NodeType.Stack; + } + + isBranch(): this is NodeImpl { + return this.ref.type === NodeType.Horizontal || this.ref.type === NodeType.Vertical; + } + + isHorizontal(): this is NodeImpl { + return this.ref.type === NodeType.Horizontal; + } + + isVertical(): this is NodeImpl { + return this.ref.type === NodeType.Vertical; + } + + isTemporal(): this is NodeImpl { + return this.ref.subtype === NodeSubtype.Temporal; + } + + isEmpty(): boolean { + if (this.isLeaf()) { + return !this.ref.handle; + } + + if (this.isFallback()) { + return this.ref.handles.length === 0; + } + + if (this.isBranch()) { + return this.ref.children.every((node) => NodeImpl.from(node).isEmpty()); + } + + this.unreachable(); + } + + isFull(): boolean { + if (this.isLeaf()) { + return !!this.ref.handle; + } + + if (this.isFallback()) { + // fallback nodes can not be fulled this allow infinite number of handles + return false; + } + + if (this.isBranch()) { + return this.ref.children.every((node) => NodeImpl.from(node).isFull()); + } + + this.unreachable(); + } + + // total will be length + 1 supposing that the node is not full + addHandle(handle: number, total = this.length + 1): boolean { + if (this.ref.condition && !evaluate(this.ref.condition, { total })) { + return false; + } + + if (this.isLeaf()) { + this.ref.handle = handle; + return true; + } + + if (this.isFallback()) { + this.ref.handles.push(handle); + this.ref.active = handle; + return true; + } + + if (this.isBranch()) { + const sortedByPriority = [...this.ref.children].sort((a, b) => a.priority - b.priority); + for (const child of sortedByPriority) { + const node = NodeImpl.from(child); + if (!node.isFull() && node.addHandle(handle, total)) { + return true; + } + } + return false; + } + + this.unreachable(); + } + + removeHandle(handle: number): boolean { + if (this.isFallback()) { + const index = this.ref.handles.indexOf(handle); + if (index !== -1) { + this.ref.handles.splice(index, 1); + if (handle === this.ref.active) { + this.ref.active = this.ref.handles[0] || null; + } + return true; + } + return false; + } + + if (this.isLeaf() && this.ref.handle === handle) { + this.ref.handle = null; + return true; + } + + if (this.isBranch()) { + for (let index = 0; index < this.ref.children.length; index++) { + const child = NodeImpl.from(this.ref.children[index]!); + if (child.removeHandle(handle)) { + if (child.isTemporal() && child.isEmpty() && (child.isLeaf() || child.isStack())) { + this.ref.children.splice(index, 1); + } + return true; + } + } + } + + return false; + } + + mutateToStacked(): NodeImpl { + if (this.isLeaf()) { + let ref = this.ref as any; + ref.type = NodeType.Fallback; + ref.subtype = NodeSubtype.Temporal; + ref.handles = []; + ref.active = null; + + if (this.ref.handle) { + ref.handles.push(this.ref.handle); + ref.active = this.ref.handle; + } + + delete ref.handle; + } + + if (this.isBranch()) { + throw new Error('Cannot mutate branch to stacked'); + } + + return this as NodeImpl; + } + + mutateToBranch(type: NodeType.Horizontal | NodeType.Vertical): NodeImpl { + if (this.isBranch()) { + throw new Error('Cannot mutate branch to branch'); + } + + let copy = this.clone_ref(); + let ref = this.ref as any; + ref.type = type; + ref.subtype = NodeSubtype.Temporal; + ref.children = [copy]; + + delete ref.handle; + // TODO(eythan) check priorities for stacked + delete ref.handles; + delete ref.active; + + return this as NodeImpl; + } + + concreteReservation(hwnd: HWND, reservation: Reservation, activeHandle: number): boolean { + console.trace(`Reserving ${reservation} for ${hwnd} on ${activeHandle}`); + + const found = this.getNodeContaining(activeHandle); + if (!found) { + console.error('Could not find node containing handle', activeHandle); + return false; + } + + const node = NodeImpl.from(found); + + switch (reservation) { + case Reservation.Stack: { + if (node.isFallback()) { + node.ref.handles.push(hwnd); + } + if (node.isLeaf()) { + const mutated = node.mutateToStacked(); + mutated.ref.handles.push(hwnd); + } + return true; + } + case Reservation.Left: { + const mutated = node.mutateToBranch(NodeType.Horizontal); + mutated.ref.children.unshift(NodeImpl.newLeaf(hwnd, mutated.ref.children[0]!.priority)); + return true; + } + case Reservation.Right: { + const mutated = node.mutateToBranch(NodeType.Horizontal); + mutated.ref.children.push(NodeImpl.newLeaf(hwnd, mutated.ref.children[0]!.priority)); + return true; + } + case Reservation.Top: { + const mutated = node.mutateToBranch(NodeType.Vertical); + mutated.ref.children.unshift(NodeImpl.newLeaf(hwnd, mutated.ref.children[0]!.priority)); + return true; + } + case Reservation.Bottom: { + const mutated = node.mutateToBranch(NodeType.Vertical); + mutated.ref.children.push(NodeImpl.newLeaf(hwnd, mutated.ref.children[0]!.priority)); + return true; + } + default: + console.error(`Unknown reservation ${reservation}`); + return false; + } + } + + getNodeContaining(searched: HWND): LeafNode | FallbackNode | null { + if (this.isLeaf()) { + return this.ref.handle === searched ? this.ref : null; + } + + if (this.isFallback()) { + return this.ref.handles.includes(searched) ? this.ref : null; + } + + if (this.isBranch()) { + for (const child of this.ref.children) { + const result = NodeImpl.from(child).getNodeContaining(searched); + if (result) { + return result; + } + } + return null; + } + + this.unreachable(); + } + + trace(to: Node, result: Node[] = []): Node[] { + if (this.isLeaf() && this.ref === to) { + result.push(this.ref); + } + + if (this.isFallback() && this.ref === to) { + result.push(this.ref); + } + + if (this.isBranch()) { + for (const child of this.ref.children) { + const traced = NodeImpl.from(child).trace(to); + if (traced.length) { + result.push(this.ref, ...traced); + } + } + } + + return result; + } + + resetGrowFactor() { + this.ref.growFactor = 1; + if (this.isBranch()) { + for (const child of this.ref.children) { + NodeImpl.from(child).resetGrowFactor(); + } + } + } + + reIndexingGrowFactor() { + if (this.isBranch()) { + const noEmptyChildren = this.ref.children.filter((child) => !NodeImpl.from(child).isEmpty()); + + const min = noEmptyChildren.reduce((acc, child) => Math.min(acc, child.growFactor), Infinity); + const scaleFactor = 1 / min; + + noEmptyChildren.forEach((child) => { + child.growFactor = Number((child.growFactor * scaleFactor).toFixed(2)); + }); + + for (const child of this.ref.children) { + NodeImpl.from(child).reIndexingGrowFactor(); + } + } + } + + updateGrowFactor(handle: HWND, axis: 'x' | 'y', action: Sizing) { + const result = this.getNodeContaining(handle); + if (!result) { + console.error('Could not find node containing handle', handle); + return; + } + + const trace = this.trace(result); + + const idx = trace.findLastIndex((_node) => { + const node = NodeImpl.from(_node); + if (!node.isBranch()) { + return false; + } + + if (node.ref.children.filter((child) => !NodeImpl.from(child).isEmpty()).length < 2) { + return false; + } + + return axis === 'x' + ? node.ref.type === NodeType.Horizontal + : node.ref.type === NodeType.Vertical; + }); + + if (idx === -1) { + console.error('Can\'t resize root'); + return; + } + + const parent = trace[idx] as BranchNode; + const nodeToResize = trace[idx + 1]!; + + const noEmptyChildren = parent.children.filter((child) => !NodeImpl.from(child).isEmpty()); + + const total = noEmptyChildren.reduce((acc, child) => acc + child.growFactor, 0); + const delta = 0.1; + + nodeToResize.growFactor = + action === Sizing.Increase + ? nodeToResize.growFactor + total * delta + : nodeToResize.growFactor - total * delta; + + this.reIndexingGrowFactor(); + } + + getLeafByPriority(): LeafNode | FallbackNode | StackNode | null { + if (this.isLeaf()) { + return this.ref.handle ? this.ref : null; + } + + if (this.isFallback() || this.isStack()) { + return this.ref.active ? this.ref : null; + } + + if (this.isBranch()) { + const sorted = [...this.ref.children].sort((a, b) => a.priority - b.priority); + for (const child of sorted) { + const node = NodeImpl.from(child); + const result = node.getLeafByPriority(); + if (result) { + return result; + } + } + } + + return null; + } + + getNodeAtSide(from: HWND, side: FocusAction): LeafNode | FallbackNode | StackNode | null { + const result = this.getNodeContaining(from); + if (!result) { + console.error('Could not find node containing handle', from); + return null; + } + + const trace = this.trace(result); + const axis = [FocusAction.Left, FocusAction.Right].includes(side) + ? NodeType.Horizontal + : NodeType.Vertical; + const after = [FocusAction.Right, FocusAction.Down].includes(side); + + let lastAncestor: Node = trace.at(-1)!; + for (const node of trace.reverse()) { + if (node.type != axis) { + lastAncestor = node; + continue; + } + + let idx = node.children.indexOf(lastAncestor); + if (idx === -1) { + console.error('Error in Trace algorithm'); + return null; + } + idx = after ? idx + 1 : idx - 1; + if (idx >= 0 && idx < node.children.length) { + let next = NodeImpl.from(node.children[idx]!); + return next.getLeafByPriority(); + } + } + + return null; + } +} diff --git a/src/apps/seelen_wm/modules/layout/domain.ts b/src/apps/seelen_wm/modules/layout/domain.ts index b6fad41b..161e2d68 100644 --- a/src/apps/seelen_wm/modules/layout/domain.ts +++ b/src/apps/seelen_wm/modules/layout/domain.ts @@ -1,20 +1,20 @@ -import { FallbackNode, HorizontalBranchNode, LeafNode, StackNode, VerticalBranchNode } from '../../../shared/schemas/Layout'; - -export enum Reservation { - Left = 'Left', - Right = 'Right', - Top = 'Top', - Bottom = 'Bottom', - Stack = 'Stack', - Float = 'Float', -} - -export enum Sizing { - Increase = 'Increase', - Decrease = 'Decrease', -} - -export type BranchNode = HorizontalBranchNode | VerticalBranchNode; -export type Node = LeafNode | FallbackNode | BranchNode | StackNode; - -export const MAX_ALLOWED_ELEMENTS_PER_ROW = 10; +import { FallbackNode, HorizontalBranchNode, LeafNode, StackNode, VerticalBranchNode } from '../../../shared/schemas/Layout'; + +export enum Reservation { + Left = 'Left', + Right = 'Right', + Top = 'Top', + Bottom = 'Bottom', + Stack = 'Stack', + Float = 'Float', +} + +export enum Sizing { + Increase = 'Increase', + Decrease = 'Decrease', +} + +export type BranchNode = HorizontalBranchNode | VerticalBranchNode; +export type Node = LeafNode | FallbackNode | BranchNode | StackNode; + +export const MAX_ALLOWED_ELEMENTS_PER_ROW = 10; diff --git a/src/apps/seelen_wm/modules/layout/infra/containers/fallback.tsx b/src/apps/seelen_wm/modules/layout/infra/containers/fallback.tsx index e20b9bf8..2d1a9190 100644 --- a/src/apps/seelen_wm/modules/layout/infra/containers/fallback.tsx +++ b/src/apps/seelen_wm/modules/layout/infra/containers/fallback.tsx @@ -1,36 +1,36 @@ -import { FallbackNode } from '../../../../../shared/schemas/Layout'; -import { cx } from '../../../../../shared/styles'; -import { LeafContainer } from './leaf'; -import { useSelector } from 'react-redux'; - -import { Selectors } from '../../../shared/store/app'; - -interface Props { - node: FallbackNode; -} - -export function FallbackContainer({ node }: Props) { - const { border } = useSelector(Selectors.settings); - - return ( -
- {node.handles.length > 1 && ( -
- {node.handles.map((handle) => ( -
- {handle} -
- ))} -
- )} - {node.active && } -
- ); -} +import { FallbackNode } from '../../../../../shared/schemas/Layout'; +import { cx } from '../../../../../shared/styles'; +import { LeafContainer } from './leaf'; +import { useSelector } from 'react-redux'; + +import { Selectors } from '../../../shared/store/app'; + +interface Props { + node: FallbackNode; +} + +export function FallbackContainer({ node }: Props) { + const { border } = useSelector(Selectors.settings); + + return ( +
+ {node.handles.length > 1 && ( +
+ {node.handles.map((handle) => ( +
+ {handle} +
+ ))} +
+ )} + {node.active && } +
+ ); +} diff --git a/src/apps/seelen_wm/modules/layout/infra/containers/leaf.tsx b/src/apps/seelen_wm/modules/layout/infra/containers/leaf.tsx index 98397e77..02da20e5 100644 --- a/src/apps/seelen_wm/modules/layout/infra/containers/leaf.tsx +++ b/src/apps/seelen_wm/modules/layout/infra/containers/leaf.tsx @@ -1,58 +1,58 @@ -import { toPhysicalPixels } from '../../../../../shared'; -import { cx } from '../../../../../shared/styles'; -import { ReservedContainer } from './reserved'; -import { invoke } from '@tauri-apps/api/core'; -import { useCallback, useEffect, useRef } from 'react'; -import { useSelector } from 'react-redux'; - -import { Selectors } from '../../../shared/store/app'; - -interface Props { - hwnd: number; - growFactor?: number; -} - -export function LeafContainer({ hwnd, growFactor }: Props) { - const ref = useRef(null); - const reservation = useSelector(Selectors.reservation); - const activeWindow = useSelector(Selectors.activeWindow); - const borderSettings = useSelector(Selectors.settings.border); - - const updateSize = useCallback(() => { - if (!ref.current) { - return; - } - - const border = borderSettings.enabled ? borderSettings.width + borderSettings.offset : 0; - const domRect = ref.current.getBoundingClientRect(); - const top = domRect.top + window.screenY + border; - const left = domRect.left + window.screenX + border; - invoke('set_window_position', { - hwnd: hwnd, - rect: { - top: toPhysicalPixels(top), - left: toPhysicalPixels(left), - right: toPhysicalPixels(left + domRect.width - border * 2), - bottom: toPhysicalPixels(top + domRect.height - border * 2), - }, - }); - }, [hwnd]); - - useEffect(updateSize); - - const isFocused = activeWindow === hwnd; - return ( -
- {!!reservation && isFocused && } -
- ); -} +import { toPhysicalPixels } from '../../../../../shared'; +import { cx } from '../../../../../shared/styles'; +import { ReservedContainer } from './reserved'; +import { invoke } from '@tauri-apps/api/core'; +import { useCallback, useEffect, useRef } from 'react'; +import { useSelector } from 'react-redux'; + +import { Selectors } from '../../../shared/store/app'; + +interface Props { + hwnd: number; + growFactor?: number; +} + +export function LeafContainer({ hwnd, growFactor }: Props) { + const ref = useRef(null); + const reservation = useSelector(Selectors.reservation); + const activeWindow = useSelector(Selectors.activeWindow); + const borderSettings = useSelector(Selectors.settings.border); + + const updateSize = useCallback(() => { + if (!ref.current) { + return; + } + + const border = borderSettings.enabled ? borderSettings.width + borderSettings.offset : 0; + const domRect = ref.current.getBoundingClientRect(); + const top = domRect.top + window.screenY + border; + const left = domRect.left + window.screenX + border; + invoke('set_window_position', { + hwnd: hwnd, + rect: { + top: toPhysicalPixels(top), + left: toPhysicalPixels(left), + right: toPhysicalPixels(left + domRect.width - border * 2), + bottom: toPhysicalPixels(top + domRect.height - border * 2), + }, + }); + }, [hwnd]); + + useEffect(updateSize); + + const isFocused = activeWindow === hwnd; + return ( +
+ {!!reservation && isFocused && } +
+ ); +} diff --git a/src/apps/seelen_wm/modules/layout/infra/containers/reserved.tsx b/src/apps/seelen_wm/modules/layout/infra/containers/reserved.tsx index c6cf7279..0b3d1d3a 100644 --- a/src/apps/seelen_wm/modules/layout/infra/containers/reserved.tsx +++ b/src/apps/seelen_wm/modules/layout/infra/containers/reserved.tsx @@ -1,23 +1,23 @@ -import { cx } from '../../../../../shared/styles'; -import { useSelector } from 'react-redux'; - -import { Selectors } from '../../../shared/store/app'; - -import { Reservation } from '../../domain'; - -export function ReservedContainer({ reservation }: { reservation: Reservation }) { - const { floating } = useSelector(Selectors.settings); - return ( -
- ); -} +import { cx } from '../../../../../shared/styles'; +import { useSelector } from 'react-redux'; + +import { Selectors } from '../../../shared/store/app'; + +import { Reservation } from '../../domain'; + +export function ReservedContainer({ reservation }: { reservation: Reservation }) { + const { floating } = useSelector(Selectors.settings); + return ( +
+ ); +} diff --git a/src/apps/seelen_wm/modules/layout/infra/index.css b/src/apps/seelen_wm/modules/layout/infra/index.css index c0345dc3..28dd87a1 100644 --- a/src/apps/seelen_wm/modules/layout/infra/index.css +++ b/src/apps/seelen_wm/modules/layout/infra/index.css @@ -1,107 +1,107 @@ -#root { - > .wm-container { - width: 100%; - height: 100%; - } -} - -.wm-container { - position: relative; - flex-grow: 1; - flex-shrink: 1; - flex-basis: 0%; - gap: var(--config-containers-gap); - - &.wm-leaf { - border-radius: 10px; - - &.wm-leaf-focused { - z-index: 1; - } - } - - &.wm-stack { - display: flex; - flex-direction: column; - - .wm-stack-bar { - max-width: fit-content; - display: flex; - gap: var(--config-containers-gap); - border-radius: 8px; - width: 100%; - - .wm-stack-bar-item { - padding: 6px; - max-width: 100px; - overflow: hidden; - text-wrap: nowrap; - text-overflow: ellipsis; - } - } - } - - &.wm-horizontal { - display: flex; - } - - &.wm-vertical { - display: flex; - flex-direction: column; - } - - &.wm-reserved { - position: absolute; - left: 0; - top: 0; - width: 100%; - height: 100%; - border-radius: 8px; - opacity: 0.8; - - &:not(.wm-reserved-float) { - transition-property: width, height, left, top; - transition-duration: 100ms; - transition-timing-function: ease-in; - } - - &.wm-reserved-float { - position: fixed; - left: 50%; - top: 50%; - translate: -50% -50%; - opacity: 0; - animation: fromCenter 200ms ease-in forwards; - animation-delay: 10ms; - } - - &.wm-reserved-left { - width: 50%; - } - - &.wm-reserved-right { - left: 50%; - width: 50%; - } - - &.wm-reserved-top { - height: 50%; - } - - &.wm-reserved-bottom { - top: 50%; - height: 50%; - } - } -} - -@keyframes fromCenter { - 0% { - scale: 0; - opacity: 0; - } - 100% { - scale: 1; - opacity: 0.8; - } -} +#root { + > .wm-container { + width: 100%; + height: 100%; + } +} + +.wm-container { + position: relative; + flex-grow: 1; + flex-shrink: 1; + flex-basis: 0%; + gap: var(--config-containers-gap); + + &.wm-leaf { + border-radius: 10px; + + &.wm-leaf-focused { + z-index: 1; + } + } + + &.wm-stack { + display: flex; + flex-direction: column; + + .wm-stack-bar { + max-width: fit-content; + display: flex; + gap: var(--config-containers-gap); + border-radius: 8px; + width: 100%; + + .wm-stack-bar-item { + padding: 6px; + max-width: 100px; + overflow: hidden; + text-wrap: nowrap; + text-overflow: ellipsis; + } + } + } + + &.wm-horizontal { + display: flex; + } + + &.wm-vertical { + display: flex; + flex-direction: column; + } + + &.wm-reserved { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + border-radius: 8px; + opacity: 0.8; + + &:not(.wm-reserved-float) { + transition-property: width, height, left, top; + transition-duration: 100ms; + transition-timing-function: ease-in; + } + + &.wm-reserved-float { + position: fixed; + left: 50%; + top: 50%; + translate: -50% -50%; + opacity: 0; + animation: fromCenter 200ms ease-in forwards; + animation-delay: 10ms; + } + + &.wm-reserved-left { + width: 50%; + } + + &.wm-reserved-right { + left: 50%; + width: 50%; + } + + &.wm-reserved-top { + height: 50%; + } + + &.wm-reserved-bottom { + top: 50%; + height: 50%; + } + } +} + +@keyframes fromCenter { + 0% { + scale: 0; + opacity: 0; + } + 100% { + scale: 1; + opacity: 0.8; + } +} diff --git a/src/apps/seelen_wm/modules/layout/infra/index.tsx b/src/apps/seelen_wm/modules/layout/infra/index.tsx index 462ca949..ec17d711 100644 --- a/src/apps/seelen_wm/modules/layout/infra/index.tsx +++ b/src/apps/seelen_wm/modules/layout/infra/index.tsx @@ -1,55 +1,55 @@ -import { cx } from '../../../../shared/styles'; -import { FallbackContainer } from './containers/fallback'; -import { LeafContainer } from './containers/leaf'; -import { useSelector } from 'react-redux'; - -import { SelectCurrentWorkspace, Selectors } from '../../shared/store/app'; -import { NodeImpl } from '../app'; - -import { Node } from '../domain'; - -import './index.css'; - -export function Container({ container }: { container: Node }) { - const node = NodeImpl.from(container); - - if (node.isEmpty()) { - return null; - } - - if (node.isFallback()) { - return ; - } - - if (node.isLeaf() && node.inner.handle) { - return ; - } - - if (node.isBranch()) { - return ( -
- {node.inner.children.map((child, idx) => ( - - ))} -
- ); - } - - return null; -} - -export function Layout() { - const workspace = useSelector(SelectCurrentWorkspace); - const version = useSelector(Selectors.version); - - if (!workspace) { - return null; - } - - return ; -} +import { cx } from '../../../../shared/styles'; +import { FallbackContainer } from './containers/fallback'; +import { LeafContainer } from './containers/leaf'; +import { useSelector } from 'react-redux'; + +import { SelectCurrentWorkspace, Selectors } from '../../shared/store/app'; +import { NodeImpl } from '../app'; + +import { Node } from '../domain'; + +import './index.css'; + +export function Container({ container }: { container: Node }) { + const node = NodeImpl.from(container); + + if (node.isEmpty()) { + return null; + } + + if (node.isFallback()) { + return ; + } + + if (node.isLeaf() && node.inner.handle) { + return ; + } + + if (node.isBranch()) { + return ( +
+ {node.inner.children.map((child, idx) => ( + + ))} +
+ ); + } + + return null; +} + +export function Layout() { + const workspace = useSelector(SelectCurrentWorkspace); + const version = useSelector(Selectors.version); + + if (!workspace) { + return null; + } + + return ; +} diff --git a/src/apps/seelen_wm/modules/shared/store/app.ts b/src/apps/seelen_wm/modules/shared/store/app.ts index 95e29e85..bbe56223 100644 --- a/src/apps/seelen_wm/modules/shared/store/app.ts +++ b/src/apps/seelen_wm/modules/shared/store/app.ts @@ -1,199 +1,199 @@ -import { defaultLayout } from '../../../../../shared.interfaces'; -import { toPhysicalPixels } from '../../../../shared'; -import { parseAsCamel } from '../../../../shared/schemas'; -import { WindowManagerSchema } from '../../../../shared/schemas/WindowManager'; -import { StateBuilder } from '../../../../shared/StateBuilder'; -import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { invoke } from '@tauri-apps/api/core'; -import { cloneDeep } from 'lodash'; - -import { NodeImpl, reIndexContainer } from '../../layout/app'; - -import { Reservation, Sizing } from '../../layout/domain'; -import { AddWindowPayload, DesktopId, FocusAction, RootState } from './domain'; - -const initialState: RootState = { - version: 0, - availableLayouts: [], - workspaces: {}, - activeWorkspace: '' as DesktopId, - desktopByHandle: {}, - handlesByDesktop: {}, - activeWindow: 0, - lastManagedActivated: null, - reservation: null, - settings: parseAsCamel(WindowManagerSchema, {}), - colors: { - background: '#ffffff', - foreground: '#000000', - accent_darkest: '#000000', - accent_darker: '#000000', - accent_dark: '#000000', - accent: '#000000', - accent_light: '#000000', - accent_lighter: '#000000', - accent_lightest: '#000000', - complement: null, - }, -}; - -export const RootSlice = createSlice({ - name: 'root', - initialState, - reducers: { - ...StateBuilder.reducersFor(initialState), - addWindow: (state, action: PayloadAction) => { - const { desktop_id, hwnd, as_floating } = action.payload; - - state.desktopByHandle[hwnd] = desktop_id; - state.handlesByDesktop[desktop_id] ??= []; - - const handlesInDesktop = state.handlesByDesktop[desktop_id]!; - handlesInDesktop.push(hwnd); - - if (!state.workspaces[desktop_id]) { - state.workspaces[desktop_id] = { - name: `Workspace ${desktop_id}`, - layout: cloneDeep( - state.availableLayouts.find((l) => l.info.filename === state.settings.defaultLayout) || - defaultLayout, - ), - }; - } - - const workspace = state.workspaces[desktop_id]!; - const node = NodeImpl.from(workspace.layout.structure); - - let successfullyAdded = false; - - const setFloatingSize = () => { - const top = toPhysicalPixels(window.screen.height / 2 - state.settings.floating.height / 2); - const left = toPhysicalPixels(window.screen.width / 2 - state.settings.floating.width / 2); - invoke('set_window_position', { - hwnd, - rect: { - top, - left, - right: left + toPhysicalPixels(state.settings.floating.width), - bottom: top + toPhysicalPixels(state.settings.floating.height), - }, - }); - }; - - if (state.reservation) { - if (state.reservation === Reservation.Float) { - invoke('bounce_handle', { hwnd }); - setFloatingSize(); - successfullyAdded = true; - } else if (state.lastManagedActivated) { - successfullyAdded = node.concreteReservation( - hwnd, - state.reservation, - state.lastManagedActivated, - ); - } - } else if (as_floating) { - setFloatingSize(); - successfullyAdded = true; - } else { - successfullyAdded = node.addHandle(hwnd); - if (successfullyAdded) { - reIndexContainer(node.inner, handlesInDesktop); - } - } - - state.reservation = null; - - if (successfullyAdded) { - state.lastManagedActivated = hwnd; - state.activeWindow = hwnd; - } else { - invoke('bounce_handle', { hwnd }); - if (!workspace.layout.noFallbackBehavior) { - console.error( - 'Layout can\'t handle the window, FallbackNode and noFallbackBehavior are not defined in layout', - ); - } else if (workspace.layout.noFallbackBehavior === 'Float') { - setFloatingSize(); - } - } - }, - removeWindow: (state, action: PayloadAction) => { - const hwnd = action.payload; - - const desktopId = state.desktopByHandle[hwnd]; - if (!desktopId) { - return; - } - - delete state.desktopByHandle[hwnd]; - const handlesInDesktop = state.handlesByDesktop[desktopId] || []; - const idx = handlesInDesktop.indexOf(hwnd); - if (idx != -1) { - handlesInDesktop.splice(idx, 1); - } - - const workspace = state.workspaces[desktopId]; - if (workspace) { - const node = NodeImpl.from(workspace.layout.structure); - const wasRemoved = node.removeHandle(hwnd); - if (wasRemoved) { - reIndexContainer(node.inner, handlesInDesktop); - } - } - }, - forceUpdate(state) { - state.version += 1; - }, - setActiveWorkspace(state, action: PayloadAction) { - state.activeWorkspace = action.payload; - if (!state.workspaces[action.payload]) { - state.workspaces[action.payload] = { - name: `Workspace ${action.payload}`, - layout: cloneDeep( - state.availableLayouts.find((l) => l.info.filename === state.settings.defaultLayout) || - defaultLayout, - ), - }; - } - }, - updateSizing(state, action: PayloadAction<{ axis: 'x' | 'y'; sizing: Sizing }>) { - const { axis, sizing } = action.payload; - if (state.lastManagedActivated) { - const node = NodeImpl.from(state.workspaces[state.activeWorkspace]!.layout.structure); - node.updateGrowFactor(state.lastManagedActivated, axis, sizing); - } - }, - resetSizing(state) { - const node = NodeImpl.from(state.workspaces[state.activeWorkspace]!.layout.structure); - node.resetGrowFactor(); - }, - focus(state, action: PayloadAction) { - const { workspaces, activeWorkspace } = state; - const workspace = workspaces[activeWorkspace]; - if (!workspace) { - return console.error('No active workspace found.'); - } - - if (!state.lastManagedActivated) { - return console.error('No last managed window found.'); - } - - if (action.payload === FocusAction.Latest) { - invoke('request_focus', { hwnd: state.lastManagedActivated }); - return; - } - - const node = NodeImpl.from(workspace.layout.structure); - const next = node.getNodeAtSide(state.lastManagedActivated, action.payload); - if (next) { - const nextNode = NodeImpl.from(next); - invoke('request_focus', { hwnd: nextNode.currentHandle || 0 }); - } - }, - }, -}); - -export const RootActions = RootSlice.actions; -export const Selectors = StateBuilder.compositeSelector(initialState); -export const SelectCurrentWorkspace = (state: RootState) => state.workspaces[state.activeWorkspace]; +import { defaultLayout } from '../../../../../shared.interfaces'; +import { toPhysicalPixels } from '../../../../shared'; +import { parseAsCamel } from '../../../../shared/schemas'; +import { WindowManagerSchema } from '../../../../shared/schemas/WindowManager'; +import { StateBuilder } from '../../../../shared/StateBuilder'; +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; +import { invoke } from '@tauri-apps/api/core'; +import { cloneDeep } from 'lodash'; + +import { NodeImpl, reIndexContainer } from '../../layout/app'; + +import { Reservation, Sizing } from '../../layout/domain'; +import { AddWindowPayload, DesktopId, FocusAction, RootState } from './domain'; + +const initialState: RootState = { + version: 0, + availableLayouts: [], + workspaces: {}, + activeWorkspace: '' as DesktopId, + desktopByHandle: {}, + handlesByDesktop: {}, + activeWindow: 0, + lastManagedActivated: null, + reservation: null, + settings: parseAsCamel(WindowManagerSchema, {}), + colors: { + background: '#ffffff', + foreground: '#000000', + accent_darkest: '#000000', + accent_darker: '#000000', + accent_dark: '#000000', + accent: '#000000', + accent_light: '#000000', + accent_lighter: '#000000', + accent_lightest: '#000000', + complement: null, + }, +}; + +export const RootSlice = createSlice({ + name: 'root', + initialState, + reducers: { + ...StateBuilder.reducersFor(initialState), + addWindow: (state, action: PayloadAction) => { + const { desktop_id, hwnd, as_floating } = action.payload; + + state.desktopByHandle[hwnd] = desktop_id; + state.handlesByDesktop[desktop_id] ??= []; + + const handlesInDesktop = state.handlesByDesktop[desktop_id]!; + handlesInDesktop.push(hwnd); + + if (!state.workspaces[desktop_id]) { + state.workspaces[desktop_id] = { + name: `Workspace ${desktop_id}`, + layout: cloneDeep( + state.availableLayouts.find((l) => l.info.filename === state.settings.defaultLayout) || + defaultLayout, + ), + }; + } + + const workspace = state.workspaces[desktop_id]!; + const node = NodeImpl.from(workspace.layout.structure); + + let successfullyAdded = false; + + const setFloatingSize = () => { + const top = toPhysicalPixels(window.screen.height / 2 - state.settings.floating.height / 2); + const left = toPhysicalPixels(window.screen.width / 2 - state.settings.floating.width / 2); + invoke('set_window_position', { + hwnd, + rect: { + top, + left, + right: left + toPhysicalPixels(state.settings.floating.width), + bottom: top + toPhysicalPixels(state.settings.floating.height), + }, + }); + }; + + if (state.reservation) { + if (state.reservation === Reservation.Float) { + invoke('bounce_handle', { hwnd }); + setFloatingSize(); + successfullyAdded = true; + } else if (state.lastManagedActivated) { + successfullyAdded = node.concreteReservation( + hwnd, + state.reservation, + state.lastManagedActivated, + ); + } + } else if (as_floating) { + setFloatingSize(); + successfullyAdded = true; + } else { + successfullyAdded = node.addHandle(hwnd); + if (successfullyAdded) { + reIndexContainer(node.inner, handlesInDesktop); + } + } + + state.reservation = null; + + if (successfullyAdded) { + state.lastManagedActivated = hwnd; + state.activeWindow = hwnd; + } else { + invoke('bounce_handle', { hwnd }); + if (!workspace.layout.noFallbackBehavior) { + console.error( + 'Layout can\'t handle the window, FallbackNode and noFallbackBehavior are not defined in layout', + ); + } else if (workspace.layout.noFallbackBehavior === 'Float') { + setFloatingSize(); + } + } + }, + removeWindow: (state, action: PayloadAction) => { + const hwnd = action.payload; + + const desktopId = state.desktopByHandle[hwnd]; + if (!desktopId) { + return; + } + + delete state.desktopByHandle[hwnd]; + const handlesInDesktop = state.handlesByDesktop[desktopId] || []; + const idx = handlesInDesktop.indexOf(hwnd); + if (idx != -1) { + handlesInDesktop.splice(idx, 1); + } + + const workspace = state.workspaces[desktopId]; + if (workspace) { + const node = NodeImpl.from(workspace.layout.structure); + const wasRemoved = node.removeHandle(hwnd); + if (wasRemoved) { + reIndexContainer(node.inner, handlesInDesktop); + } + } + }, + forceUpdate(state) { + state.version += 1; + }, + setActiveWorkspace(state, action: PayloadAction) { + state.activeWorkspace = action.payload; + if (!state.workspaces[action.payload]) { + state.workspaces[action.payload] = { + name: `Workspace ${action.payload}`, + layout: cloneDeep( + state.availableLayouts.find((l) => l.info.filename === state.settings.defaultLayout) || + defaultLayout, + ), + }; + } + }, + updateSizing(state, action: PayloadAction<{ axis: 'x' | 'y'; sizing: Sizing }>) { + const { axis, sizing } = action.payload; + if (state.lastManagedActivated) { + const node = NodeImpl.from(state.workspaces[state.activeWorkspace]!.layout.structure); + node.updateGrowFactor(state.lastManagedActivated, axis, sizing); + } + }, + resetSizing(state) { + const node = NodeImpl.from(state.workspaces[state.activeWorkspace]!.layout.structure); + node.resetGrowFactor(); + }, + focus(state, action: PayloadAction) { + const { workspaces, activeWorkspace } = state; + const workspace = workspaces[activeWorkspace]; + if (!workspace) { + return console.error('No active workspace found.'); + } + + if (!state.lastManagedActivated) { + return console.error('No last managed window found.'); + } + + if (action.payload === FocusAction.Latest) { + invoke('request_focus', { hwnd: state.lastManagedActivated }); + return; + } + + const node = NodeImpl.from(workspace.layout.structure); + const next = node.getNodeAtSide(state.lastManagedActivated, action.payload); + if (next) { + const nextNode = NodeImpl.from(next); + invoke('request_focus', { hwnd: nextNode.currentHandle || 0 }); + } + }, + }, +}); + +export const RootActions = RootSlice.actions; +export const Selectors = StateBuilder.compositeSelector(initialState); +export const SelectCurrentWorkspace = (state: RootState) => state.workspaces[state.activeWorkspace]; diff --git a/src/apps/seelen_wm/modules/shared/store/domain.ts b/src/apps/seelen_wm/modules/shared/store/domain.ts index 3bd01200..5515872a 100644 --- a/src/apps/seelen_wm/modules/shared/store/domain.ts +++ b/src/apps/seelen_wm/modules/shared/store/domain.ts @@ -1,57 +1,57 @@ -import { IRootState } from '../../../../../shared.interfaces'; -import { Layout } from '../../../../shared/schemas/Layout'; -import { WindowManager } from '../../../../shared/schemas/WindowManager'; -import { SoftOpaque } from 'readable-types'; - -import { Reservation } from '../../layout/domain'; -import { HWND } from '../utils/domain'; - -interface Workspace { - name: string; - layout: Layout; -} - -export type DesktopId = SoftOpaque; - -export enum FocusAction { - Left = 'Left', - Right = 'Right', - Up = 'Up', - Down = 'Down', - Latest = 'Latest', -} - -export interface UIColors { - background: string; - foreground: string; - accent_darkest: string; - accent_darker: string; - accent_dark: string; - accent: string; - accent_light: string; - accent_lighter: string; - accent_lightest: string; - complement: string | null; -} - -export interface RootState extends IRootState { - colors: UIColors; - availableLayouts: Layout[]; - workspaces: Record; - activeWorkspace: DesktopId; - /** current focused window handle */ - activeWindow: HWND; - /** last managed window activated */ - lastManagedActivated: HWND | null; - reservation: Reservation | null; - handlesByDesktop: Record; - desktopByHandle: Record; - /** Prop to listen for app forced updates */ - version: number; -} - -export interface AddWindowPayload { - hwnd: HWND; - desktop_id: DesktopId; - as_floating: boolean; -} +import { IRootState } from '../../../../../shared.interfaces'; +import { Layout } from '../../../../shared/schemas/Layout'; +import { WindowManager } from '../../../../shared/schemas/WindowManager'; +import { SoftOpaque } from 'readable-types'; + +import { Reservation } from '../../layout/domain'; +import { HWND } from '../utils/domain'; + +interface Workspace { + name: string; + layout: Layout; +} + +export type DesktopId = SoftOpaque; + +export enum FocusAction { + Left = 'Left', + Right = 'Right', + Up = 'Up', + Down = 'Down', + Latest = 'Latest', +} + +export interface UIColors { + background: string; + foreground: string; + accent_darkest: string; + accent_darker: string; + accent_dark: string; + accent: string; + accent_light: string; + accent_lighter: string; + accent_lightest: string; + complement: string | null; +} + +export interface RootState extends IRootState { + colors: UIColors; + availableLayouts: Layout[]; + workspaces: Record; + activeWorkspace: DesktopId; + /** current focused window handle */ + activeWindow: HWND; + /** last managed window activated */ + lastManagedActivated: HWND | null; + reservation: Reservation | null; + handlesByDesktop: Record; + desktopByHandle: Record; + /** Prop to listen for app forced updates */ + version: number; +} + +export interface AddWindowPayload { + hwnd: HWND; + desktop_id: DesktopId; + as_floating: boolean; +} diff --git a/src/apps/seelen_wm/modules/shared/store/infra.ts b/src/apps/seelen_wm/modules/shared/store/infra.ts index 015a043d..53ea1e28 100644 --- a/src/apps/seelen_wm/modules/shared/store/infra.ts +++ b/src/apps/seelen_wm/modules/shared/store/infra.ts @@ -1,119 +1,119 @@ -import { UserSettingsLoader } from '../../../../settings/modules/shared/store/storeApi'; -import { loadThemeCSS, setColorsAsCssVariables } from '../../../../shared'; -import { FileChange } from '../../../../shared/events'; -import { WindowManager } from '../../../../shared/schemas/WindowManager'; -import { configureStore } from '@reduxjs/toolkit'; -import { listen as listenGlobal } from '@tauri-apps/api/event'; -import { debounce } from 'lodash'; - -import { RootActions, RootSlice } from './app'; - -import { Reservation, Sizing } from '../../layout/domain'; -import { AddWindowPayload, DesktopId, FocusAction, UIColors } from './domain'; - -export const store = configureStore({ - reducer: RootSlice.reducer, - devTools: true, -}); - -export async function loadStore() { - const userSettings = await new UserSettingsLoader().withLayouts().load(); - const settings = userSettings.jsonSettings.windowManager; - store.dispatch(RootActions.setAvailableLayouts(userSettings.layouts)); - store.dispatch(RootActions.setSettings(settings)); - loadSettingsCSS(settings); - loadThemeCSS(userSettings); -} - -export async function registerStoreEvents() { - await listenGlobal( - FileChange.Settings, - debounce(async () => { - await loadStore(); - }, 100), - ); - - await listenGlobal('add-window', (event) => { - store.dispatch(RootActions.addWindow(event.payload)); - }); - - await listenGlobal('remove-window', (event) => { - store.dispatch(RootActions.removeWindow(event.payload)); - }); - - await listenGlobal('force-retiling', () => { - store.dispatch(RootActions.forceUpdate()); - }); - - await listenGlobal('set-active-workspace', (event) => { - store.dispatch(RootActions.setActiveWorkspace(event.payload)); - }); - - await listenGlobal('set-active-window', (event) => { - store.dispatch(RootActions.setActiveWindow(event.payload)); - if (event.payload != 0) { - store.dispatch(RootActions.setLastManagedActivated(event.payload)); - } - }); - - await listenGlobal('set-reservation', (event) => { - store.dispatch(RootActions.setReservation(event.payload)); - }); - - await listenGlobal('update-width', (event) => { - store.dispatch(RootActions.updateSizing({ axis: 'x', sizing: event.payload })); - }); - - await listenGlobal('update-height', (event) => { - store.dispatch(RootActions.updateSizing({ axis: 'y', sizing: event.payload })); - }); - - await listenGlobal('reset-workspace-size', () => { - store.dispatch(RootActions.resetSizing()); - }); - - await listenGlobal('focus', (event) => { - store.dispatch(RootActions.focus(event.payload)); - }); - - await listenGlobal('update-window', (event) => { - store.dispatch(RootActions.removeWindow(event.payload.hwnd)); - store.dispatch(RootActions.addWindow(event.payload)); - }); - - await listenGlobal('colors', (event) => { - setColorsAsCssVariables(event.payload); - store.dispatch(RootActions.setColors(event.payload)); - }); - - await listenGlobal( - FileChange.Themes, - debounce(async () => { - const userSettings = await new UserSettingsLoader().load(); - loadThemeCSS(userSettings); - }, 100), - ); - - await listenGlobal( - FileChange.Placeholders, - debounce(async () => { - const userSettings = await new UserSettingsLoader().withLayouts().load(); - store.dispatch(RootActions.setAvailableLayouts(userSettings.layouts)); - }, 100), - ); -} - -function loadSettingsCSS(settings: WindowManager) { - const styles = document.documentElement.style; - - styles.setProperty('--config-padding', `${settings.workspacePadding}px`); - styles.setProperty('--config-containers-gap', `${settings.workspaceGap}px`); - - styles.setProperty('--config-margin-top', `${settings.globalWorkAreaOffset.top}px`); - styles.setProperty('--config-margin-left', `${settings.globalWorkAreaOffset.left}px`); - styles.setProperty('--config-margin-right', `${settings.globalWorkAreaOffset.right}px`); - styles.setProperty('--config-margin-bottom', `${settings.globalWorkAreaOffset.bottom}px`); - - styles.setProperty('--config-border-offset', `${settings.border.offset}px`); - styles.setProperty('--config-border-width', `${settings.border.width}px`); -} +import { UserSettingsLoader } from '../../../../settings/modules/shared/store/storeApi'; +import { loadThemeCSS, setColorsAsCssVariables } from '../../../../shared'; +import { FileChange } from '../../../../shared/events'; +import { WindowManager } from '../../../../shared/schemas/WindowManager'; +import { configureStore } from '@reduxjs/toolkit'; +import { listen as listenGlobal } from '@tauri-apps/api/event'; +import { debounce } from 'lodash'; + +import { RootActions, RootSlice } from './app'; + +import { Reservation, Sizing } from '../../layout/domain'; +import { AddWindowPayload, DesktopId, FocusAction, UIColors } from './domain'; + +export const store = configureStore({ + reducer: RootSlice.reducer, + devTools: true, +}); + +export async function loadStore() { + const userSettings = await new UserSettingsLoader().withLayouts().load(); + const settings = userSettings.jsonSettings.windowManager; + store.dispatch(RootActions.setAvailableLayouts(userSettings.layouts)); + store.dispatch(RootActions.setSettings(settings)); + loadSettingsCSS(settings); + loadThemeCSS(userSettings); +} + +export async function registerStoreEvents() { + await listenGlobal( + FileChange.Settings, + debounce(async () => { + await loadStore(); + }, 100), + ); + + await listenGlobal('add-window', (event) => { + store.dispatch(RootActions.addWindow(event.payload)); + }); + + await listenGlobal('remove-window', (event) => { + store.dispatch(RootActions.removeWindow(event.payload)); + }); + + await listenGlobal('force-retiling', () => { + store.dispatch(RootActions.forceUpdate()); + }); + + await listenGlobal('set-active-workspace', (event) => { + store.dispatch(RootActions.setActiveWorkspace(event.payload)); + }); + + await listenGlobal('set-active-window', (event) => { + store.dispatch(RootActions.setActiveWindow(event.payload)); + if (event.payload != 0) { + store.dispatch(RootActions.setLastManagedActivated(event.payload)); + } + }); + + await listenGlobal('set-reservation', (event) => { + store.dispatch(RootActions.setReservation(event.payload)); + }); + + await listenGlobal('update-width', (event) => { + store.dispatch(RootActions.updateSizing({ axis: 'x', sizing: event.payload })); + }); + + await listenGlobal('update-height', (event) => { + store.dispatch(RootActions.updateSizing({ axis: 'y', sizing: event.payload })); + }); + + await listenGlobal('reset-workspace-size', () => { + store.dispatch(RootActions.resetSizing()); + }); + + await listenGlobal('focus', (event) => { + store.dispatch(RootActions.focus(event.payload)); + }); + + await listenGlobal('update-window', (event) => { + store.dispatch(RootActions.removeWindow(event.payload.hwnd)); + store.dispatch(RootActions.addWindow(event.payload)); + }); + + await listenGlobal('colors', (event) => { + setColorsAsCssVariables(event.payload); + store.dispatch(RootActions.setColors(event.payload)); + }); + + await listenGlobal( + FileChange.Themes, + debounce(async () => { + const userSettings = await new UserSettingsLoader().load(); + loadThemeCSS(userSettings); + }, 100), + ); + + await listenGlobal( + FileChange.Placeholders, + debounce(async () => { + const userSettings = await new UserSettingsLoader().withLayouts().load(); + store.dispatch(RootActions.setAvailableLayouts(userSettings.layouts)); + }, 100), + ); +} + +function loadSettingsCSS(settings: WindowManager) { + const styles = document.documentElement.style; + + styles.setProperty('--config-padding', `${settings.workspacePadding}px`); + styles.setProperty('--config-containers-gap', `${settings.workspaceGap}px`); + + styles.setProperty('--config-margin-top', `${settings.globalWorkAreaOffset.top}px`); + styles.setProperty('--config-margin-left', `${settings.globalWorkAreaOffset.left}px`); + styles.setProperty('--config-margin-right', `${settings.globalWorkAreaOffset.right}px`); + styles.setProperty('--config-margin-bottom', `${settings.globalWorkAreaOffset.bottom}px`); + + styles.setProperty('--config-border-offset', `${settings.border.offset}px`); + styles.setProperty('--config-border-width', `${settings.border.width}px`); +} diff --git a/src/apps/seelen_wm/styles/colors.css b/src/apps/seelen_wm/styles/colors.css index ec8ed844..f12ab260 100644 --- a/src/apps/seelen_wm/styles/colors.css +++ b/src/apps/seelen_wm/styles/colors.css @@ -1,599 +1,599 @@ -:root { - /* Persisted colors variables (not changed on dark mode) */ - --color-persist-white: #ffffff; - --color-persist-gray-50: #fdfdfd; - --color-persist-gray-100: #f8f8f8; - --color-persist-gray-200: #e6e6e6; - --color-persist-gray-300: #d5d5d5; - --color-persist-gray-400: #b1b1b1; - --color-persist-gray-500: #909090; - --color-persist-gray-600: #6d6d6d; - --color-persist-gray-700: #464646; - --color-persist-gray-800: #222222; - --color-persist-gray-900: #151515; - --color-persist-black: #000000; - - --color-persist-blue-100: #e0f2ff; - --color-persist-blue-200: #cae8ff; - --color-persist-blue-300: #b5deff; - --color-persist-blue-400: #96cefd; - --color-persist-blue-500: #78bbfa; - --color-persist-blue-600: #59a7f6; - --color-persist-blue-700: #3892f3; - --color-persist-blue-800: #147af3; - --color-persist-blue-900: #0265dc; - --color-persist-blue-1000: #0054b6; - --color-persist-blue-1100: #004491; - --color-persist-blue-1200: #003571; - --color-persist-blue-1300: #002754; - - --color-persist-green-100: #cef8e0; - --color-persist-green-200: #adf4ce; - --color-persist-green-300: #89ecbc; - --color-persist-green-400: #67dea8; - --color-persist-green-500: #49cc93; - --color-persist-green-600: #2fb880; - --color-persist-green-700: #15a46e; - --color-persist-green-800: #008f5d; - --color-persist-green-900: #007a4d; - --color-persist-green-1000: #00653e; - --color-persist-green-1100: #005132; - --color-persist-green-1200: #053f27; - --color-persist-green-1300: #0a2e1d; - - --color-persist-orange-100: #ffeccc; - --color-persist-orange-200: #ffdfad; - --color-persist-orange-300: #fdd291; - --color-persist-orange-400: #ffbb63; - --color-persist-orange-500: #ffa037; - --color-persist-orange-600: #f68511; - --color-persist-orange-700: #e46f00; - --color-persist-orange-800: #cb5d00; - --color-persist-orange-900: #b14c00; - --color-persist-orange-1000: #953d00; - --color-persist-orange-1100: #7a2f00; - --color-persist-orange-1200: #612300; - --color-persist-orange-1300: #491901; - - --color-persist-red-100: #ffebe7; - --color-persist-red-200: #ffddd6; - --color-persist-red-300: #ffcdc3; - --color-persist-red-400: #ffb7a9; - --color-persist-red-500: #ff9b88; - --color-persist-red-600: #ff7c65; - --color-persist-red-700: #f75c46; - --color-persist-red-800: #ea3829; - --color-persist-red-900: #d31510; - --color-persist-red-1000: #b40000; - --color-persist-red-1100: #930000; - --color-persist-red-1200: #740000; - --color-persist-red-1300: #590000; - - --color-persist-celery-100: #cdfcbf; - --color-persist-celery-200: #aef69d; - --color-persist-celery-300: #96ee85; - --color-persist-celery-400: #72e06a; - --color-persist-celery-500: #4ecf50; - --color-persist-celery-600: #27bb36; - --color-persist-celery-700: #07a721; - --color-persist-celery-800: #009112; - --color-persist-celery-900: #007c0f; - --color-persist-celery-1000: #00670f; - --color-persist-celery-1100: #00530d; - --color-persist-celery-1200: #00400a; - --color-persist-celery-1300: #003007; - - --color-persist-chartreuse-100: #dbfc6e; - --color-persist-chartreuse-200: #cbf443; - --color-persist-chartreuse-300: #bce92a; - --color-persist-chartreuse-400: #aad816; - --color-persist-chartreuse-500: #98c50a; - --color-persist-chartreuse-600: #87b103; - --color-persist-chartreuse-700: #769c00; - --color-persist-chartreuse-800: #678800; - --color-persist-chartreuse-900: #577400; - --color-persist-chartreuse-1000: #486000; - --color-persist-chartreuse-1100: #3a4d00; - --color-persist-chartreuse-1200: #2c3b00; - --color-persist-chartreuse-1300: #212c00; - - --color-persist-cyan-100: #c5f8ff; - --color-persist-cyan-200: #a4f0ff; - --color-persist-cyan-300: #88e7fa; - --color-persist-cyan-400: #60d8f3; - --color-persist-cyan-500: #33c5e8; - --color-persist-cyan-600: #12b0da; - --color-persist-cyan-700: #019cc8; - --color-persist-cyan-800: #0086b4; - --color-persist-cyan-900: #00719f; - --color-persist-cyan-1000: #005d89; - --color-persist-cyan-1100: #004a73; - --color-persist-cyan-1200: #00395d; - --color-persist-cyan-1300: #002a46; - - --color-persist-fuchsia-100: #ffe9fc; - --color-persist-fuchsia-200: #ffdafa; - --color-persist-fuchsia-300: #fec7f8; - --color-persist-fuchsia-400: #fbaef6; - --color-persist-fuchsia-500: #f592f3; - --color-persist-fuchsia-600: #ed74ed; - --color-persist-fuchsia-700: #e055e2; - --color-persist-fuchsia-800: #cd3ace; - --color-persist-fuchsia-900: #b622b7; - --color-persist-fuchsia-1000: #9d039e; - --color-persist-fuchsia-1100: #800081; - --color-persist-fuchsia-1200: #640664; - --color-persist-fuchsia-1300: #470e46; - - --color-persist-indigo-100: #edeeff; - --color-persist-indigo-200: #e0e2ff; - --color-persist-indigo-300: #d3d5ff; - --color-persist-indigo-400: #c1c4ff; - --color-persist-indigo-500: #acafff; - --color-persist-indigo-600: #9599ff; - --color-persist-indigo-700: #7e84fc; - --color-persist-indigo-800: #686df4; - --color-persist-indigo-900: #5258e4; - --color-persist-indigo-1000: #4046ca; - --color-persist-indigo-1100: #3236a8; - --color-persist-indigo-1200: #262986; - --color-persist-indigo-1300: #1b1e64; - - --color-persist-magenta-100: #ffeaf1; - --color-persist-magenta-200: #ffdce8; - --color-persist-magenta-300: #ffcadd; - --color-persist-magenta-400: #ffb2ce; - --color-persist-magenta-500: #ff95bd; - --color-persist-magenta-600: #fa77aa; - --color-persist-magenta-700: #ef5a98; - --color-persist-magenta-800: #de3d82; - --color-persist-magenta-900: #c82269; - --color-persist-magenta-1000: #ad0955; - --color-persist-magenta-1100: #8e0045; - --color-persist-magenta-1200: #700037; - --color-persist-magenta-1300: #54032a; - - --color-persist-purple-100: #f6ebff; - --color-persist-purple-200: #eeddff; - --color-persist-purple-300: #e6d0ff; - --color-persist-purple-400: #dbbbfe; - --color-persist-purple-500: #cca4fd; - --color-persist-purple-600: #bd8bfc; - --color-persist-purple-700: #ae72f9; - --color-persist-purple-800: #9d57f4; - --color-persist-purple-900: #893de7; - --color-persist-purple-1000: #7326d3; - --color-persist-purple-1100: #5d13b7; - --color-persist-purple-1200: #470c94; - --color-persist-purple-1300: #33106a; - - --color-persist-seafoam-100: #cef7f3; - --color-persist-seafoam-200: #aaf1ea; - --color-persist-seafoam-300: #8ce9e2; - --color-persist-seafoam-400: #65dad2; - --color-persist-seafoam-500: #3fc9c1; - --color-persist-seafoam-600: #0fb5ae; - --color-persist-seafoam-700: #00a19a; - --color-persist-seafoam-800: #008c87; - --color-persist-seafoam-900: #007772; - --color-persist-seafoam-1000: #00635f; - --color-persist-seafoam-1100: #0c4f4c; - --color-persist-seafoam-1200: #123c3a; - --color-persist-seafoam-1300: #122c2b; - - --color-persist-yellow-100: #fbf198; - --color-persist-yellow-200: #f8e750; - --color-persist-yellow-300: #f8d904; - --color-persist-yellow-400: #e8c600; - --color-persist-yellow-500: #d7b300; - --color-persist-yellow-600: #c49f00; - --color-persist-yellow-700: #b08c00; - --color-persist-yellow-800: #9b7800; - --color-persist-yellow-900: #856600; - --color-persist-yellow-1000: #705300; - --color-persist-yellow-1100: #5b4300; - --color-persist-yellow-1200: #483300; - --color-persist-yellow-1300: #362500; -} - -@media (prefers-color-scheme: dark) { - :root { - --color-white: #000000; - - --color-gray-50: #151515; - --color-gray-100: #222222; - --color-gray-200: #464646; - --color-gray-300: #6d6d6d; - --color-gray-400: #909090; - --color-gray-500: #b1b1b1; - --color-gray-600: #d5d5d5; - --color-gray-700: #e6e6e6; - --color-gray-800: #f8f8f8; - --color-gray-900: #fdfdfd; - - --color-black: #ffffff; - - --color-blue-100: #003877; - --color-blue-200: #00418a; - --color-blue-300: #004da3; - --color-blue-400: #0059c2; - --color-blue-500: #0367e0; - --color-blue-600: #1379f3; - --color-blue-700: #348ff4; - --color-blue-800: #54a3f6; - --color-blue-900: #72b7f9; - --color-blue-1000: #8fcafc; - --color-blue-1100: #aedbfe; - --color-blue-1200: #cce9ff; - --color-blue-1300: #e8f6ff; - - --color-green-100: #044329; - --color-green-200: #004e2f; - --color-green-300: #005c38; - --color-green-400: #006c43; - --color-green-500: #007d4e; - --color-green-600: #008f5d; - --color-green-700: #12a26c; - --color-green-800: #2bb47d; - --color-green-900: #43c78f; - --color-green-1000: #5ed9a2; - --color-green-1100: #81e9b8; - --color-green-1200: #b1f4d1; - --color-green-1300: #dffaea; - - --color-orange-100: #662500; - --color-orange-200: #752d00; - --color-orange-300: #893700; - --color-orange-400: #9e4200; - --color-orange-500: #b44e00; - --color-orange-600: #ca5d00; - --color-orange-700: #e16d00; - --color-orange-800: #f4810c; - --color-orange-900: #fe9a2e; - --color-orange-1000: #ffb558; - --color-orange-1100: #fdce88; - --color-orange-1200: #ffe1b3; - --color-orange-1300: #fff2dd; - - --color-red-100: #7b0000; - --color-red-200: #8d0000; - --color-red-300: #a50000; - --color-red-400: #be0403; - --color-red-500: #d71913; - --color-red-600: #ea3829; - --color-red-700: #f65843; - --color-red-800: #ff755e; - --color-red-900: #ff9581; - --color-red-1000: #ffb0a1; - --color-red-1100: #ffc9bd; - --color-red-1200: #ffded8; - --color-red-1300: #fff1ee; - - --color-celery-100: #00450a; - --color-celery-200: #00500c; - --color-celery-300: #005e0e; - --color-celery-400: #006d0f; - --color-celery-500: #007f0f; - --color-celery-600: #009112; - --color-celery-700: #04a51e; - --color-celery-800: #22b833; - --color-celery-900: #44ca49; - --color-celery-1000: #69dc63; - --color-celery-1100: #8eeb7f; - --color-celery-1200: #b4f7a2; - --color-celery-1300: #ddfdd3; - - --color-chartreuse-100: #304000; - --color-chartreuse-200: #374a00; - --color-chartreuse-300: #415700; - --color-chartreuse-400: #4c6600; - --color-chartreuse-500: #597600; - --color-chartreuse-600: #668800; - --color-chartreuse-700: #759a00; - --color-chartreuse-800: #84ad01; - --color-chartreuse-900: #94c008; - --color-chartreuse-1000: #a6d312; - --color-chartreuse-1100: #b8e525; - --color-chartreuse-1200: #cdf547; - --color-chartreuse-1300: #e7fe9a; - - --color-cyan-100: #003d62; - --color-cyan-200: #00476f; - --color-cyan-300: #00557f; - --color-cyan-400: #006491; - --color-cyan-500: #0074a2; - --color-cyan-600: #0086b4; - --color-cyan-700: #0099c6; - --color-cyan-800: #0eadd7; - --color-cyan-900: #2cc1e6; - --color-cyan-1000: #54d3f1; - --color-cyan-1100: #7fe4f9; - --color-cyan-1200: #a7f1ff; - --color-cyan-1300: #d7faff; - - --color-fuchsia-100: #6b036a; - --color-fuchsia-200: #7b007b; - --color-fuchsia-300: #900091; - --color-fuchsia-400: #a50da6; - --color-fuchsia-500: #b925b9; - --color-fuchsia-600: #cd39ce; - --color-fuchsia-700: #df51e0; - --color-fuchsia-800: #eb6eec; - --color-fuchsia-900: #f48cf2; - --color-fuchsia-1000: #faa8f5; - --color-fuchsia-1100: #fec2f8; - --color-fuchsia-1200: #ffdbfa; - --color-fuchsia-1300: #ffeffc; - - --color-indigo-100: #282c8c; - --color-indigo-200: #2f34a3; - --color-indigo-300: #393fbb; - --color-indigo-400: #464bd3; - --color-indigo-500: #555be7; - --color-indigo-600: #686df4; - --color-indigo-700: #7c81fb; - --color-indigo-800: #9195ff; - --color-indigo-900: #a7aaff; - --color-indigo-1000: #bcbeff; - --color-indigo-1100: #d0d2ff; - --color-indigo-1200: #e2e4ff; - --color-indigo-1300: #f3f3fe; - - --color-magenta-100: #76003a; - --color-magenta-200: #890042; - --color-magenta-300: #a0004d; - --color-magenta-400: #b6125a; - --color-magenta-500: #cb266d; - --color-magenta-600: #de3d82; - --color-magenta-700: #ed5795; - --color-magenta-800: #f972a7; - --color-magenta-900: #ff8fb9; - --color-magenta-1000: #ffacca; - --color-magenta-1100: #ffc6da; - --color-magenta-1200: #ffdde9; - --color-magenta-1300: #fff0f5; - - --color-purple-100: #4c0d9d; - --color-purple-200: #5911b1; - --color-purple-300: #691cc8; - --color-purple-400: #7a2dda; - --color-purple-500: #8c41e9; - --color-purple-600: #9d57f3; - --color-purple-700: #ac6ff9; - --color-purple-800: #bb87fb; - --color-purple-900: #ca9ffc; - --color-purple-1000: #d7b6fe; - --color-purple-1100: #e4ccfe; - --color-purple-1200: #efdfff; - --color-purple-1300: #f9f0ff; - - --color-seafoam-100: #12413f; - --color-seafoam-200: #0e4c49; - --color-seafoam-300: #045a57; - --color-seafoam-400: #006965; - --color-seafoam-500: #007a75; - --color-seafoam-600: #008c87; - --color-seafoam-700: #009e98; - --color-seafoam-800: #03b2ab; - --color-seafoam-900: #36c5bd; - --color-seafoam-1000: #5dd6cf; - --color-seafoam-1100: #84e6df; - --color-seafoam-1200: #b0f2ec; - --color-seafoam-1300: #dff9f6; - - --color-yellow-100: #4c3600; - --color-yellow-200: #584000; - --color-yellow-300: #674c00; - --color-yellow-400: #775900; - --color-yellow-500: #886800; - --color-yellow-600: #9b7800; - --color-yellow-700: #ae8900; - --color-yellow-800: #c09c00; - --color-yellow-900: #d3ae00; - --color-yellow-1000: #e4c200; - --color-yellow-1100: #f4d500; - --color-yellow-1200: #f9e85c; - --color-yellow-1300: #fcf6bb; - } -} - -@media (prefers-color-scheme: light) { - :root { - --color-white: #ffffff; - - --color-gray-50: #fdfdfd; - --color-gray-100: #f8f8f8; - --color-gray-200: #e6e6e6; - --color-gray-300: #d5d5d5; - --color-gray-400: #b1b1b1; - --color-gray-500: #909090; - --color-gray-600: #6d6d6d; - --color-gray-700: #464646; - --color-gray-800: #222222; - --color-gray-900: #151515; - - --color-black: #000000; - - --color-blue-100: #e0f2ff; - --color-blue-200: #cae8ff; - --color-blue-300: #b5deff; - --color-blue-400: #96cefd; - --color-blue-500: #78bbfa; - --color-blue-600: #59a7f6; - --color-blue-700: #3892f3; - --color-blue-800: #147af3; - --color-blue-900: #0265dc; - --color-blue-1000: #0054b6; - --color-blue-1100: #004491; - --color-blue-1200: #003571; - --color-blue-1300: #002754; - - --color-green-100: #cef8e0; - --color-green-200: #adf4ce; - --color-green-300: #89ecbc; - --color-green-400: #67dea8; - --color-green-500: #49cc93; - --color-green-600: #2fb880; - --color-green-700: #15a46e; - --color-green-800: #008f5d; - --color-green-900: #007a4d; - --color-green-1000: #00653e; - --color-green-1100: #005132; - --color-green-1200: #053f27; - --color-green-1300: #0a2e1d; - - --color-orange-100: #ffeccc; - --color-orange-200: #ffdfad; - --color-orange-300: #fdd291; - --color-orange-400: #ffbb63; - --color-orange-500: #ffa037; - --color-orange-600: #f68511; - --color-orange-700: #e46f00; - --color-orange-800: #cb5d00; - --color-orange-900: #b14c00; - --color-orange-1000: #953d00; - --color-orange-1100: #7a2f00; - --color-orange-1200: #612300; - --color-orange-1300: #491901; - - --color-red-100: #ffebe7; - --color-red-200: #ffddd6; - --color-red-300: #ffcdc3; - --color-red-400: #ffb7a9; - --color-red-500: #ff9b88; - --color-red-600: #ff7c65; - --color-red-700: #f75c46; - --color-red-800: #ea3829; - --color-red-900: #d31510; - --color-red-1000: #b40000; - --color-red-1100: #930000; - --color-red-1200: #740000; - --color-red-1300: #590000; - - --color-celery-100: #cdfcbf; - --color-celery-200: #aef69d; - --color-celery-300: #96ee85; - --color-celery-400: #72e06a; - --color-celery-500: #4ecf50; - --color-celery-600: #27bb36; - --color-celery-700: #07a721; - --color-celery-800: #009112; - --color-celery-900: #007c0f; - --color-celery-1000: #00670f; - --color-celery-1100: #00530d; - --color-celery-1200: #00400a; - --color-celery-1300: #003007; - - --color-chartreuse-100: #dbfc6e; - --color-chartreuse-200: #cbf443; - --color-chartreuse-300: #bce92a; - --color-chartreuse-400: #aad816; - --color-chartreuse-500: #98c50a; - --color-chartreuse-600: #87b103; - --color-chartreuse-700: #769c00; - --color-chartreuse-800: #678800; - --color-chartreuse-900: #577400; - --color-chartreuse-1000: #486000; - --color-chartreuse-1100: #3a4d00; - --color-chartreuse-1200: #2c3b00; - --color-chartreuse-1300: #212c00; - - --color-cyan-100: #c5f8ff; - --color-cyan-200: #a4f0ff; - --color-cyan-300: #88e7fa; - --color-cyan-400: #60d8f3; - --color-cyan-500: #33c5e8; - --color-cyan-600: #12b0da; - --color-cyan-700: #019cc8; - --color-cyan-800: #0086b4; - --color-cyan-900: #00719f; - --color-cyan-1000: #005d89; - --color-cyan-1100: #004a73; - --color-cyan-1200: #00395d; - --color-cyan-1300: #002a46; - - --color-fuchsia-100: #ffe9fc; - --color-fuchsia-200: #ffdafa; - --color-fuchsia-300: #fec7f8; - --color-fuchsia-400: #fbaef6; - --color-fuchsia-500: #f592f3; - --color-fuchsia-600: #ed74ed; - --color-fuchsia-700: #e055e2; - --color-fuchsia-800: #cd3ace; - --color-fuchsia-900: #b622b7; - --color-fuchsia-1000: #9d039e; - --color-fuchsia-1100: #800081; - --color-fuchsia-1200: #640664; - --color-fuchsia-1300: #470e46; - - --color-indigo-100: #edeeff; - --color-indigo-200: #e0e2ff; - --color-indigo-300: #d3d5ff; - --color-indigo-400: #c1c4ff; - --color-indigo-500: #acafff; - --color-indigo-600: #9599ff; - --color-indigo-700: #7e84fc; - --color-indigo-800: #686df4; - --color-indigo-900: #5258e4; - --color-indigo-1000: #4046ca; - --color-indigo-1100: #3236a8; - --color-indigo-1200: #262986; - --color-indigo-1300: #1b1e64; - - --color-magenta-100: #ffeaf1; - --color-magenta-200: #ffdce8; - --color-magenta-300: #ffcadd; - --color-magenta-400: #ffb2ce; - --color-magenta-500: #ff95bd; - --color-magenta-600: #fa77aa; - --color-magenta-700: #ef5a98; - --color-magenta-800: #de3d82; - --color-magenta-900: #c82269; - --color-magenta-1000: #ad0955; - --color-magenta-1100: #8e0045; - --color-magenta-1200: #700037; - --color-magenta-1300: #54032a; - - --color-purple-100: #f6ebff; - --color-purple-200: #eeddff; - --color-purple-300: #e6d0ff; - --color-purple-400: #dbbbfe; - --color-purple-500: #cca4fd; - --color-purple-600: #bd8bfc; - --color-purple-700: #ae72f9; - --color-purple-800: #9d57f4; - --color-purple-900: #893de7; - --color-purple-1000: #7326d3; - --color-purple-1100: #5d13b7; - --color-purple-1200: #470c94; - --color-purple-1300: #33106a; - - --color-seafoam-100: #cef7f3; - --color-seafoam-200: #aaf1ea; - --color-seafoam-300: #8ce9e2; - --color-seafoam-400: #65dad2; - --color-seafoam-500: #3fc9c1; - --color-seafoam-600: #0fb5ae; - --color-seafoam-700: #00a19a; - --color-seafoam-800: #008c87; - --color-seafoam-900: #007772; - --color-seafoam-1000: #00635f; - --color-seafoam-1100: #0c4f4c; - --color-seafoam-1200: #123c3a; - --color-seafoam-1300: #122c2b; - - --color-yellow-100: #fbf198; - --color-yellow-200: #f8e750; - --color-yellow-300: #f8d904; - --color-yellow-400: #e8c600; - --color-yellow-500: #d7b300; - --color-yellow-600: #c49f00; - --color-yellow-700: #b08c00; - --color-yellow-800: #9b7800; - --color-yellow-900: #856600; - --color-yellow-1000: #705300; - --color-yellow-1100: #5b4300; - --color-yellow-1200: #483300; - --color-yellow-1300: #362500; - } -} +:root { + /* Persisted colors variables (not changed on dark mode) */ + --color-persist-white: #ffffff; + --color-persist-gray-50: #fdfdfd; + --color-persist-gray-100: #f8f8f8; + --color-persist-gray-200: #e6e6e6; + --color-persist-gray-300: #d5d5d5; + --color-persist-gray-400: #b1b1b1; + --color-persist-gray-500: #909090; + --color-persist-gray-600: #6d6d6d; + --color-persist-gray-700: #464646; + --color-persist-gray-800: #222222; + --color-persist-gray-900: #151515; + --color-persist-black: #000000; + + --color-persist-blue-100: #e0f2ff; + --color-persist-blue-200: #cae8ff; + --color-persist-blue-300: #b5deff; + --color-persist-blue-400: #96cefd; + --color-persist-blue-500: #78bbfa; + --color-persist-blue-600: #59a7f6; + --color-persist-blue-700: #3892f3; + --color-persist-blue-800: #147af3; + --color-persist-blue-900: #0265dc; + --color-persist-blue-1000: #0054b6; + --color-persist-blue-1100: #004491; + --color-persist-blue-1200: #003571; + --color-persist-blue-1300: #002754; + + --color-persist-green-100: #cef8e0; + --color-persist-green-200: #adf4ce; + --color-persist-green-300: #89ecbc; + --color-persist-green-400: #67dea8; + --color-persist-green-500: #49cc93; + --color-persist-green-600: #2fb880; + --color-persist-green-700: #15a46e; + --color-persist-green-800: #008f5d; + --color-persist-green-900: #007a4d; + --color-persist-green-1000: #00653e; + --color-persist-green-1100: #005132; + --color-persist-green-1200: #053f27; + --color-persist-green-1300: #0a2e1d; + + --color-persist-orange-100: #ffeccc; + --color-persist-orange-200: #ffdfad; + --color-persist-orange-300: #fdd291; + --color-persist-orange-400: #ffbb63; + --color-persist-orange-500: #ffa037; + --color-persist-orange-600: #f68511; + --color-persist-orange-700: #e46f00; + --color-persist-orange-800: #cb5d00; + --color-persist-orange-900: #b14c00; + --color-persist-orange-1000: #953d00; + --color-persist-orange-1100: #7a2f00; + --color-persist-orange-1200: #612300; + --color-persist-orange-1300: #491901; + + --color-persist-red-100: #ffebe7; + --color-persist-red-200: #ffddd6; + --color-persist-red-300: #ffcdc3; + --color-persist-red-400: #ffb7a9; + --color-persist-red-500: #ff9b88; + --color-persist-red-600: #ff7c65; + --color-persist-red-700: #f75c46; + --color-persist-red-800: #ea3829; + --color-persist-red-900: #d31510; + --color-persist-red-1000: #b40000; + --color-persist-red-1100: #930000; + --color-persist-red-1200: #740000; + --color-persist-red-1300: #590000; + + --color-persist-celery-100: #cdfcbf; + --color-persist-celery-200: #aef69d; + --color-persist-celery-300: #96ee85; + --color-persist-celery-400: #72e06a; + --color-persist-celery-500: #4ecf50; + --color-persist-celery-600: #27bb36; + --color-persist-celery-700: #07a721; + --color-persist-celery-800: #009112; + --color-persist-celery-900: #007c0f; + --color-persist-celery-1000: #00670f; + --color-persist-celery-1100: #00530d; + --color-persist-celery-1200: #00400a; + --color-persist-celery-1300: #003007; + + --color-persist-chartreuse-100: #dbfc6e; + --color-persist-chartreuse-200: #cbf443; + --color-persist-chartreuse-300: #bce92a; + --color-persist-chartreuse-400: #aad816; + --color-persist-chartreuse-500: #98c50a; + --color-persist-chartreuse-600: #87b103; + --color-persist-chartreuse-700: #769c00; + --color-persist-chartreuse-800: #678800; + --color-persist-chartreuse-900: #577400; + --color-persist-chartreuse-1000: #486000; + --color-persist-chartreuse-1100: #3a4d00; + --color-persist-chartreuse-1200: #2c3b00; + --color-persist-chartreuse-1300: #212c00; + + --color-persist-cyan-100: #c5f8ff; + --color-persist-cyan-200: #a4f0ff; + --color-persist-cyan-300: #88e7fa; + --color-persist-cyan-400: #60d8f3; + --color-persist-cyan-500: #33c5e8; + --color-persist-cyan-600: #12b0da; + --color-persist-cyan-700: #019cc8; + --color-persist-cyan-800: #0086b4; + --color-persist-cyan-900: #00719f; + --color-persist-cyan-1000: #005d89; + --color-persist-cyan-1100: #004a73; + --color-persist-cyan-1200: #00395d; + --color-persist-cyan-1300: #002a46; + + --color-persist-fuchsia-100: #ffe9fc; + --color-persist-fuchsia-200: #ffdafa; + --color-persist-fuchsia-300: #fec7f8; + --color-persist-fuchsia-400: #fbaef6; + --color-persist-fuchsia-500: #f592f3; + --color-persist-fuchsia-600: #ed74ed; + --color-persist-fuchsia-700: #e055e2; + --color-persist-fuchsia-800: #cd3ace; + --color-persist-fuchsia-900: #b622b7; + --color-persist-fuchsia-1000: #9d039e; + --color-persist-fuchsia-1100: #800081; + --color-persist-fuchsia-1200: #640664; + --color-persist-fuchsia-1300: #470e46; + + --color-persist-indigo-100: #edeeff; + --color-persist-indigo-200: #e0e2ff; + --color-persist-indigo-300: #d3d5ff; + --color-persist-indigo-400: #c1c4ff; + --color-persist-indigo-500: #acafff; + --color-persist-indigo-600: #9599ff; + --color-persist-indigo-700: #7e84fc; + --color-persist-indigo-800: #686df4; + --color-persist-indigo-900: #5258e4; + --color-persist-indigo-1000: #4046ca; + --color-persist-indigo-1100: #3236a8; + --color-persist-indigo-1200: #262986; + --color-persist-indigo-1300: #1b1e64; + + --color-persist-magenta-100: #ffeaf1; + --color-persist-magenta-200: #ffdce8; + --color-persist-magenta-300: #ffcadd; + --color-persist-magenta-400: #ffb2ce; + --color-persist-magenta-500: #ff95bd; + --color-persist-magenta-600: #fa77aa; + --color-persist-magenta-700: #ef5a98; + --color-persist-magenta-800: #de3d82; + --color-persist-magenta-900: #c82269; + --color-persist-magenta-1000: #ad0955; + --color-persist-magenta-1100: #8e0045; + --color-persist-magenta-1200: #700037; + --color-persist-magenta-1300: #54032a; + + --color-persist-purple-100: #f6ebff; + --color-persist-purple-200: #eeddff; + --color-persist-purple-300: #e6d0ff; + --color-persist-purple-400: #dbbbfe; + --color-persist-purple-500: #cca4fd; + --color-persist-purple-600: #bd8bfc; + --color-persist-purple-700: #ae72f9; + --color-persist-purple-800: #9d57f4; + --color-persist-purple-900: #893de7; + --color-persist-purple-1000: #7326d3; + --color-persist-purple-1100: #5d13b7; + --color-persist-purple-1200: #470c94; + --color-persist-purple-1300: #33106a; + + --color-persist-seafoam-100: #cef7f3; + --color-persist-seafoam-200: #aaf1ea; + --color-persist-seafoam-300: #8ce9e2; + --color-persist-seafoam-400: #65dad2; + --color-persist-seafoam-500: #3fc9c1; + --color-persist-seafoam-600: #0fb5ae; + --color-persist-seafoam-700: #00a19a; + --color-persist-seafoam-800: #008c87; + --color-persist-seafoam-900: #007772; + --color-persist-seafoam-1000: #00635f; + --color-persist-seafoam-1100: #0c4f4c; + --color-persist-seafoam-1200: #123c3a; + --color-persist-seafoam-1300: #122c2b; + + --color-persist-yellow-100: #fbf198; + --color-persist-yellow-200: #f8e750; + --color-persist-yellow-300: #f8d904; + --color-persist-yellow-400: #e8c600; + --color-persist-yellow-500: #d7b300; + --color-persist-yellow-600: #c49f00; + --color-persist-yellow-700: #b08c00; + --color-persist-yellow-800: #9b7800; + --color-persist-yellow-900: #856600; + --color-persist-yellow-1000: #705300; + --color-persist-yellow-1100: #5b4300; + --color-persist-yellow-1200: #483300; + --color-persist-yellow-1300: #362500; +} + +@media (prefers-color-scheme: dark) { + :root { + --color-white: #000000; + + --color-gray-50: #151515; + --color-gray-100: #222222; + --color-gray-200: #464646; + --color-gray-300: #6d6d6d; + --color-gray-400: #909090; + --color-gray-500: #b1b1b1; + --color-gray-600: #d5d5d5; + --color-gray-700: #e6e6e6; + --color-gray-800: #f8f8f8; + --color-gray-900: #fdfdfd; + + --color-black: #ffffff; + + --color-blue-100: #003877; + --color-blue-200: #00418a; + --color-blue-300: #004da3; + --color-blue-400: #0059c2; + --color-blue-500: #0367e0; + --color-blue-600: #1379f3; + --color-blue-700: #348ff4; + --color-blue-800: #54a3f6; + --color-blue-900: #72b7f9; + --color-blue-1000: #8fcafc; + --color-blue-1100: #aedbfe; + --color-blue-1200: #cce9ff; + --color-blue-1300: #e8f6ff; + + --color-green-100: #044329; + --color-green-200: #004e2f; + --color-green-300: #005c38; + --color-green-400: #006c43; + --color-green-500: #007d4e; + --color-green-600: #008f5d; + --color-green-700: #12a26c; + --color-green-800: #2bb47d; + --color-green-900: #43c78f; + --color-green-1000: #5ed9a2; + --color-green-1100: #81e9b8; + --color-green-1200: #b1f4d1; + --color-green-1300: #dffaea; + + --color-orange-100: #662500; + --color-orange-200: #752d00; + --color-orange-300: #893700; + --color-orange-400: #9e4200; + --color-orange-500: #b44e00; + --color-orange-600: #ca5d00; + --color-orange-700: #e16d00; + --color-orange-800: #f4810c; + --color-orange-900: #fe9a2e; + --color-orange-1000: #ffb558; + --color-orange-1100: #fdce88; + --color-orange-1200: #ffe1b3; + --color-orange-1300: #fff2dd; + + --color-red-100: #7b0000; + --color-red-200: #8d0000; + --color-red-300: #a50000; + --color-red-400: #be0403; + --color-red-500: #d71913; + --color-red-600: #ea3829; + --color-red-700: #f65843; + --color-red-800: #ff755e; + --color-red-900: #ff9581; + --color-red-1000: #ffb0a1; + --color-red-1100: #ffc9bd; + --color-red-1200: #ffded8; + --color-red-1300: #fff1ee; + + --color-celery-100: #00450a; + --color-celery-200: #00500c; + --color-celery-300: #005e0e; + --color-celery-400: #006d0f; + --color-celery-500: #007f0f; + --color-celery-600: #009112; + --color-celery-700: #04a51e; + --color-celery-800: #22b833; + --color-celery-900: #44ca49; + --color-celery-1000: #69dc63; + --color-celery-1100: #8eeb7f; + --color-celery-1200: #b4f7a2; + --color-celery-1300: #ddfdd3; + + --color-chartreuse-100: #304000; + --color-chartreuse-200: #374a00; + --color-chartreuse-300: #415700; + --color-chartreuse-400: #4c6600; + --color-chartreuse-500: #597600; + --color-chartreuse-600: #668800; + --color-chartreuse-700: #759a00; + --color-chartreuse-800: #84ad01; + --color-chartreuse-900: #94c008; + --color-chartreuse-1000: #a6d312; + --color-chartreuse-1100: #b8e525; + --color-chartreuse-1200: #cdf547; + --color-chartreuse-1300: #e7fe9a; + + --color-cyan-100: #003d62; + --color-cyan-200: #00476f; + --color-cyan-300: #00557f; + --color-cyan-400: #006491; + --color-cyan-500: #0074a2; + --color-cyan-600: #0086b4; + --color-cyan-700: #0099c6; + --color-cyan-800: #0eadd7; + --color-cyan-900: #2cc1e6; + --color-cyan-1000: #54d3f1; + --color-cyan-1100: #7fe4f9; + --color-cyan-1200: #a7f1ff; + --color-cyan-1300: #d7faff; + + --color-fuchsia-100: #6b036a; + --color-fuchsia-200: #7b007b; + --color-fuchsia-300: #900091; + --color-fuchsia-400: #a50da6; + --color-fuchsia-500: #b925b9; + --color-fuchsia-600: #cd39ce; + --color-fuchsia-700: #df51e0; + --color-fuchsia-800: #eb6eec; + --color-fuchsia-900: #f48cf2; + --color-fuchsia-1000: #faa8f5; + --color-fuchsia-1100: #fec2f8; + --color-fuchsia-1200: #ffdbfa; + --color-fuchsia-1300: #ffeffc; + + --color-indigo-100: #282c8c; + --color-indigo-200: #2f34a3; + --color-indigo-300: #393fbb; + --color-indigo-400: #464bd3; + --color-indigo-500: #555be7; + --color-indigo-600: #686df4; + --color-indigo-700: #7c81fb; + --color-indigo-800: #9195ff; + --color-indigo-900: #a7aaff; + --color-indigo-1000: #bcbeff; + --color-indigo-1100: #d0d2ff; + --color-indigo-1200: #e2e4ff; + --color-indigo-1300: #f3f3fe; + + --color-magenta-100: #76003a; + --color-magenta-200: #890042; + --color-magenta-300: #a0004d; + --color-magenta-400: #b6125a; + --color-magenta-500: #cb266d; + --color-magenta-600: #de3d82; + --color-magenta-700: #ed5795; + --color-magenta-800: #f972a7; + --color-magenta-900: #ff8fb9; + --color-magenta-1000: #ffacca; + --color-magenta-1100: #ffc6da; + --color-magenta-1200: #ffdde9; + --color-magenta-1300: #fff0f5; + + --color-purple-100: #4c0d9d; + --color-purple-200: #5911b1; + --color-purple-300: #691cc8; + --color-purple-400: #7a2dda; + --color-purple-500: #8c41e9; + --color-purple-600: #9d57f3; + --color-purple-700: #ac6ff9; + --color-purple-800: #bb87fb; + --color-purple-900: #ca9ffc; + --color-purple-1000: #d7b6fe; + --color-purple-1100: #e4ccfe; + --color-purple-1200: #efdfff; + --color-purple-1300: #f9f0ff; + + --color-seafoam-100: #12413f; + --color-seafoam-200: #0e4c49; + --color-seafoam-300: #045a57; + --color-seafoam-400: #006965; + --color-seafoam-500: #007a75; + --color-seafoam-600: #008c87; + --color-seafoam-700: #009e98; + --color-seafoam-800: #03b2ab; + --color-seafoam-900: #36c5bd; + --color-seafoam-1000: #5dd6cf; + --color-seafoam-1100: #84e6df; + --color-seafoam-1200: #b0f2ec; + --color-seafoam-1300: #dff9f6; + + --color-yellow-100: #4c3600; + --color-yellow-200: #584000; + --color-yellow-300: #674c00; + --color-yellow-400: #775900; + --color-yellow-500: #886800; + --color-yellow-600: #9b7800; + --color-yellow-700: #ae8900; + --color-yellow-800: #c09c00; + --color-yellow-900: #d3ae00; + --color-yellow-1000: #e4c200; + --color-yellow-1100: #f4d500; + --color-yellow-1200: #f9e85c; + --color-yellow-1300: #fcf6bb; + } +} + +@media (prefers-color-scheme: light) { + :root { + --color-white: #ffffff; + + --color-gray-50: #fdfdfd; + --color-gray-100: #f8f8f8; + --color-gray-200: #e6e6e6; + --color-gray-300: #d5d5d5; + --color-gray-400: #b1b1b1; + --color-gray-500: #909090; + --color-gray-600: #6d6d6d; + --color-gray-700: #464646; + --color-gray-800: #222222; + --color-gray-900: #151515; + + --color-black: #000000; + + --color-blue-100: #e0f2ff; + --color-blue-200: #cae8ff; + --color-blue-300: #b5deff; + --color-blue-400: #96cefd; + --color-blue-500: #78bbfa; + --color-blue-600: #59a7f6; + --color-blue-700: #3892f3; + --color-blue-800: #147af3; + --color-blue-900: #0265dc; + --color-blue-1000: #0054b6; + --color-blue-1100: #004491; + --color-blue-1200: #003571; + --color-blue-1300: #002754; + + --color-green-100: #cef8e0; + --color-green-200: #adf4ce; + --color-green-300: #89ecbc; + --color-green-400: #67dea8; + --color-green-500: #49cc93; + --color-green-600: #2fb880; + --color-green-700: #15a46e; + --color-green-800: #008f5d; + --color-green-900: #007a4d; + --color-green-1000: #00653e; + --color-green-1100: #005132; + --color-green-1200: #053f27; + --color-green-1300: #0a2e1d; + + --color-orange-100: #ffeccc; + --color-orange-200: #ffdfad; + --color-orange-300: #fdd291; + --color-orange-400: #ffbb63; + --color-orange-500: #ffa037; + --color-orange-600: #f68511; + --color-orange-700: #e46f00; + --color-orange-800: #cb5d00; + --color-orange-900: #b14c00; + --color-orange-1000: #953d00; + --color-orange-1100: #7a2f00; + --color-orange-1200: #612300; + --color-orange-1300: #491901; + + --color-red-100: #ffebe7; + --color-red-200: #ffddd6; + --color-red-300: #ffcdc3; + --color-red-400: #ffb7a9; + --color-red-500: #ff9b88; + --color-red-600: #ff7c65; + --color-red-700: #f75c46; + --color-red-800: #ea3829; + --color-red-900: #d31510; + --color-red-1000: #b40000; + --color-red-1100: #930000; + --color-red-1200: #740000; + --color-red-1300: #590000; + + --color-celery-100: #cdfcbf; + --color-celery-200: #aef69d; + --color-celery-300: #96ee85; + --color-celery-400: #72e06a; + --color-celery-500: #4ecf50; + --color-celery-600: #27bb36; + --color-celery-700: #07a721; + --color-celery-800: #009112; + --color-celery-900: #007c0f; + --color-celery-1000: #00670f; + --color-celery-1100: #00530d; + --color-celery-1200: #00400a; + --color-celery-1300: #003007; + + --color-chartreuse-100: #dbfc6e; + --color-chartreuse-200: #cbf443; + --color-chartreuse-300: #bce92a; + --color-chartreuse-400: #aad816; + --color-chartreuse-500: #98c50a; + --color-chartreuse-600: #87b103; + --color-chartreuse-700: #769c00; + --color-chartreuse-800: #678800; + --color-chartreuse-900: #577400; + --color-chartreuse-1000: #486000; + --color-chartreuse-1100: #3a4d00; + --color-chartreuse-1200: #2c3b00; + --color-chartreuse-1300: #212c00; + + --color-cyan-100: #c5f8ff; + --color-cyan-200: #a4f0ff; + --color-cyan-300: #88e7fa; + --color-cyan-400: #60d8f3; + --color-cyan-500: #33c5e8; + --color-cyan-600: #12b0da; + --color-cyan-700: #019cc8; + --color-cyan-800: #0086b4; + --color-cyan-900: #00719f; + --color-cyan-1000: #005d89; + --color-cyan-1100: #004a73; + --color-cyan-1200: #00395d; + --color-cyan-1300: #002a46; + + --color-fuchsia-100: #ffe9fc; + --color-fuchsia-200: #ffdafa; + --color-fuchsia-300: #fec7f8; + --color-fuchsia-400: #fbaef6; + --color-fuchsia-500: #f592f3; + --color-fuchsia-600: #ed74ed; + --color-fuchsia-700: #e055e2; + --color-fuchsia-800: #cd3ace; + --color-fuchsia-900: #b622b7; + --color-fuchsia-1000: #9d039e; + --color-fuchsia-1100: #800081; + --color-fuchsia-1200: #640664; + --color-fuchsia-1300: #470e46; + + --color-indigo-100: #edeeff; + --color-indigo-200: #e0e2ff; + --color-indigo-300: #d3d5ff; + --color-indigo-400: #c1c4ff; + --color-indigo-500: #acafff; + --color-indigo-600: #9599ff; + --color-indigo-700: #7e84fc; + --color-indigo-800: #686df4; + --color-indigo-900: #5258e4; + --color-indigo-1000: #4046ca; + --color-indigo-1100: #3236a8; + --color-indigo-1200: #262986; + --color-indigo-1300: #1b1e64; + + --color-magenta-100: #ffeaf1; + --color-magenta-200: #ffdce8; + --color-magenta-300: #ffcadd; + --color-magenta-400: #ffb2ce; + --color-magenta-500: #ff95bd; + --color-magenta-600: #fa77aa; + --color-magenta-700: #ef5a98; + --color-magenta-800: #de3d82; + --color-magenta-900: #c82269; + --color-magenta-1000: #ad0955; + --color-magenta-1100: #8e0045; + --color-magenta-1200: #700037; + --color-magenta-1300: #54032a; + + --color-purple-100: #f6ebff; + --color-purple-200: #eeddff; + --color-purple-300: #e6d0ff; + --color-purple-400: #dbbbfe; + --color-purple-500: #cca4fd; + --color-purple-600: #bd8bfc; + --color-purple-700: #ae72f9; + --color-purple-800: #9d57f4; + --color-purple-900: #893de7; + --color-purple-1000: #7326d3; + --color-purple-1100: #5d13b7; + --color-purple-1200: #470c94; + --color-purple-1300: #33106a; + + --color-seafoam-100: #cef7f3; + --color-seafoam-200: #aaf1ea; + --color-seafoam-300: #8ce9e2; + --color-seafoam-400: #65dad2; + --color-seafoam-500: #3fc9c1; + --color-seafoam-600: #0fb5ae; + --color-seafoam-700: #00a19a; + --color-seafoam-800: #008c87; + --color-seafoam-900: #007772; + --color-seafoam-1000: #00635f; + --color-seafoam-1100: #0c4f4c; + --color-seafoam-1200: #123c3a; + --color-seafoam-1300: #122c2b; + + --color-yellow-100: #fbf198; + --color-yellow-200: #f8e750; + --color-yellow-300: #f8d904; + --color-yellow-400: #e8c600; + --color-yellow-500: #d7b300; + --color-yellow-600: #c49f00; + --color-yellow-700: #b08c00; + --color-yellow-800: #9b7800; + --color-yellow-900: #856600; + --color-yellow-1000: #705300; + --color-yellow-1100: #5b4300; + --color-yellow-1200: #483300; + --color-yellow-1300: #362500; + } +} diff --git a/src/apps/seelen_wm/styles/global.css b/src/apps/seelen_wm/styles/global.css index 522be40e..199b91fe 100644 --- a/src/apps/seelen_wm/styles/global.css +++ b/src/apps/seelen_wm/styles/global.css @@ -1,23 +1,23 @@ -*, *:after, *:before { - margin: 0; - padding: 0; - border: 0; - outline: none; - box-sizing: border-box; - vertical-align: baseline; -} - -#root { - padding-top: calc(var(--config-padding) + var(--config-margin-top)); - padding-left: calc(var(--config-padding) + var(--config-margin-left)); - padding-right: calc(var(--config-padding) + var(--config-margin-right)); - padding-bottom: calc(var(--config-padding) + var(--config-margin-bottom)); - height: 100%; - width: 100%; -} - -body { - height: 100vh; - width: 100vw; - overflow: hidden; +*, *:after, *:before { + margin: 0; + padding: 0; + border: 0; + outline: none; + box-sizing: border-box; + vertical-align: baseline; +} + +#root { + padding-top: calc(var(--config-padding) + var(--config-margin-top)); + padding-left: calc(var(--config-padding) + var(--config-margin-left)); + padding-right: calc(var(--config-padding) + var(--config-margin-right)); + padding-bottom: calc(var(--config-padding) + var(--config-margin-bottom)); + height: 100%; + width: 100%; +} + +body { + height: 100vh; + width: 100vw; + overflow: hidden; } \ No newline at end of file diff --git a/src/apps/seelen_wm/styles/variables.css b/src/apps/seelen_wm/styles/variables.css index 42275892..3e189322 100644 --- a/src/apps/seelen_wm/styles/variables.css +++ b/src/apps/seelen_wm/styles/variables.css @@ -1,15 +1,15 @@ -:root { - --config-padding: 0px; - --config-containers-gap: 0px; - - --config-margin-top: 0px; - --config-margin-left: 0px; - --config-margin-right: 0px; - --config-margin-bottom: 0px; - - --config-accent-color: #ff0000; - --config-accent-color-rgb: 255, 0, 0; - - --config-border-offset: 0px; - --config-border-width: 0px; -} +:root { + --config-padding: 0px; + --config-containers-gap: 0px; + + --config-margin-top: 0px; + --config-margin-left: 0px; + --config-margin-right: 0px; + --config-margin-bottom: 0px; + + --config-accent-color: #ff0000; + --config-accent-color-rgb: 255, 0, 0; + + --config-border-offset: 0px; + --config-border-width: 0px; +} diff --git a/src/apps/seelenweg-hitbox/index.css b/src/apps/seelenweg-hitbox/index.css index 766cfd5d..a92a4589 100644 --- a/src/apps/seelenweg-hitbox/index.css +++ b/src/apps/seelenweg-hitbox/index.css @@ -1,12 +1,12 @@ -*, *:after, *:before { - margin: 0; - padding: 0; - border: 0; - outline: none; - box-sizing: border-box; - vertical-align: baseline; -} - -/* body { - background: lime; +*, *:after, *:before { + margin: 0; + padding: 0; + border: 0; + outline: none; + box-sizing: border-box; + vertical-align: baseline; +} + +/* body { + background: lime; } */ \ No newline at end of file diff --git a/src/apps/seelenweg-hitbox/index.html b/src/apps/seelenweg-hitbox/index.html index aa458273..5a3e45d6 100644 --- a/src/apps/seelenweg-hitbox/index.html +++ b/src/apps/seelenweg-hitbox/index.html @@ -1,8 +1,8 @@ - - - - - - - - + + + + + + + + diff --git a/src/apps/seelenweg-hitbox/index.tsx b/src/apps/seelenweg-hitbox/index.tsx index eb776e47..84d07bb5 100644 --- a/src/apps/seelenweg-hitbox/index.tsx +++ b/src/apps/seelenweg-hitbox/index.tsx @@ -1,56 +1,56 @@ -import { wrapConsole } from '../shared/ConsoleWrapper'; -import { invoke } from '@tauri-apps/api/core'; -import { PhysicalPosition, PhysicalSize } from '@tauri-apps/api/dpi'; -import { emitTo } from '@tauri-apps/api/event'; -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; - -import './index.css'; - -async function Main() { - wrapConsole(); - let view = getCurrentWebviewWindow(); - let main = view.label.replace('-hitbox', ''); - - view.listen('init', () => { - getCurrentWebviewWindow().show(); - - document.body.addEventListener('mouseenter', () => { - emitTo(main, 'mouseenter'); - invoke('ensure_hitboxes_zorder').catch(console.error); - }); - - async function onClick(e: MouseEvent | TouchEvent) { - invoke('ensure_hitboxes_zorder').catch(console.error); - - let x = 0; - let y = 0; - if (e instanceof MouseEvent) { - x = e.clientX; - y = e.clientY; - emitTo(main, 'click', { x, y }); - return; - } - - if (e.touches && e.touches.length > 0) { - x = e.touches[0]?.clientX || 0; - y = e.touches[0]?.clientY || 0; - emitTo(main, 'click', { x, y }); - } - } - - document.body.addEventListener('click', onClick); - document.body.addEventListener('touchend', onClick); - }); - - view.listen('resize', (event) => { - const { width, height } = event.payload as any; - getCurrentWebviewWindow().setSize(new PhysicalSize(width, height)); - }); - - view.listen('move', (event) => { - const { x, y } = event.payload as any; - getCurrentWebviewWindow().setPosition(new PhysicalPosition(x, y)); - }); -} - -Main(); +import { wrapConsole } from '../shared/ConsoleWrapper'; +import { invoke } from '@tauri-apps/api/core'; +import { PhysicalPosition, PhysicalSize } from '@tauri-apps/api/dpi'; +import { emitTo } from '@tauri-apps/api/event'; +import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; + +import './index.css'; + +async function Main() { + wrapConsole(); + let view = getCurrentWebviewWindow(); + let main = view.label.replace('-hitbox', ''); + + view.listen('init', () => { + getCurrentWebviewWindow().show(); + + document.body.addEventListener('mouseenter', () => { + emitTo(main, 'mouseenter'); + invoke('ensure_hitboxes_zorder').catch(console.error); + }); + + async function onClick(e: MouseEvent | TouchEvent) { + invoke('ensure_hitboxes_zorder').catch(console.error); + + let x = 0; + let y = 0; + if (e instanceof MouseEvent) { + x = e.clientX; + y = e.clientY; + emitTo(main, 'click', { x, y }); + return; + } + + if (e.touches && e.touches.length > 0) { + x = e.touches[0]?.clientX || 0; + y = e.touches[0]?.clientY || 0; + emitTo(main, 'click', { x, y }); + } + } + + document.body.addEventListener('click', onClick); + document.body.addEventListener('touchend', onClick); + }); + + view.listen('resize', (event) => { + const { width, height } = event.payload as any; + getCurrentWebviewWindow().setSize(new PhysicalSize(width, height)); + }); + + view.listen('move', (event) => { + const { x, y } = event.payload as any; + getCurrentWebviewWindow().setPosition(new PhysicalPosition(x, y)); + }); +} + +Main(); diff --git a/src/apps/seelenweg/app.tsx b/src/apps/seelenweg/app.tsx index 97a81948..a410758c 100644 --- a/src/apps/seelenweg/app.tsx +++ b/src/apps/seelenweg/app.tsx @@ -1,46 +1,46 @@ -import { getRootContainer } from '../shared'; -import { useDarkMode } from '../shared/styles'; -import { ErrorBoundary } from './components/Error'; -import { updateHitbox } from './events'; -import { SeelenWeg } from './modules/bar'; -import { emit, emitTo } from '@tauri-apps/api/event'; -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; -import { ConfigProvider, theme } from 'antd'; -import { useEffect } from 'react'; -import { useSelector } from 'react-redux'; - -import { Selectors } from './modules/shared/store/app'; - -async function onMount() { - let view = getCurrentWebviewWindow(); - updateHitbox(); - await emitTo(view.label.replace('/', '-hitbox/'), 'init'); - await view.show(); - await view.emitTo(view.label, 'complete-setup'); - await emit('register-colors-events'); -} -export function App() { - const isDarkMode = useDarkMode(); - const colors = useSelector(Selectors.colors); - - useEffect(() => { - onMount(); - }, []); - - return ( - - Something went wrong
}> - - - - ); -} +import { getRootContainer } from '../shared'; +import { useDarkMode } from '../shared/styles'; +import { ErrorBoundary } from './components/Error'; +import { updateHitbox } from './events'; +import { SeelenWeg } from './modules/bar'; +import { emit, emitTo } from '@tauri-apps/api/event'; +import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; +import { ConfigProvider, theme } from 'antd'; +import { useEffect } from 'react'; +import { useSelector } from 'react-redux'; + +import { Selectors } from './modules/shared/store/app'; + +async function onMount() { + let view = getCurrentWebviewWindow(); + updateHitbox(); + await emitTo(view.label.replace('/', '-hitbox/'), 'init'); + await view.show(); + await view.emitTo(view.label, 'complete-setup'); + await emit('register-colors-events'); +} +export function App() { + const isDarkMode = useDarkMode(); + const colors = useSelector(Selectors.colors); + + useEffect(() => { + onMount(); + }, []); + + return ( + + Something went wrong
}> + + + + ); +} diff --git a/src/apps/seelenweg/components/BackgroundByLayers/infra.module.css b/src/apps/seelenweg/components/BackgroundByLayers/infra.module.css index 22be4d4b..3ad1a99e 100644 --- a/src/apps/seelenweg/components/BackgroundByLayers/infra.module.css +++ b/src/apps/seelenweg/components/BackgroundByLayers/infra.module.css @@ -1,18 +1,18 @@ -.background { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: -1; - - .layer { - width: 100%; - height: 100%; - position: absolute; - } -} - -.container { - position: relative; -} +.background { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: -1; + + .layer { + width: 100%; + height: 100%; + position: absolute; + } +} + +.container { + position: relative; +} diff --git a/src/apps/seelenweg/components/BackgroundByLayers/infra.tsx b/src/apps/seelenweg/components/BackgroundByLayers/infra.tsx index ac592b42..21355efc 100644 --- a/src/apps/seelenweg/components/BackgroundByLayers/infra.tsx +++ b/src/apps/seelenweg/components/BackgroundByLayers/infra.tsx @@ -1,42 +1,42 @@ -import { cx } from '../../../shared/styles'; -import { HTMLAttributes, PropsWithChildren } from 'react'; - -import cs from './infra.module.css'; - -interface PropsV2 extends PropsWithChildren, HTMLAttributes { - className?: string; - /** for backward compatibility */ - prefix?: string; -} - -export function BackgroundByLayersV2({ - children, - className, - prefix: _prefix, - ...divProps -}: PropsV2) { - const prefix = _prefix ? _prefix + '-' : ''; - - let background = ( -
- {Array.from({ length: 10 }, (_, index) => ( -
- ))} -
- ); - - if (!children) { - /** for backward compatibility with V1 */ - return background; - } - - return ( -
- {background} - {children} -
- ); -} +import { cx } from '../../../shared/styles'; +import { HTMLAttributes, PropsWithChildren } from 'react'; + +import cs from './infra.module.css'; + +interface PropsV2 extends PropsWithChildren, HTMLAttributes { + className?: string; + /** for backward compatibility */ + prefix?: string; +} + +export function BackgroundByLayersV2({ + children, + className, + prefix: _prefix, + ...divProps +}: PropsV2) { + const prefix = _prefix ? _prefix + '-' : ''; + + let background = ( +
+ {Array.from({ length: 10 }, (_, index) => ( +
+ ))} +
+ ); + + if (!children) { + /** for backward compatibility with V1 */ + return background; + } + + return ( +
+ {background} + {children} +
+ ); +} diff --git a/src/apps/seelenweg/components/Error/index.tsx b/src/apps/seelenweg/components/Error/index.tsx index ca7a52d6..c97e3c75 100644 --- a/src/apps/seelenweg/components/Error/index.tsx +++ b/src/apps/seelenweg/components/Error/index.tsx @@ -1,33 +1,33 @@ -import React from 'react'; - -interface Props { - fallback: React.ReactNode; - children: React.ReactNode; -} - -interface State { - hasError: boolean; -} - -export class ErrorBoundary extends React.Component { - constructor(props: Props) { - super(props); - this.state = { hasError: false }; - } - - static getDerivedStateFromError() { - return { hasError: true }; - } - - componentDidCatch(error: any, info: any) { - console.error(error, info); - } - - render() { - if (this.state.hasError) { - return this.props.fallback; - } - - return this.props.children; - } +import React from 'react'; + +interface Props { + fallback: React.ReactNode; + children: React.ReactNode; +} + +interface State { + hasError: boolean; +} + +export class ErrorBoundary extends React.Component { + constructor(props: Props) { + super(props); + this.state = { hasError: false }; + } + + static getDerivedStateFromError() { + return { hasError: true }; + } + + componentDidCatch(error: any, info: any) { + console.error(error, info); + } + + render() { + if (this.state.hasError) { + return this.props.fallback; + } + + return this.props.children; + } } \ No newline at end of file diff --git a/src/apps/seelenweg/components/TooltipWrap/infra.tsx b/src/apps/seelenweg/components/TooltipWrap/infra.tsx index e91b8a9e..81ac6ccc 100644 --- a/src/apps/seelenweg/components/TooltipWrap/infra.tsx +++ b/src/apps/seelenweg/components/TooltipWrap/infra.tsx @@ -1,17 +1,17 @@ -import { Tooltip } from 'antd'; -import { PropsWithChildren } from 'react'; - -interface Props extends PropsWithChildren { - showToltip: boolean; - text: string; -} - -export const TooltipWrap = ({ children, showToltip, text }: Props) => { - if (!showToltip) { - return children; - } - - return - {children} - ; +import { Tooltip } from 'antd'; +import { PropsWithChildren } from 'react'; + +interface Props extends PropsWithChildren { + showToltip: boolean; + text: string; +} + +export const TooltipWrap = ({ children, showToltip, text }: Props) => { + if (!showToltip) { + return children; + } + + return + {children} + ; }; \ No newline at end of file diff --git a/src/apps/seelenweg/components/WithContextMenu.tsx b/src/apps/seelenweg/components/WithContextMenu.tsx index 7fb6ab5f..e80287c9 100644 --- a/src/apps/seelenweg/components/WithContextMenu.tsx +++ b/src/apps/seelenweg/components/WithContextMenu.tsx @@ -1,41 +1,41 @@ -import { Dropdown, Menu } from 'antd'; -import { ItemType, MenuItemType } from 'antd/es/menu/interface'; -import { PropsWithChildren, useState } from 'react'; - -import { useAppBlur } from '../modules/shared/hooks/infra'; -import { BackgroundByLayersV2 } from './BackgroundByLayers/infra'; - -interface Props extends PropsWithChildren { - items: ItemType[]; -} - -export function WithContextMenu({ children, items }: Props) { - const [openContextMenu, setOpenContextMenu] = useState(false); - - useAppBlur(() => { - setOpenContextMenu(false); - }); - - return ( - ( - - e.stopPropagation()} - items={items} - /> - - )} - > - {children} - - ); -} +import { Dropdown, Menu } from 'antd'; +import { ItemType, MenuItemType } from 'antd/es/menu/interface'; +import { PropsWithChildren, useState } from 'react'; + +import { useAppBlur } from '../modules/shared/hooks/infra'; +import { BackgroundByLayersV2 } from './BackgroundByLayers/infra'; + +interface Props extends PropsWithChildren { + items: ItemType[]; +} + +export function WithContextMenu({ children, items }: Props) { + const [openContextMenu, setOpenContextMenu] = useState(false); + + useAppBlur(() => { + setOpenContextMenu(false); + }); + + return ( + ( + + e.stopPropagation()} + items={items} + /> + + )} + > + {children} + + ); +} diff --git a/src/apps/seelenweg/events.ts b/src/apps/seelenweg/events.ts index 6a591414..0b7ea065 100644 --- a/src/apps/seelenweg/events.ts +++ b/src/apps/seelenweg/events.ts @@ -1,91 +1,91 @@ -import { toPhysicalPixels } from '../shared'; -import { SeelenWegHideMode, SeelenWegSide } from '../shared/schemas/Seelenweg'; -import { debounce, TimeoutIdRef } from '../shared/Timing'; -import { emitTo } from '@tauri-apps/api/event'; -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; - -import { store } from './modules/shared/store/infra'; - -import { CallbacksManager } from './modules/shared/utils/app'; - -const root_container = document.getElementById('root')!; - -export const ExtraCallbacksOnLeave = new CallbacksManager(); -export const ExtraCallbacksOnActivate = new CallbacksManager(); - -export const updateHitbox = debounce(async () => { - const { - isOverlaped, - settings: { position, hideMode }, - } = store.getState(); - const view = getCurrentWebviewWindow(); - const hitboxTarget = view.label.replace('/', '-hitbox/'); - - const viewPosition = await view.innerPosition(); - const viewSize = await view.innerSize(); - - const isAutoHideOn = - (hideMode !== SeelenWegHideMode.Never && isOverlaped) || hideMode === SeelenWegHideMode.Always; - const isHorizontal = position === SeelenWegSide.TOP || position === SeelenWegSide.BOTTOM; - - const hiddenOffsetTop = - position === SeelenWegSide.TOP ? viewPosition.y : viewPosition.y + viewSize.height - 1; - const hiddenOffsetLeft = - position === SeelenWegSide.LEFT ? viewPosition.x : viewPosition.x + viewSize.width - 1; - emitTo(hitboxTarget, 'move', { - x: - isAutoHideOn && !isHorizontal - ? hiddenOffsetLeft - : viewPosition.x + toPhysicalPixels(root_container.offsetLeft), - y: - isAutoHideOn && isHorizontal - ? hiddenOffsetTop - : viewPosition.y + toPhysicalPixels(root_container.offsetTop), - }); - emitTo(hitboxTarget, 'resize', { - width: isAutoHideOn && !isHorizontal ? 1 : toPhysicalPixels(root_container.offsetWidth), - height: isAutoHideOn && isHorizontal ? 1 : toPhysicalPixels(root_container.offsetHeight), - }); -}, 300); - -export function registerDocumentEvents() { - const timeoutId: TimeoutIdRef = { current: null }; - const webview = getCurrentWebviewWindow(); - - const onMouseLeave = debounce( - () => { - webview.setIgnoreCursorEvents(true); - ExtraCallbacksOnLeave.execute(); - updateHitbox(); - }, - 200, - timeoutId, - ); - - const onMouseEnter = () => { - if (timeoutId.current) { - clearTimeout(timeoutId.current); - } - webview.setIgnoreCursorEvents(false); - ExtraCallbacksOnActivate.execute(); - }; - - root_container.addEventListener('mouseleave', onMouseLeave); - // if for some reazon mouseleave is not emitted - // set ignore cursor events when user click on screen - document.body.addEventListener('click', (event) => { - if (event.target === document.body) { - onMouseLeave(); - } - }); - - root_container.addEventListener('mouseenter', onMouseEnter); - webview.listen('mouseenter', onMouseEnter); // listener for hitbox - - webview.listen<{ x: number; y: number }>('click', (event) => { - let element = document.elementFromPoint(event.payload.x, event.payload.y); - if (element && 'click' in element && typeof element.click === 'function') { - element.click(); - } - }); -} +import { toPhysicalPixels } from '../shared'; +import { SeelenWegHideMode, SeelenWegSide } from '../shared/schemas/Seelenweg'; +import { debounce, TimeoutIdRef } from '../shared/Timing'; +import { emitTo } from '@tauri-apps/api/event'; +import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; + +import { store } from './modules/shared/store/infra'; + +import { CallbacksManager } from './modules/shared/utils/app'; + +const root_container = document.getElementById('root')!; + +export const ExtraCallbacksOnLeave = new CallbacksManager(); +export const ExtraCallbacksOnActivate = new CallbacksManager(); + +export const updateHitbox = debounce(async () => { + const { + isOverlaped, + settings: { position, hideMode }, + } = store.getState(); + const view = getCurrentWebviewWindow(); + const hitboxTarget = view.label.replace('/', '-hitbox/'); + + const viewPosition = await view.innerPosition(); + const viewSize = await view.innerSize(); + + const isAutoHideOn = + (hideMode !== SeelenWegHideMode.Never && isOverlaped) || hideMode === SeelenWegHideMode.Always; + const isHorizontal = position === SeelenWegSide.TOP || position === SeelenWegSide.BOTTOM; + + const hiddenOffsetTop = + position === SeelenWegSide.TOP ? viewPosition.y : viewPosition.y + viewSize.height - 1; + const hiddenOffsetLeft = + position === SeelenWegSide.LEFT ? viewPosition.x : viewPosition.x + viewSize.width - 1; + emitTo(hitboxTarget, 'move', { + x: + isAutoHideOn && !isHorizontal + ? hiddenOffsetLeft + : viewPosition.x + toPhysicalPixels(root_container.offsetLeft), + y: + isAutoHideOn && isHorizontal + ? hiddenOffsetTop + : viewPosition.y + toPhysicalPixels(root_container.offsetTop), + }); + emitTo(hitboxTarget, 'resize', { + width: isAutoHideOn && !isHorizontal ? 1 : toPhysicalPixels(root_container.offsetWidth), + height: isAutoHideOn && isHorizontal ? 1 : toPhysicalPixels(root_container.offsetHeight), + }); +}, 300); + +export function registerDocumentEvents() { + const timeoutId: TimeoutIdRef = { current: null }; + const webview = getCurrentWebviewWindow(); + + const onMouseLeave = debounce( + () => { + webview.setIgnoreCursorEvents(true); + ExtraCallbacksOnLeave.execute(); + updateHitbox(); + }, + 200, + timeoutId, + ); + + const onMouseEnter = () => { + if (timeoutId.current) { + clearTimeout(timeoutId.current); + } + webview.setIgnoreCursorEvents(false); + ExtraCallbacksOnActivate.execute(); + }; + + root_container.addEventListener('mouseleave', onMouseLeave); + // if for some reazon mouseleave is not emitted + // set ignore cursor events when user click on screen + document.body.addEventListener('click', (event) => { + if (event.target === document.body) { + onMouseLeave(); + } + }); + + root_container.addEventListener('mouseenter', onMouseEnter); + webview.listen('mouseenter', onMouseEnter); // listener for hitbox + + webview.listen<{ x: number; y: number }>('click', (event) => { + let element = document.elementFromPoint(event.payload.x, event.payload.y); + if (element && 'click' in element && typeof element.click === 'function') { + element.click(); + } + }); +} diff --git a/src/apps/seelenweg/i18n/index.ts b/src/apps/seelenweg/i18n/index.ts index 714b73a7..caf11a7c 100644 --- a/src/apps/seelenweg/i18n/index.ts +++ b/src/apps/seelenweg/i18n/index.ts @@ -1,98 +1,98 @@ -import { Lang } from '../../shared/lang'; -import i18n from 'i18next'; -import yaml from 'js-yaml'; -import { initReactI18next } from 'react-i18next'; - -i18n.use(initReactI18next).init( - { - lng: 'en', - fallbackLng: 'en', - interpolation: { - escapeValue: false, - }, - debug: true, - resources: {}, - }, - undefined, -); - -export async function loadTranslations() { - const translations: Record = { - en: await import('./translations/en.yml'), - es: await import('./translations/es.yml'), - de: await import('./translations/de.yml'), - zh: await import('./translations/zh.yml'), - ko: await import('./translations/ko.yml'), - fr: await import('./translations/fr.yml'), - ar: await import('./translations/ar.yml'), - ru: await import('./translations/ru.yml'), - pt: await import('./translations/pt.yml'), - ja: await import('./translations/ja.yml'), - hi: await import('./translations/hi.yml'), - it: await import('./translations/it.yml'), - nl: await import('./translations/nl.yml'), - tr: await import('./translations/tr.yml'), - pl: await import('./translations/pl.yml'), - uk: await import('./translations/uk.yml'), - id: await import('./translations/id.yml'), - cs: await import('./translations/cs.yml'), - th: await import('./translations/th.yml'), - vi: await import('./translations/vi.yml'), - ms: await import('./translations/ms.yml'), - he: await import('./translations/he.yml'), - ro: await import('./translations/ro.yml'), - el: await import('./translations/el.yml'), - sv: await import('./translations/sv.yml'), - no: await import('./translations/no.yml'), - fi: await import('./translations/fi.yml'), - da: await import('./translations/da.yml'), - hu: await import('./translations/hu.yml'), - lt: await import('./translations/lt.yml'), - bg: await import('./translations/bg.yml'), - sk: await import('./translations/sk.yml'), - hr: await import('./translations/hr.yml'), - lv: await import('./translations/lv.yml'), - et: await import('./translations/et.yml'), - tl: await import('./translations/tl.yml'), - ca: await import('./translations/ca.yml'), - af: await import('./translations/af.yml'), - bn: await import('./translations/bn.yml'), - fa: await import('./translations/fa.yml'), - pa: await import('./translations/pa.yml'), - sw: await import('./translations/sw.yml'), - ta: await import('./translations/ta.yml'), - ur: await import('./translations/ur.yml'), - cy: await import('./translations/cy.yml'), - am: await import('./translations/am.yml'), - hy: await import('./translations/hy.yml'), - az: await import('./translations/az.yml'), - eu: await import('./translations/eu.yml'), - bs: await import('./translations/bs.yml'), - ka: await import('./translations/ka.yml'), - gu: await import('./translations/gu.yml'), - is: await import('./translations/is.yml'), - km: await import('./translations/km.yml'), - ku: await import('./translations/ku.yml'), - lo: await import('./translations/lo.yml'), - lb: await import('./translations/lb.yml'), - mk: await import('./translations/mk.yml'), - mt: await import('./translations/mt.yml'), - mn: await import('./translations/mn.yml'), - ne: await import('./translations/ne.yml'), - ps: await import('./translations/ps.yml'), - sr: await import('./translations/sr.yml'), - si: await import('./translations/si.yml'), - so: await import('./translations/so.yml'), - tg: await import('./translations/tg.yml'), - te: await import('./translations/te.yml'), - uz: await import('./translations/uz.yml'), - yo: await import('./translations/yo.yml'), - zu: await import('./translations/zu.yml'), - }; - - for (const [key, value] of Object.entries(translations)) { - i18n.addResourceBundle(key, 'translation', yaml.load(value.default)); - } -} - -export default i18n; +import { Lang } from '../../shared/lang'; +import i18n from 'i18next'; +import yaml from 'js-yaml'; +import { initReactI18next } from 'react-i18next'; + +i18n.use(initReactI18next).init( + { + lng: 'en', + fallbackLng: 'en', + interpolation: { + escapeValue: false, + }, + debug: true, + resources: {}, + }, + undefined, +); + +export async function loadTranslations() { + const translations: Record = { + en: await import('./translations/en.yml'), + es: await import('./translations/es.yml'), + de: await import('./translations/de.yml'), + zh: await import('./translations/zh.yml'), + ko: await import('./translations/ko.yml'), + fr: await import('./translations/fr.yml'), + ar: await import('./translations/ar.yml'), + ru: await import('./translations/ru.yml'), + pt: await import('./translations/pt.yml'), + ja: await import('./translations/ja.yml'), + hi: await import('./translations/hi.yml'), + it: await import('./translations/it.yml'), + nl: await import('./translations/nl.yml'), + tr: await import('./translations/tr.yml'), + pl: await import('./translations/pl.yml'), + uk: await import('./translations/uk.yml'), + id: await import('./translations/id.yml'), + cs: await import('./translations/cs.yml'), + th: await import('./translations/th.yml'), + vi: await import('./translations/vi.yml'), + ms: await import('./translations/ms.yml'), + he: await import('./translations/he.yml'), + ro: await import('./translations/ro.yml'), + el: await import('./translations/el.yml'), + sv: await import('./translations/sv.yml'), + no: await import('./translations/no.yml'), + fi: await import('./translations/fi.yml'), + da: await import('./translations/da.yml'), + hu: await import('./translations/hu.yml'), + lt: await import('./translations/lt.yml'), + bg: await import('./translations/bg.yml'), + sk: await import('./translations/sk.yml'), + hr: await import('./translations/hr.yml'), + lv: await import('./translations/lv.yml'), + et: await import('./translations/et.yml'), + tl: await import('./translations/tl.yml'), + ca: await import('./translations/ca.yml'), + af: await import('./translations/af.yml'), + bn: await import('./translations/bn.yml'), + fa: await import('./translations/fa.yml'), + pa: await import('./translations/pa.yml'), + sw: await import('./translations/sw.yml'), + ta: await import('./translations/ta.yml'), + ur: await import('./translations/ur.yml'), + cy: await import('./translations/cy.yml'), + am: await import('./translations/am.yml'), + hy: await import('./translations/hy.yml'), + az: await import('./translations/az.yml'), + eu: await import('./translations/eu.yml'), + bs: await import('./translations/bs.yml'), + ka: await import('./translations/ka.yml'), + gu: await import('./translations/gu.yml'), + is: await import('./translations/is.yml'), + km: await import('./translations/km.yml'), + ku: await import('./translations/ku.yml'), + lo: await import('./translations/lo.yml'), + lb: await import('./translations/lb.yml'), + mk: await import('./translations/mk.yml'), + mt: await import('./translations/mt.yml'), + mn: await import('./translations/mn.yml'), + ne: await import('./translations/ne.yml'), + ps: await import('./translations/ps.yml'), + sr: await import('./translations/sr.yml'), + si: await import('./translations/si.yml'), + so: await import('./translations/so.yml'), + tg: await import('./translations/tg.yml'), + te: await import('./translations/te.yml'), + uz: await import('./translations/uz.yml'), + yo: await import('./translations/yo.yml'), + zu: await import('./translations/zu.yml'), + }; + + for (const [key, value] of Object.entries(translations)) { + i18n.addResourceBundle(key, 'translation', yaml.load(value.default)); + } +} + +export default i18n; diff --git a/src/apps/seelenweg/i18n/translations/af.yml b/src/apps/seelenweg/i18n/translations/af.yml index 2ff30640..26cf2c2a 100644 --- a/src/apps/seelenweg/i18n/translations/af.yml +++ b/src/apps/seelenweg/i18n/translations/af.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Open instellings - start: Voeg beginmodule by - media: Voeg mediasmodule by -app_menu: - close: Naby - pin: Speld - pin_to_right: Speld na regs - close_multiple: Sluit alles - pin_to_center: Speld na die sentrum - run_as: Hardloop as administrateur - pin_to_left: Speld na links - open_file_location: Oop lêlokasie - copy_handles: Kopiehandvatsels - unpin: Unpin -media_menu: - remove: Verwyder die media -module -start_menu: - remove: Verwyder beginmodule +taskbar_menu: + settings: Open instellings + start: Voeg beginmodule by + media: Voeg mediasmodule by +app_menu: + close: Naby + pin: Speld + pin_to_right: Speld na regs + close_multiple: Sluit alles + pin_to_center: Speld na die sentrum + run_as: Hardloop as administrateur + pin_to_left: Speld na links + open_file_location: Oop lêlokasie + copy_handles: Kopiehandvatsels + unpin: Unpin +media_menu: + remove: Verwyder die media -module +start_menu: + remove: Verwyder beginmodule diff --git a/src/apps/seelenweg/i18n/translations/am.yml b/src/apps/seelenweg/i18n/translations/am.yml index 0282da5f..7f38384a 100644 --- a/src/apps/seelenweg/i18n/translations/am.yml +++ b/src/apps/seelenweg/i18n/translations/am.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: የሚዲያ ሞዱል ያክሉ - settings: ክፍት ቅንብሮች - start: የመነሻ ሞጁል ያክሉ -app_menu: - close: ገጠመ - pin_to_left: ፒን ወደ ግራ - pin_to_right: በቀኝ በኩል ፒን - pin_to_center: ፒን እስከ ማእከል - open_file_location: የፋይል ቦታ ይክፈቱ - pin: ፒን - close_multiple: ሁሉንም ዝጋ - run_as: እንደ አስተዳዳሪ ይሮጡ - copy_handles: መያዣዎች - unpin: እየቀነሰ ይሄዳል -media_menu: - remove: የሚዲያ ሞዱል ያስወግዱ -start_menu: - remove: የጀግንነት ሞዱልን ያስወግዱ +taskbar_menu: + media: የሚዲያ ሞዱል ያክሉ + settings: ክፍት ቅንብሮች + start: የመነሻ ሞጁል ያክሉ +app_menu: + close: ገጠመ + pin_to_left: ፒን ወደ ግራ + pin_to_right: በቀኝ በኩል ፒን + pin_to_center: ፒን እስከ ማእከል + open_file_location: የፋይል ቦታ ይክፈቱ + pin: ፒን + close_multiple: ሁሉንም ዝጋ + run_as: እንደ አስተዳዳሪ ይሮጡ + copy_handles: መያዣዎች + unpin: እየቀነሰ ይሄዳል +media_menu: + remove: የሚዲያ ሞዱል ያስወግዱ +start_menu: + remove: የጀግንነት ሞዱልን ያስወግዱ diff --git a/src/apps/seelenweg/i18n/translations/ar.yml b/src/apps/seelenweg/i18n/translations/ar.yml index c22310de..5ac8ec7a 100644 --- a/src/apps/seelenweg/i18n/translations/ar.yml +++ b/src/apps/seelenweg/i18n/translations/ar.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: إضافة وحدة الوسائط - start: إضافة وحدة البداية - settings: أفتح الإعدادات -app_menu: - unpin: إزالة التثبيت - pin: دبوس - pin_to_left: دبوس إلى اليسار - pin_to_center: تثبيت على المركز - pin_to_right: تثبيت على اليمين - open_file_location: افتح مكان ملف - run_as: تشغيل كمسؤول - copy_handles: مقابض النسخ - close: يغلق - close_multiple: إغلاق الكل -media_menu: - remove: إزالة وحدة الوسائط -start_menu: - remove: إزالة وحدة البداية +taskbar_menu: + media: إضافة وحدة الوسائط + start: إضافة وحدة البداية + settings: أفتح الإعدادات +app_menu: + unpin: إزالة التثبيت + pin: دبوس + pin_to_left: دبوس إلى اليسار + pin_to_center: تثبيت على المركز + pin_to_right: تثبيت على اليمين + open_file_location: افتح مكان ملف + run_as: تشغيل كمسؤول + copy_handles: مقابض النسخ + close: يغلق + close_multiple: إغلاق الكل +media_menu: + remove: إزالة وحدة الوسائط +start_menu: + remove: إزالة وحدة البداية diff --git a/src/apps/seelenweg/i18n/translations/az.yml b/src/apps/seelenweg/i18n/translations/az.yml index d9eb7734..354ea79a 100644 --- a/src/apps/seelenweg/i18n/translations/az.yml +++ b/src/apps/seelenweg/i18n/translations/az.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Media modulu əlavə edin - start: Başlama modulu əlavə edin - settings: Parametrləri açın -app_menu: - close: Yaxın - pin: Pin - pin_to_left: Pin sola - pin_to_center: Mərkəzə pin - copy_handles: Copular - run_as: İdarəçi kimi qaçmaq - open_file_location: Fayl yeri açın - close_multiple: Hamısını bağlayın - unpin: Qeyri-pəncələmək - pin_to_right: Sağa pin -media_menu: - remove: Media modulunu çıxarın -start_menu: - remove: Başlama modulunu çıxarın +taskbar_menu: + media: Media modulu əlavə edin + start: Başlama modulu əlavə edin + settings: Parametrləri açın +app_menu: + close: Yaxın + pin: Pin + pin_to_left: Pin sola + pin_to_center: Mərkəzə pin + copy_handles: Copular + run_as: İdarəçi kimi qaçmaq + open_file_location: Fayl yeri açın + close_multiple: Hamısını bağlayın + unpin: Qeyri-pəncələmək + pin_to_right: Sağa pin +media_menu: + remove: Media modulunu çıxarın +start_menu: + remove: Başlama modulunu çıxarın diff --git a/src/apps/seelenweg/i18n/translations/bg.yml b/src/apps/seelenweg/i18n/translations/bg.yml index 650b2809..08e8c098 100644 --- a/src/apps/seelenweg/i18n/translations/bg.yml +++ b/src/apps/seelenweg/i18n/translations/bg.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Отворени настройки - media: Добавете медиен модул - start: Добавете старт модул -app_menu: - close: Близо - close_multiple: Затвори всички - run_as: Изпълни като администратор - copy_handles: Копиращи дръжки - open_file_location: Отворете местоположението на файла - pin_to_center: Щифт към центъра - pin_to_left: Пин вляво - pin_to_right: Пин вдясно - pin: Щифт - unpin: Unpin -media_menu: - remove: Премахване на медийния модул -start_menu: - remove: Премахване на стартовия модул +taskbar_menu: + settings: Отворени настройки + media: Добавете медиен модул + start: Добавете старт модул +app_menu: + close: Близо + close_multiple: Затвори всички + run_as: Изпълни като администратор + copy_handles: Копиращи дръжки + open_file_location: Отворете местоположението на файла + pin_to_center: Щифт към центъра + pin_to_left: Пин вляво + pin_to_right: Пин вдясно + pin: Щифт + unpin: Unpin +media_menu: + remove: Премахване на медийния модул +start_menu: + remove: Премахване на стартовия модул diff --git a/src/apps/seelenweg/i18n/translations/bn.yml b/src/apps/seelenweg/i18n/translations/bn.yml index 9fa1ecda..ca217ec2 100644 --- a/src/apps/seelenweg/i18n/translations/bn.yml +++ b/src/apps/seelenweg/i18n/translations/bn.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: ওপেন সেটিংস - media: মিডিয়া মডিউল যুক্ত করুন - start: স্টার্ট মডিউল যুক্ত করুন -app_menu: - close_multiple: সব বন্ধ করা - run_as: প্রশাসক হিসাবে চালান - close: বন্ধ - open_file_location: নথির অবস্থান বের করা - pin_to_center: কেন্দ্রে পিন - pin_to_left: বাম দিকে পিন - unpin: আনপিন - pin: পিন - pin_to_right: ডান পিন - copy_handles: হ্যান্ডলগুলি অনুলিপি -media_menu: - remove: মিডিয়া মডিউল সরান -start_menu: - remove: স্টার্ট মডিউল সরান +taskbar_menu: + settings: ওপেন সেটিংস + media: মিডিয়া মডিউল যুক্ত করুন + start: স্টার্ট মডিউল যুক্ত করুন +app_menu: + close_multiple: সব বন্ধ করা + run_as: প্রশাসক হিসাবে চালান + close: বন্ধ + open_file_location: নথির অবস্থান বের করা + pin_to_center: কেন্দ্রে পিন + pin_to_left: বাম দিকে পিন + unpin: আনপিন + pin: পিন + pin_to_right: ডান পিন + copy_handles: হ্যান্ডলগুলি অনুলিপি +media_menu: + remove: মিডিয়া মডিউল সরান +start_menu: + remove: স্টার্ট মডিউল সরান diff --git a/src/apps/seelenweg/i18n/translations/bs.yml b/src/apps/seelenweg/i18n/translations/bs.yml index d799abb3..1e708ff0 100644 --- a/src/apps/seelenweg/i18n/translations/bs.yml +++ b/src/apps/seelenweg/i18n/translations/bs.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Otvorite postavke - media: Dodajte medijski modul - start: Dodajte početni modul -app_menu: - close: Zatvoriti - open_file_location: Otvorite lokaciju datoteke - run_as: Trčite kao administrator - pin_to_left: Pin na lijevo - close_multiple: Zatvoriti sve - unpin: Otrcati - copy_handles: Ručke za kopiranje - pin_to_center: Pin za centar - pin_to_right: Pin na desno - pin: Pin -media_menu: - remove: Uklonite medijski modul -start_menu: - remove: Uklonite početni modul +taskbar_menu: + settings: Otvorite postavke + media: Dodajte medijski modul + start: Dodajte početni modul +app_menu: + close: Zatvoriti + open_file_location: Otvorite lokaciju datoteke + run_as: Trčite kao administrator + pin_to_left: Pin na lijevo + close_multiple: Zatvoriti sve + unpin: Otrcati + copy_handles: Ručke za kopiranje + pin_to_center: Pin za centar + pin_to_right: Pin na desno + pin: Pin +media_menu: + remove: Uklonite medijski modul +start_menu: + remove: Uklonite početni modul diff --git a/src/apps/seelenweg/i18n/translations/ca.yml b/src/apps/seelenweg/i18n/translations/ca.yml index 54427fb6..11168ec7 100644 --- a/src/apps/seelenweg/i18n/translations/ca.yml +++ b/src/apps/seelenweg/i18n/translations/ca.yml @@ -1,19 +1,19 @@ -taskbar_menu: - start: Afegiu el mòdul d'inici - settings: Configuració oberta - media: Afegiu el mòdul de suports -app_menu: - pin_to_left: Pin a l’esquerra - close: Tanca - run_as: Executa com administrador - pin: Agulla - close_multiple: Tanca tot - open_file_location: Obriu la ubicació del fitxer - pin_to_right: Pin a la dreta - pin_to_center: Pin al centre - copy_handles: Manelles de còpia - unpin: Desfeta -media_menu: - remove: Elimina el mòdul de suports -start_menu: - remove: Elimina el mòdul d'inici +taskbar_menu: + start: Afegiu el mòdul d'inici + settings: Configuració oberta + media: Afegiu el mòdul de suports +app_menu: + pin_to_left: Pin a l’esquerra + close: Tanca + run_as: Executa com administrador + pin: Agulla + close_multiple: Tanca tot + open_file_location: Obriu la ubicació del fitxer + pin_to_right: Pin a la dreta + pin_to_center: Pin al centre + copy_handles: Manelles de còpia + unpin: Desfeta +media_menu: + remove: Elimina el mòdul de suports +start_menu: + remove: Elimina el mòdul d'inici diff --git a/src/apps/seelenweg/i18n/translations/cs.yml b/src/apps/seelenweg/i18n/translations/cs.yml index f0eced09..9db0aa30 100644 --- a/src/apps/seelenweg/i18n/translations/cs.yml +++ b/src/apps/seelenweg/i18n/translations/cs.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Otevřené nastavení - media: Přidat mediální modul - start: Přidat startovací modul -app_menu: - pin: Kolík - pin_to_center: Pin do středu - open_file_location: Otevřít umístění souboru - close_multiple: Zavřete všechny - run_as: Spustit jako administrátor - close: Zavřít - copy_handles: Kopírovat úchyty - pin_to_right: Pin doprava - unpin: Unlin - pin_to_left: Pin doleva -media_menu: - remove: Odebrat mediální modul -start_menu: - remove: Odstraňte startovací modul +taskbar_menu: + settings: Otevřené nastavení + media: Přidat mediální modul + start: Přidat startovací modul +app_menu: + pin: Kolík + pin_to_center: Pin do středu + open_file_location: Otevřít umístění souboru + close_multiple: Zavřete všechny + run_as: Spustit jako administrátor + close: Zavřít + copy_handles: Kopírovat úchyty + pin_to_right: Pin doprava + unpin: Unlin + pin_to_left: Pin doleva +media_menu: + remove: Odebrat mediální modul +start_menu: + remove: Odstraňte startovací modul diff --git a/src/apps/seelenweg/i18n/translations/cy.yml b/src/apps/seelenweg/i18n/translations/cy.yml index f54f582f..6857d5ef 100644 --- a/src/apps/seelenweg/i18n/translations/cy.yml +++ b/src/apps/seelenweg/i18n/translations/cy.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Gosodiadau Agored - media: Ychwanegu Modiwl Cyfryngau - start: Ychwanegu Modiwl Start -app_menu: - copy_handles: Dolenni copi - pin_to_center: Pin i'r canol - pin_to_left: Pin i'r chwith - run_as: Rhedeg fel Gweinyddwr - close_multiple: Cau popeth - unpin: Dadleuon - open_file_location: Lleoliad Ffeil Agored - close: Chaewch - pin_to_right: Pin i'r dde - pin: Piniff -media_menu: - remove: Dileu Modiwl Cyfryngau -start_menu: - remove: Tynnwch y modiwl cychwyn +taskbar_menu: + settings: Gosodiadau Agored + media: Ychwanegu Modiwl Cyfryngau + start: Ychwanegu Modiwl Start +app_menu: + copy_handles: Dolenni copi + pin_to_center: Pin i'r canol + pin_to_left: Pin i'r chwith + run_as: Rhedeg fel Gweinyddwr + close_multiple: Cau popeth + unpin: Dadleuon + open_file_location: Lleoliad Ffeil Agored + close: Chaewch + pin_to_right: Pin i'r dde + pin: Piniff +media_menu: + remove: Dileu Modiwl Cyfryngau +start_menu: + remove: Tynnwch y modiwl cychwyn diff --git a/src/apps/seelenweg/i18n/translations/da.yml b/src/apps/seelenweg/i18n/translations/da.yml index 650dc74f..21b56db7 100644 --- a/src/apps/seelenweg/i18n/translations/da.yml +++ b/src/apps/seelenweg/i18n/translations/da.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Åbne indstillinger - media: Tilføj mediemodul - start: Tilføj startmodul -app_menu: - pin_to_center: Stift til centrum - open_file_location: Åbn filplacering - close_multiple: Luk alt - copy_handles: Kopier håndtag - unpin: Unpin - pin: Pin - close: Tæt - pin_to_left: Pin til venstre - pin_to_right: Pin til højre - run_as: Kør som administrator -media_menu: - remove: Fjern mediemodulet -start_menu: - remove: Fjern startmodulet +taskbar_menu: + settings: Åbne indstillinger + media: Tilføj mediemodul + start: Tilføj startmodul +app_menu: + pin_to_center: Stift til centrum + open_file_location: Åbn filplacering + close_multiple: Luk alt + copy_handles: Kopier håndtag + unpin: Unpin + pin: Pin + close: Tæt + pin_to_left: Pin til venstre + pin_to_right: Pin til højre + run_as: Kør som administrator +media_menu: + remove: Fjern mediemodulet +start_menu: + remove: Fjern startmodulet diff --git a/src/apps/seelenweg/i18n/translations/de.yml b/src/apps/seelenweg/i18n/translations/de.yml index 1d83bb99..a82c4ead 100644 --- a/src/apps/seelenweg/i18n/translations/de.yml +++ b/src/apps/seelenweg/i18n/translations/de.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Medienmodul hinzufügen - start: Startmodul hinzufügen - settings: Einstellungen öffnen -app_menu: - unpin: Lösen - pin: Anheften - pin_to_left: Links anheften - pin_to_center: Zentral anheften - pin_to_right: Rechts anheften - open_file_location: Dateispeicherort öffnen - run_as: Als Administrator ausführen - copy_handles: Handles kopieren - close: Schließen - close_multiple: Alle schließen -media_menu: - remove: Medienmodul entfernen -start_menu: - remove: Startmodul entfernen +taskbar_menu: + media: Medienmodul hinzufügen + start: Startmodul hinzufügen + settings: Einstellungen öffnen +app_menu: + unpin: Lösen + pin: Anheften + pin_to_left: Links anheften + pin_to_center: Zentral anheften + pin_to_right: Rechts anheften + open_file_location: Dateispeicherort öffnen + run_as: Als Administrator ausführen + copy_handles: Handles kopieren + close: Schließen + close_multiple: Alle schließen +media_menu: + remove: Medienmodul entfernen +start_menu: + remove: Startmodul entfernen diff --git a/src/apps/seelenweg/i18n/translations/el.yml b/src/apps/seelenweg/i18n/translations/el.yml index 68e57bd1..5611ec8a 100644 --- a/src/apps/seelenweg/i18n/translations/el.yml +++ b/src/apps/seelenweg/i18n/translations/el.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Ανοίξτε τις ρυθμίσεις - media: Προσθήκη ενότητας μέσων - start: Προσθήκη μονάδας εκκίνησης -app_menu: - close_multiple: Κλείσ'τα όλα - close: Κλείσε - pin: Καρφίτσα - unpin: Ξεκαρφιτσώνω - pin_to_right: Pin προς τα δεξιά - copy_handles: Λαβές αντιγράφων - pin_to_center: Καρφίτσα στο κέντρο - run_as: Εκτελέστε ως διαχειριστής - open_file_location: Ανοίξτε την τοποθεσία αρχείου - pin_to_left: Καρφίτσα στα αριστερά -media_menu: - remove: Αφαιρέστε τη μονάδα μέσων -start_menu: - remove: Αφαιρέστε την ενότητα εκκίνησης +taskbar_menu: + settings: Ανοίξτε τις ρυθμίσεις + media: Προσθήκη ενότητας μέσων + start: Προσθήκη μονάδας εκκίνησης +app_menu: + close_multiple: Κλείσ'τα όλα + close: Κλείσε + pin: Καρφίτσα + unpin: Ξεκαρφιτσώνω + pin_to_right: Pin προς τα δεξιά + copy_handles: Λαβές αντιγράφων + pin_to_center: Καρφίτσα στο κέντρο + run_as: Εκτελέστε ως διαχειριστής + open_file_location: Ανοίξτε την τοποθεσία αρχείου + pin_to_left: Καρφίτσα στα αριστερά +media_menu: + remove: Αφαιρέστε τη μονάδα μέσων +start_menu: + remove: Αφαιρέστε την ενότητα εκκίνησης diff --git a/src/apps/seelenweg/i18n/translations/en.yml b/src/apps/seelenweg/i18n/translations/en.yml index d29a7a1c..05241298 100644 --- a/src/apps/seelenweg/i18n/translations/en.yml +++ b/src/apps/seelenweg/i18n/translations/en.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Add Media Module - start: Add Start Module - settings: Open Settings -app_menu: - unpin: Unpin - pin: Pin - pin_to_left: Pin to Left - pin_to_center: Pin to Center - pin_to_right: Pin to Right - open_file_location: Open File Location - run_as: Run as Administrator - copy_handles: Copy Handles - close: Close - close_multiple: Close All -media_menu: - remove: Remove Media Module -start_menu: +taskbar_menu: + media: Add Media Module + start: Add Start Module + settings: Open Settings +app_menu: + unpin: Unpin + pin: Pin + pin_to_left: Pin to Left + pin_to_center: Pin to Center + pin_to_right: Pin to Right + open_file_location: Open File Location + run_as: Run as Administrator + copy_handles: Copy Handles + close: Close + close_multiple: Close All +media_menu: + remove: Remove Media Module +start_menu: remove: Remove Start Module \ No newline at end of file diff --git a/src/apps/seelenweg/i18n/translations/es.yml b/src/apps/seelenweg/i18n/translations/es.yml index 2ae70925..f45d2cac 100644 --- a/src/apps/seelenweg/i18n/translations/es.yml +++ b/src/apps/seelenweg/i18n/translations/es.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Añadir módulo de medios - start: Añadir módulo de inicio - settings: Abrir configuraciones -app_menu: - unpin: Desanclar - pin: Anclar - pin_to_left: Anclar a la izquierda - pin_to_center: Anclar al centro - pin_to_right: Anclar a la derecha - open_file_location: Abrir ubicación del archivo - run_as: Ejecutar como administrador - copy_handles: Copiar identificadores - close: Cerrar - close_multiple: Cerrar todo -media_menu: - remove: Eliminar módulo de medios -start_menu: - remove: Eliminar módulo de inicio +taskbar_menu: + media: Añadir módulo de medios + start: Añadir módulo de inicio + settings: Abrir configuraciones +app_menu: + unpin: Desanclar + pin: Anclar + pin_to_left: Anclar a la izquierda + pin_to_center: Anclar al centro + pin_to_right: Anclar a la derecha + open_file_location: Abrir ubicación del archivo + run_as: Ejecutar como administrador + copy_handles: Copiar identificadores + close: Cerrar + close_multiple: Cerrar todo +media_menu: + remove: Eliminar módulo de medios +start_menu: + remove: Eliminar módulo de inicio diff --git a/src/apps/seelenweg/i18n/translations/et.yml b/src/apps/seelenweg/i18n/translations/et.yml index 5aec21c0..752a7453 100644 --- a/src/apps/seelenweg/i18n/translations/et.yml +++ b/src/apps/seelenweg/i18n/translations/et.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Avatud sätted - start: Lisage käivitusmoodul - media: Lisage meediumimoodul -app_menu: - pin_to_center: Tihvt keskele - close: Sulge - pin: Nööpnõel - close_multiple: Sulgege kõik - open_file_location: Ava faili asukoht - unpin: Lahti keelama - pin_to_left: Tihvt vasakule - pin_to_right: Tihvt paremal - run_as: Joosta administraatorina - copy_handles: Koopiakäepidemed -media_menu: - remove: Eemaldage meediumimoodul -start_menu: - remove: Eemaldage algusmoodul +taskbar_menu: + settings: Avatud sätted + start: Lisage käivitusmoodul + media: Lisage meediumimoodul +app_menu: + pin_to_center: Tihvt keskele + close: Sulge + pin: Nööpnõel + close_multiple: Sulgege kõik + open_file_location: Ava faili asukoht + unpin: Lahti keelama + pin_to_left: Tihvt vasakule + pin_to_right: Tihvt paremal + run_as: Joosta administraatorina + copy_handles: Koopiakäepidemed +media_menu: + remove: Eemaldage meediumimoodul +start_menu: + remove: Eemaldage algusmoodul diff --git a/src/apps/seelenweg/i18n/translations/eu.yml b/src/apps/seelenweg/i18n/translations/eu.yml index 15eabc3c..d669d9db 100644 --- a/src/apps/seelenweg/i18n/translations/eu.yml +++ b/src/apps/seelenweg/i18n/translations/eu.yml @@ -1,19 +1,19 @@ -taskbar_menu: - start: Gehitu abiapuntu modulua - settings: Ezarpenak irekitzea - media: Gehitu multimedia modulua -app_menu: - pin: Iskilinba - close_multiple: Itxi guztiak - unpin: Desjendu - close: Hurbileko - pin_to_left: Ezkerrera - pin_to_center: Pin zentrora - copy_handles: Kopiatu heldulekuak - run_as: Exekutatu administratzaile gisa - open_file_location: Ireki fitxategiaren kokapena - pin_to_right: PIN eskuin -media_menu: - remove: Kendu multimedia modulua -start_menu: - remove: Kendu hasierako modulua +taskbar_menu: + start: Gehitu abiapuntu modulua + settings: Ezarpenak irekitzea + media: Gehitu multimedia modulua +app_menu: + pin: Iskilinba + close_multiple: Itxi guztiak + unpin: Desjendu + close: Hurbileko + pin_to_left: Ezkerrera + pin_to_center: Pin zentrora + copy_handles: Kopiatu heldulekuak + run_as: Exekutatu administratzaile gisa + open_file_location: Ireki fitxategiaren kokapena + pin_to_right: PIN eskuin +media_menu: + remove: Kendu multimedia modulua +start_menu: + remove: Kendu hasierako modulua diff --git a/src/apps/seelenweg/i18n/translations/fa.yml b/src/apps/seelenweg/i18n/translations/fa.yml index 771dcee4..14684c13 100644 --- a/src/apps/seelenweg/i18n/translations/fa.yml +++ b/src/apps/seelenweg/i18n/translations/fa.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: تنظیمات باز - media: ماژول رسانه را اضافه کنید - start: ماژول شروع را اضافه کنید -app_menu: - pin: پین کردن - close: بستن - unpin: باز کردن - pin_to_center: پین به مرکز - pin_to_left: پین به سمت چپ - copy_handles: دسته کپی کردن - open_file_location: مکان فایل را باز کنید - pin_to_right: پین به راست - close_multiple: همه را ببندید - run_as: به عنوان مدیر اجرا کنید -media_menu: - remove: ماژول رسانه را حذف کنید -start_menu: - remove: ماژول شروع را حذف کنید +taskbar_menu: + settings: تنظیمات باز + media: ماژول رسانه را اضافه کنید + start: ماژول شروع را اضافه کنید +app_menu: + pin: پین کردن + close: بستن + unpin: باز کردن + pin_to_center: پین به مرکز + pin_to_left: پین به سمت چپ + copy_handles: دسته کپی کردن + open_file_location: مکان فایل را باز کنید + pin_to_right: پین به راست + close_multiple: همه را ببندید + run_as: به عنوان مدیر اجرا کنید +media_menu: + remove: ماژول رسانه را حذف کنید +start_menu: + remove: ماژول شروع را حذف کنید diff --git a/src/apps/seelenweg/i18n/translations/fi.yml b/src/apps/seelenweg/i18n/translations/fi.yml index f7e3675a..9973f71b 100644 --- a/src/apps/seelenweg/i18n/translations/fi.yml +++ b/src/apps/seelenweg/i18n/translations/fi.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Avaa asetukset - start: Lisää aloitusmoduuli - media: Lisää mediamoduuli -app_menu: - close_multiple: Sulje kaikki - run_as: Suorita järjestelmänvalvojana - close: kiinni - open_file_location: Avaa tiedoston sijainti - pin_to_right: Pistä oikealle - copy_handles: Kopiokahvat - pin: Nasta - pin_to_center: Pintää keskustaan - pin_to_left: Vasemmalle - unpin: Purkaa -media_menu: - remove: Poista mediamoduuli -start_menu: - remove: Poista Start -moduuli +taskbar_menu: + settings: Avaa asetukset + start: Lisää aloitusmoduuli + media: Lisää mediamoduuli +app_menu: + close_multiple: Sulje kaikki + run_as: Suorita järjestelmänvalvojana + close: kiinni + open_file_location: Avaa tiedoston sijainti + pin_to_right: Pistä oikealle + copy_handles: Kopiokahvat + pin: Nasta + pin_to_center: Pintää keskustaan + pin_to_left: Vasemmalle + unpin: Purkaa +media_menu: + remove: Poista mediamoduuli +start_menu: + remove: Poista Start -moduuli diff --git a/src/apps/seelenweg/i18n/translations/fr.yml b/src/apps/seelenweg/i18n/translations/fr.yml index 3151eb4c..4b3cdc72 100644 --- a/src/apps/seelenweg/i18n/translations/fr.yml +++ b/src/apps/seelenweg/i18n/translations/fr.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Ajouter un module multimédia - start: Ajouter un module de démarrage - settings: Ouvrir les paramètres -app_menu: - unpin: Détacher - pin: Épingle - pin_to_left: Épingler à gauche - pin_to_center: Épingler au centre - pin_to_right: Épingler à droite - open_file_location: Lieu de fichier ouvert - run_as: Exécuter en tant qu'administrateur - copy_handles: Poignées de copie - close: Fermer - close_multiple: Ferme tout -media_menu: - remove: Supprimer le module multimédia -start_menu: - remove: Supprimer le module de démarrage +taskbar_menu: + media: Ajouter un module multimédia + start: Ajouter un module de démarrage + settings: Ouvrir les paramètres +app_menu: + unpin: Détacher + pin: Épingle + pin_to_left: Épingler à gauche + pin_to_center: Épingler au centre + pin_to_right: Épingler à droite + open_file_location: Lieu de fichier ouvert + run_as: Exécuter en tant qu'administrateur + copy_handles: Poignées de copie + close: Fermer + close_multiple: Ferme tout +media_menu: + remove: Supprimer le module multimédia +start_menu: + remove: Supprimer le module de démarrage diff --git a/src/apps/seelenweg/i18n/translations/gu.yml b/src/apps/seelenweg/i18n/translations/gu.yml index 33a2893f..e49d6961 100644 --- a/src/apps/seelenweg/i18n/translations/gu.yml +++ b/src/apps/seelenweg/i18n/translations/gu.yml @@ -1,19 +1,19 @@ -taskbar_menu: - start: પ્રારંભ મોડ્યુલ ઉમેરો - settings: ખુલ્લી સેટિંગ્સ - media: મીડિયા મોડ્યુલ ઉમેરો -app_menu: - close: બંધ - pin_to_center: કેન્દ્રથી પિનથી કેન્દ્રમાં - pin_to_left: ડાબી બાજુ - run_as: વહીવટકર્તા તરીકે ચલાવો - copy_handles: નકલ - close_multiple: બંધ કરવું - pin_to_right: જમણી બાજુ - unpin: ખોળવું - open_file_location: ફાઇલ સ્થાન ખોલો - pin: પિન -media_menu: - remove: મીડિયા મોડ્યુલ દૂર કરો -start_menu: - remove: પ્રારંભ મોડ્યુલ દૂર કરો +taskbar_menu: + start: પ્રારંભ મોડ્યુલ ઉમેરો + settings: ખુલ્લી સેટિંગ્સ + media: મીડિયા મોડ્યુલ ઉમેરો +app_menu: + close: બંધ + pin_to_center: કેન્દ્રથી પિનથી કેન્દ્રમાં + pin_to_left: ડાબી બાજુ + run_as: વહીવટકર્તા તરીકે ચલાવો + copy_handles: નકલ + close_multiple: બંધ કરવું + pin_to_right: જમણી બાજુ + unpin: ખોળવું + open_file_location: ફાઇલ સ્થાન ખોલો + pin: પિન +media_menu: + remove: મીડિયા મોડ્યુલ દૂર કરો +start_menu: + remove: પ્રારંભ મોડ્યુલ દૂર કરો diff --git a/src/apps/seelenweg/i18n/translations/he.yml b/src/apps/seelenweg/i18n/translations/he.yml index 8b2b7925..98054648 100644 --- a/src/apps/seelenweg/i18n/translations/he.yml +++ b/src/apps/seelenweg/i18n/translations/he.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: פתח הגדרות - media: הוסף מודול מדיה - start: הוסף מודול התחל -app_menu: - run_as: הפעל כמנהל - pin: פִּין - close_multiple: סגור הכל - close: סגור - unpin: לְהוֹצִיא סִיכָּה - pin_to_center: סיכה למרכז - open_file_location: פתח את מיקום הקובץ - copy_handles: העתק ידיות - pin_to_right: סיכה לימין - pin_to_left: סיכה משמאל -media_menu: - remove: הסר את מודול המדיה -start_menu: - remove: הסר את מודול ההתחלה +taskbar_menu: + settings: פתח הגדרות + media: הוסף מודול מדיה + start: הוסף מודול התחל +app_menu: + run_as: הפעל כמנהל + pin: פִּין + close_multiple: סגור הכל + close: סגור + unpin: לְהוֹצִיא סִיכָּה + pin_to_center: סיכה למרכז + open_file_location: פתח את מיקום הקובץ + copy_handles: העתק ידיות + pin_to_right: סיכה לימין + pin_to_left: סיכה משמאל +media_menu: + remove: הסר את מודול המדיה +start_menu: + remove: הסר את מודול ההתחלה diff --git a/src/apps/seelenweg/i18n/translations/hi.yml b/src/apps/seelenweg/i18n/translations/hi.yml index 5289a0a9..1eecc607 100644 --- a/src/apps/seelenweg/i18n/translations/hi.yml +++ b/src/apps/seelenweg/i18n/translations/hi.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: खुली सेटिंग - media: मीडिया मॉड्यूल जोड़ें - start: स्टार्ट मॉड्यूल जोड़ें -app_menu: - close_multiple: सब बंद करें - pin_to_right: दाईं ओर पिन करना - pin_to_center: केंद्र को पिन करना - pin_to_left: बाईं ओर पिन - close: बंद करना - run_as: व्यवस्थापक के रूप में चलाएं - open_file_location: फ़ाइल के स्थान को खोलें - copy_handles: कॉपी हैंडल - unpin: अनपिन - pin: नत्थी करना -media_menu: - remove: मीडिया मॉड्यूल निकालें -start_menu: - remove: प्रारंभ मॉड्यूल निकालें +taskbar_menu: + settings: खुली सेटिंग + media: मीडिया मॉड्यूल जोड़ें + start: स्टार्ट मॉड्यूल जोड़ें +app_menu: + close_multiple: सब बंद करें + pin_to_right: दाईं ओर पिन करना + pin_to_center: केंद्र को पिन करना + pin_to_left: बाईं ओर पिन + close: बंद करना + run_as: व्यवस्थापक के रूप में चलाएं + open_file_location: फ़ाइल के स्थान को खोलें + copy_handles: कॉपी हैंडल + unpin: अनपिन + pin: नत्थी करना +media_menu: + remove: मीडिया मॉड्यूल निकालें +start_menu: + remove: प्रारंभ मॉड्यूल निकालें diff --git a/src/apps/seelenweg/i18n/translations/hr.yml b/src/apps/seelenweg/i18n/translations/hr.yml index dad728b7..278e93ce 100644 --- a/src/apps/seelenweg/i18n/translations/hr.yml +++ b/src/apps/seelenweg/i18n/translations/hr.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Otvorene postavke - media: Dodajte medijski modul - start: Dodajte modul za start -app_menu: - copy_handles: Ručke za kopiranje - close: Zatvoriti - pin_to_left: PIN ulijevo - run_as: Pokreni kao administrator - pin_to_right: PIN na desno - pin: Pričvrstiti - pin_to_center: Pin do centra - open_file_location: Otvorena lokacija datoteke - unpin: Raskoš - close_multiple: Zatvori sve -media_menu: - remove: Uklonite medijski modul -start_menu: - remove: Uklonite modul Start +taskbar_menu: + settings: Otvorene postavke + media: Dodajte medijski modul + start: Dodajte modul za start +app_menu: + copy_handles: Ručke za kopiranje + close: Zatvoriti + pin_to_left: PIN ulijevo + run_as: Pokreni kao administrator + pin_to_right: PIN na desno + pin: Pričvrstiti + pin_to_center: Pin do centra + open_file_location: Otvorena lokacija datoteke + unpin: Raskoš + close_multiple: Zatvori sve +media_menu: + remove: Uklonite medijski modul +start_menu: + remove: Uklonite modul Start diff --git a/src/apps/seelenweg/i18n/translations/hu.yml b/src/apps/seelenweg/i18n/translations/hu.yml index 3791d077..6982b743 100644 --- a/src/apps/seelenweg/i18n/translations/hu.yml +++ b/src/apps/seelenweg/i18n/translations/hu.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Adjon hozzá média modult - settings: Nyisd meg a beállításokat - start: Adja hozzá a Start modult -app_menu: - pin_to_right: Pin jobbra - unpin: Kibont - run_as: Futtatás rendszergazdaként - pin: Csap - close: Bezárás - close_multiple: Zárja be az összeset - pin_to_left: Pin balra - pin_to_center: Pin a középpontba - open_file_location: Nyissa meg a fájl helyét - copy_handles: Másolás fogantyúk -media_menu: - remove: Távolítsa el a média modult -start_menu: - remove: Távolítsa el a Start modult +taskbar_menu: + media: Adjon hozzá média modult + settings: Nyisd meg a beállításokat + start: Adja hozzá a Start modult +app_menu: + pin_to_right: Pin jobbra + unpin: Kibont + run_as: Futtatás rendszergazdaként + pin: Csap + close: Bezárás + close_multiple: Zárja be az összeset + pin_to_left: Pin balra + pin_to_center: Pin a középpontba + open_file_location: Nyissa meg a fájl helyét + copy_handles: Másolás fogantyúk +media_menu: + remove: Távolítsa el a média modult +start_menu: + remove: Távolítsa el a Start modult diff --git a/src/apps/seelenweg/i18n/translations/hy.yml b/src/apps/seelenweg/i18n/translations/hy.yml index e9546f03..2d1a10ec 100644 --- a/src/apps/seelenweg/i18n/translations/hy.yml +++ b/src/apps/seelenweg/i18n/translations/hy.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Ավելացնել մեդիա մոդուլ - settings: Բաց պարամետրեր - start: Ավելացնել Սկսել մոդուլը -app_menu: - close: փակել - pin_to_center: Քորոց դեպի կենտրոն - pin_to_left: PIN- ը ձախից - open_file_location: Բաց ֆայլի գտնվելու վայրը - copy_handles: Պատճենել բռնակներ - pin_to_right: Քորոց աջից - pin: Թոշակ - unpin: Անապաղում - close_multiple: Փակել բոլորը - run_as: Գործարկել որպես ադմինիստրատոր -media_menu: - remove: Հեռացրեք մեդիա մոդուլը -start_menu: - remove: Հեռացրեք Սկսել մոդուլը +taskbar_menu: + media: Ավելացնել մեդիա մոդուլ + settings: Բաց պարամետրեր + start: Ավելացնել Սկսել մոդուլը +app_menu: + close: փակել + pin_to_center: Քորոց դեպի կենտրոն + pin_to_left: PIN- ը ձախից + open_file_location: Բաց ֆայլի գտնվելու վայրը + copy_handles: Պատճենել բռնակներ + pin_to_right: Քորոց աջից + pin: Թոշակ + unpin: Անապաղում + close_multiple: Փակել բոլորը + run_as: Գործարկել որպես ադմինիստրատոր +media_menu: + remove: Հեռացրեք մեդիա մոդուլը +start_menu: + remove: Հեռացրեք Սկսել մոդուլը diff --git a/src/apps/seelenweg/i18n/translations/id.yml b/src/apps/seelenweg/i18n/translations/id.yml index 8467da42..91e4c3a1 100644 --- a/src/apps/seelenweg/i18n/translations/id.yml +++ b/src/apps/seelenweg/i18n/translations/id.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Tambahkan modul media - start: Tambahkan modul Mulai - settings: Buka Pengaturan -app_menu: - pin_to_center: Pin ke tengah - open_file_location: Buka Lokasi File - close_multiple: Tutup semua - run_as: Jalankan sebagai administrator - pin_to_right: Pin ke kanan - pin: Pin - pin_to_left: Pin ke kiri - close: Menutup - unpin: Membuka peniti - copy_handles: Pegangan Salin -media_menu: - remove: Hapus Modul Media -start_menu: - remove: Hapus modul Mulai +taskbar_menu: + media: Tambahkan modul media + start: Tambahkan modul Mulai + settings: Buka Pengaturan +app_menu: + pin_to_center: Pin ke tengah + open_file_location: Buka Lokasi File + close_multiple: Tutup semua + run_as: Jalankan sebagai administrator + pin_to_right: Pin ke kanan + pin: Pin + pin_to_left: Pin ke kiri + close: Menutup + unpin: Membuka peniti + copy_handles: Pegangan Salin +media_menu: + remove: Hapus Modul Media +start_menu: + remove: Hapus modul Mulai diff --git a/src/apps/seelenweg/i18n/translations/is.yml b/src/apps/seelenweg/i18n/translations/is.yml index 1530ecc1..ecc1b69c 100644 --- a/src/apps/seelenweg/i18n/translations/is.yml +++ b/src/apps/seelenweg/i18n/translations/is.yml @@ -1,19 +1,19 @@ -taskbar_menu: - start: Bættu við Start Module - media: Bættu við Media Module - settings: Opnar stillingar -app_menu: - pin_to_left: Pinna til vinstri - pin_to_center: Pinna í miðju - run_as: Hlaupa sem stjórnandi - close_multiple: Lokaðu öllu - close: Lokaðu - unpin: Taka úr - copy_handles: Afrit handföng - open_file_location: Opnaðu staðsetningu skráar - pin: PIN - pin_to_right: Pinna til hægri -media_menu: - remove: Fjarlægðu miðlunareininguna -start_menu: - remove: Fjarlægðu upphafseininguna +taskbar_menu: + start: Bættu við Start Module + media: Bættu við Media Module + settings: Opnar stillingar +app_menu: + pin_to_left: Pinna til vinstri + pin_to_center: Pinna í miðju + run_as: Hlaupa sem stjórnandi + close_multiple: Lokaðu öllu + close: Lokaðu + unpin: Taka úr + copy_handles: Afrit handföng + open_file_location: Opnaðu staðsetningu skráar + pin: PIN + pin_to_right: Pinna til hægri +media_menu: + remove: Fjarlægðu miðlunareininguna +start_menu: + remove: Fjarlægðu upphafseininguna diff --git a/src/apps/seelenweg/i18n/translations/it.yml b/src/apps/seelenweg/i18n/translations/it.yml index be7aca3f..abadcf74 100644 --- a/src/apps/seelenweg/i18n/translations/it.yml +++ b/src/apps/seelenweg/i18n/translations/it.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Impostazioni aperte - start: Aggiungi il modulo Start - media: Aggiungi il modulo multimediale -app_menu: - copy_handles: Copia maniglie - pin_to_center: Pin al centro - close_multiple: Chiudi tutto - open_file_location: Aprire la destinazione del file - pin: Spillo - unpin: Unpin - run_as: Esegui come amministratore - pin_to_right: Pin a destra - pin_to_left: Pin a sinistra - close: Vicina -media_menu: - remove: Rimuovere il modulo multimediale -start_menu: - remove: Rimuovi il modulo Start +taskbar_menu: + settings: Impostazioni aperte + start: Aggiungi il modulo Start + media: Aggiungi il modulo multimediale +app_menu: + copy_handles: Copia maniglie + pin_to_center: Pin al centro + close_multiple: Chiudi tutto + open_file_location: Aprire la destinazione del file + pin: Spillo + unpin: Unpin + run_as: Esegui come amministratore + pin_to_right: Pin a destra + pin_to_left: Pin a sinistra + close: Vicina +media_menu: + remove: Rimuovere il modulo multimediale +start_menu: + remove: Rimuovi il modulo Start diff --git a/src/apps/seelenweg/i18n/translations/ja.yml b/src/apps/seelenweg/i18n/translations/ja.yml index f4217313..f3a77923 100644 --- a/src/apps/seelenweg/i18n/translations/ja.yml +++ b/src/apps/seelenweg/i18n/translations/ja.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: 設定を開く - media: メディアモジュールを追加します - start: 開始モジュールを追加します -app_menu: - pin: ピン - open_file_location: 開いているファイルの場所 - close: 近い - run_as: 管理者として実行 - pin_to_center: 中央にピン - pin_to_right: 右にピン - close_multiple: すべてを閉じます - unpin: unepin - copy_handles: ハンドルをコピーします - pin_to_left: 左にピン -media_menu: - remove: メディアモジュールを削除します -start_menu: - remove: 開始モジュールを削除します +taskbar_menu: + settings: 設定を開く + media: メディアモジュールを追加します + start: 開始モジュールを追加します +app_menu: + pin: ピン + open_file_location: 開いているファイルの場所 + close: 近い + run_as: 管理者として実行 + pin_to_center: 中央にピン + pin_to_right: 右にピン + close_multiple: すべてを閉じます + unpin: unepin + copy_handles: ハンドルをコピーします + pin_to_left: 左にピン +media_menu: + remove: メディアモジュールを削除します +start_menu: + remove: 開始モジュールを削除します diff --git a/src/apps/seelenweg/i18n/translations/ka.yml b/src/apps/seelenweg/i18n/translations/ka.yml index d4bc1dee..05d38f1c 100644 --- a/src/apps/seelenweg/i18n/translations/ka.yml +++ b/src/apps/seelenweg/i18n/translations/ka.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: ღია პარამეტრები - media: დაამატეთ მედია მოდული - start: დაამატეთ დაწყების მოდული -app_menu: - run_as: Ადმინისტრატორის სახელით გაშვება - close_multiple: Დახურე ყველა - close: ახლო - pin_to_center: Pin to Center - open_file_location: გახსენით ფაილის ადგილმდებარეობა - copy_handles: ასლის სახელურები - pin_to_left: პინი მარცხნივ - pin_to_right: Pin მარჯვნივ - unpin: გაუქმება - pin: ქინძისთავი -media_menu: - remove: წაშალეთ მედია მოდული -start_menu: - remove: წაშალეთ დაწყების მოდული +taskbar_menu: + settings: ღია პარამეტრები + media: დაამატეთ მედია მოდული + start: დაამატეთ დაწყების მოდული +app_menu: + run_as: Ადმინისტრატორის სახელით გაშვება + close_multiple: Დახურე ყველა + close: ახლო + pin_to_center: Pin to Center + open_file_location: გახსენით ფაილის ადგილმდებარეობა + copy_handles: ასლის სახელურები + pin_to_left: პინი მარცხნივ + pin_to_right: Pin მარჯვნივ + unpin: გაუქმება + pin: ქინძისთავი +media_menu: + remove: წაშალეთ მედია მოდული +start_menu: + remove: წაშალეთ დაწყების მოდული diff --git a/src/apps/seelenweg/i18n/translations/km.yml b/src/apps/seelenweg/i18n/translations/km.yml index 4183d710..d191d8a1 100644 --- a/src/apps/seelenweg/i18n/translations/km.yml +++ b/src/apps/seelenweg/i18n/translations/km.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: បើកការកំណត់ - media: បន្ថែមម៉ូឌុលមេឌៀបន្ថែម - start: បន្ថែមម៉ូឌុលចាប់ផ្តើម -app_menu: - run_as: ដំណើរការ​ជា​រ​អ្នកគ្រប់គ្រង - pin: ម្ជុល - copy_handles: ចម្លងចំណុចទាញ - unpin: អក្គោអិន - pin_to_center: ម្ជុលទៅកណ្តាល - close_multiple: បិទទាំងអស់ - pin_to_left: ម្ជុលទៅឆ្វេង - pin_to_right: ម្ជុលទៅស្តាំ - close: បិត - open_file_location: បើកទីតាំងឯកសារ -media_menu: - remove: យកម៉ូឌុលមេឌៀចេញ -start_menu: - remove: យកម៉ូឌុលចាប់ផ្តើមចេញ +taskbar_menu: + settings: បើកការកំណត់ + media: បន្ថែមម៉ូឌុលមេឌៀបន្ថែម + start: បន្ថែមម៉ូឌុលចាប់ផ្តើម +app_menu: + run_as: ដំណើរការ​ជា​រ​អ្នកគ្រប់គ្រង + pin: ម្ជុល + copy_handles: ចម្លងចំណុចទាញ + unpin: អក្គោអិន + pin_to_center: ម្ជុលទៅកណ្តាល + close_multiple: បិទទាំងអស់ + pin_to_left: ម្ជុលទៅឆ្វេង + pin_to_right: ម្ជុលទៅស្តាំ + close: បិត + open_file_location: បើកទីតាំងឯកសារ +media_menu: + remove: យកម៉ូឌុលមេឌៀចេញ +start_menu: + remove: យកម៉ូឌុលចាប់ផ្តើមចេញ diff --git a/src/apps/seelenweg/i18n/translations/ko.yml b/src/apps/seelenweg/i18n/translations/ko.yml index a2f6e253..3cb20748 100644 --- a/src/apps/seelenweg/i18n/translations/ko.yml +++ b/src/apps/seelenweg/i18n/translations/ko.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: 미디어 모듈 추가 - start: 시작 모듈 추가 - settings: 설정 열기 -app_menu: - unpin: 고정 해제 - pin: 고정 - pin_to_left: 왼쪽에 고정 - pin_to_center: 중앙에 고정 - pin_to_right: 오른쪽에 고정 - open_file_location: 파일 위치 열기 - run_as: 관리자 권한으로 실행 - copy_handles: 핸들 복사 - close: 닫기 - close_multiple: 모두 닫기 -media_menu: - remove: 미디어 모듈 제거 -start_menu: - remove: 시작 모듈 제거 +taskbar_menu: + media: 미디어 모듈 추가 + start: 시작 모듈 추가 + settings: 설정 열기 +app_menu: + unpin: 고정 해제 + pin: 고정 + pin_to_left: 왼쪽에 고정 + pin_to_center: 중앙에 고정 + pin_to_right: 오른쪽에 고정 + open_file_location: 파일 위치 열기 + run_as: 관리자 권한으로 실행 + copy_handles: 핸들 복사 + close: 닫기 + close_multiple: 모두 닫기 +media_menu: + remove: 미디어 모듈 제거 +start_menu: + remove: 시작 모듈 제거 diff --git a/src/apps/seelenweg/i18n/translations/ku.yml b/src/apps/seelenweg/i18n/translations/ku.yml index dc3083a6..46f34b12 100644 --- a/src/apps/seelenweg/i18n/translations/ku.yml +++ b/src/apps/seelenweg/i18n/translations/ku.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Modela medyayê lê zêde bike - settings: Mîhengên vekirî - start: Modulê dest pê bikin -app_menu: - pin: Derzî - close: Nêzîkî - run_as: Wek Rêvebir bisekinin - pin_to_center: Pin to navenda - open_file_location: Cihê pelê vekirî - pin_to_right: Pin berbi rast - close_multiple: Her tiştî bigire - pin_to_left: Pin çepê - copy_handles: Destên kopî bikin - unpin: Unpin -media_menu: - remove: Modela medyayê rakin -start_menu: - remove: Modela Destpêkê rakirin +taskbar_menu: + media: Modela medyayê lê zêde bike + settings: Mîhengên vekirî + start: Modulê dest pê bikin +app_menu: + pin: Derzî + close: Nêzîkî + run_as: Wek Rêvebir bisekinin + pin_to_center: Pin to navenda + open_file_location: Cihê pelê vekirî + pin_to_right: Pin berbi rast + close_multiple: Her tiştî bigire + pin_to_left: Pin çepê + copy_handles: Destên kopî bikin + unpin: Unpin +media_menu: + remove: Modela medyayê rakin +start_menu: + remove: Modela Destpêkê rakirin diff --git a/src/apps/seelenweg/i18n/translations/lb.yml b/src/apps/seelenweg/i18n/translations/lb.yml index 1d19a273..cf7ad2ec 100644 --- a/src/apps/seelenweg/i18n/translations/lb.yml +++ b/src/apps/seelenweg/i18n/translations/lb.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Füügt Media Modul bäi - start: Füügt Start Modul - settings: Oppen Astellungen -app_menu: - close_multiple: Alles dobäi - copy_handles: Kopie Handelen - pin_to_left: PIN fir lénks - run_as: Lafen als Administrator - close: Zoumaachen - open_file_location: Open Dateiplaz - pin_to_center: PIN op Zentrum - unpin: Net unsträichen - pin: Pin - pin_to_right: PIN op riets -media_menu: - remove: Ewechzehuelen Media Modul -start_menu: - remove: Ewechzehuelen Start Modul +taskbar_menu: + media: Füügt Media Modul bäi + start: Füügt Start Modul + settings: Oppen Astellungen +app_menu: + close_multiple: Alles dobäi + copy_handles: Kopie Handelen + pin_to_left: PIN fir lénks + run_as: Lafen als Administrator + close: Zoumaachen + open_file_location: Open Dateiplaz + pin_to_center: PIN op Zentrum + unpin: Net unsträichen + pin: Pin + pin_to_right: PIN op riets +media_menu: + remove: Ewechzehuelen Media Modul +start_menu: + remove: Ewechzehuelen Start Modul diff --git a/src/apps/seelenweg/i18n/translations/lo.yml b/src/apps/seelenweg/i18n/translations/lo.yml index 74edb84e..8198394d 100644 --- a/src/apps/seelenweg/i18n/translations/lo.yml +++ b/src/apps/seelenweg/i18n/translations/lo.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: ເປີດການຕັ້ງຄ່າ - media: ຕື່ມການໂມດູນສື່ - start: ເພີ່ມໂມດູນ Start -app_menu: - run_as: ດໍາເນີນການເປັນຜູ້ບໍລິຫານ - close_multiple: ປິດທັງຫມົດ - pin_to_right: PIN ກັບຂວາ - copy_handles: ຄັດລອກ - open_file_location: ເປີດສະຖານທີ່ເອກະສານ - close: ປິດ - pin_to_center: PIN ເຖິງສູນກາງ - pin: ເຂັມ PIN - unpin: unppin - pin_to_left: ເຂັມຊ້າຍໄປ -media_menu: - remove: ເອົາ Module ສື່ -start_menu: - remove: ເອົາໂມດູນເລີ່ມຕົ້ນ +taskbar_menu: + settings: ເປີດການຕັ້ງຄ່າ + media: ຕື່ມການໂມດູນສື່ + start: ເພີ່ມໂມດູນ Start +app_menu: + run_as: ດໍາເນີນການເປັນຜູ້ບໍລິຫານ + close_multiple: ປິດທັງຫມົດ + pin_to_right: PIN ກັບຂວາ + copy_handles: ຄັດລອກ + open_file_location: ເປີດສະຖານທີ່ເອກະສານ + close: ປິດ + pin_to_center: PIN ເຖິງສູນກາງ + pin: ເຂັມ PIN + unpin: unppin + pin_to_left: ເຂັມຊ້າຍໄປ +media_menu: + remove: ເອົາ Module ສື່ +start_menu: + remove: ເອົາໂມດູນເລີ່ມຕົ້ນ diff --git a/src/apps/seelenweg/i18n/translations/lt.yml b/src/apps/seelenweg/i18n/translations/lt.yml index 1c6d57a1..2a657fe4 100644 --- a/src/apps/seelenweg/i18n/translations/lt.yml +++ b/src/apps/seelenweg/i18n/translations/lt.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Atidaryti nustatymai - start: Pridėkite pradžios modulį - media: Pridėkite laikmenos modulį -app_menu: - pin_to_center: Kaištis iki centro - close: Uždaryti - pin: Kaištis - unpin: Unpin - copy_handles: Kopijavimo rankenos - pin_to_right: Kaištis į dešinę - pin_to_left: Kaištis į kairę - open_file_location: Atidarykite failo vietą - run_as: Vykdykite kaip administratorius - close_multiple: Uždaryk viską -media_menu: - remove: Pašalinkite medijos modulį -start_menu: - remove: Pašalinkite pradžios modulį +taskbar_menu: + settings: Atidaryti nustatymai + start: Pridėkite pradžios modulį + media: Pridėkite laikmenos modulį +app_menu: + pin_to_center: Kaištis iki centro + close: Uždaryti + pin: Kaištis + unpin: Unpin + copy_handles: Kopijavimo rankenos + pin_to_right: Kaištis į dešinę + pin_to_left: Kaištis į kairę + open_file_location: Atidarykite failo vietą + run_as: Vykdykite kaip administratorius + close_multiple: Uždaryk viską +media_menu: + remove: Pašalinkite medijos modulį +start_menu: + remove: Pašalinkite pradžios modulį diff --git a/src/apps/seelenweg/i18n/translations/lv.yml b/src/apps/seelenweg/i18n/translations/lv.yml index 7fa91af6..e597d1d4 100644 --- a/src/apps/seelenweg/i18n/translations/lv.yml +++ b/src/apps/seelenweg/i18n/translations/lv.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Atvērti iestatījumi - start: Pievienojiet starta moduli - media: Pievienojiet multivides moduli -app_menu: - close: Tuvs - pin_to_right: Piespraudiet labajā pusē - copy_handles: Kopēt rokturus - close_multiple: Aizvērt visu - run_as: Izpildīt kā administratoram - open_file_location: Atveriet faila atrašanās vietu - unpin: Neslēpt - pin_to_left: Piespraudiet pa kreisi - pin_to_center: Piespraudiet centrā - pin: Piespraust -media_menu: - remove: Noņemiet multivides moduli -start_menu: - remove: Noņemiet sākuma moduli +taskbar_menu: + settings: Atvērti iestatījumi + start: Pievienojiet starta moduli + media: Pievienojiet multivides moduli +app_menu: + close: Tuvs + pin_to_right: Piespraudiet labajā pusē + copy_handles: Kopēt rokturus + close_multiple: Aizvērt visu + run_as: Izpildīt kā administratoram + open_file_location: Atveriet faila atrašanās vietu + unpin: Neslēpt + pin_to_left: Piespraudiet pa kreisi + pin_to_center: Piespraudiet centrā + pin: Piespraust +media_menu: + remove: Noņemiet multivides moduli +start_menu: + remove: Noņemiet sākuma moduli diff --git a/src/apps/seelenweg/i18n/translations/mk.yml b/src/apps/seelenweg/i18n/translations/mk.yml index 998ea80d..e537013c 100644 --- a/src/apps/seelenweg/i18n/translations/mk.yml +++ b/src/apps/seelenweg/i18n/translations/mk.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Отворете ги поставките - start: Додадете модул за почеток - media: Додадете медиумски модул -app_menu: - run_as: Работи како администратор - open_file_location: Отворете ја локацијата на датотеката - pin: Игла - unpin: Unpin - pin_to_left: Игла на лево - copy_handles: Копирање рачки - close: Затвори - pin_to_right: Игла надесно - close_multiple: Затворете ги сите - pin_to_center: Игла до центар -media_menu: - remove: Отстранете го модулот за медиуми -start_menu: - remove: Отстранете го модулот за почеток +taskbar_menu: + settings: Отворете ги поставките + start: Додадете модул за почеток + media: Додадете медиумски модул +app_menu: + run_as: Работи како администратор + open_file_location: Отворете ја локацијата на датотеката + pin: Игла + unpin: Unpin + pin_to_left: Игла на лево + copy_handles: Копирање рачки + close: Затвори + pin_to_right: Игла надесно + close_multiple: Затворете ги сите + pin_to_center: Игла до центар +media_menu: + remove: Отстранете го модулот за медиуми +start_menu: + remove: Отстранете го модулот за почеток diff --git a/src/apps/seelenweg/i18n/translations/mn.yml b/src/apps/seelenweg/i18n/translations/mn.yml index e1a65e46..87be7068 100644 --- a/src/apps/seelenweg/i18n/translations/mn.yml +++ b/src/apps/seelenweg/i18n/translations/mn.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: АВир танилцуулга - media: Медиа модулийг нэмнэ - start: Эхлэх модулийг нэмнэ үү -app_menu: - run_as: Администратороор ажиллуулах - unpin: Нууц - pin_to_left: Зүүн тийш зүү - close_multiple: Бүгдийг хаах - open_file_location: Нээлттэй файлын байршлыг нээнэ үү - pin_to_center: Төв рүү зүү - copy_handles: Хуулбарлах - pin: Сулбээр зүү - pin_to_right: Баруун тийш зүү - close: Ойр дөхөм -media_menu: - remove: МЭДЭЭЛЛИЙН МЭДЭЭЛЛИЙН МЭДЭЭЛЭЛ -start_menu: - remove: Эхлэх модулийг устгах +taskbar_menu: + settings: АВир танилцуулга + media: Медиа модулийг нэмнэ + start: Эхлэх модулийг нэмнэ үү +app_menu: + run_as: Администратороор ажиллуулах + unpin: Нууц + pin_to_left: Зүүн тийш зүү + close_multiple: Бүгдийг хаах + open_file_location: Нээлттэй файлын байршлыг нээнэ үү + pin_to_center: Төв рүү зүү + copy_handles: Хуулбарлах + pin: Сулбээр зүү + pin_to_right: Баруун тийш зүү + close: Ойр дөхөм +media_menu: + remove: МЭДЭЭЛЛИЙН МЭДЭЭЛЛИЙН МЭДЭЭЛЭЛ +start_menu: + remove: Эхлэх модулийг устгах diff --git a/src/apps/seelenweg/i18n/translations/ms.yml b/src/apps/seelenweg/i18n/translations/ms.yml index 5134a9b6..d3ee985b 100644 --- a/src/apps/seelenweg/i18n/translations/ms.yml +++ b/src/apps/seelenweg/i18n/translations/ms.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Buka Tetapan - media: Tambah Modul Media - start: Tambah Modul Mula -app_menu: - close_multiple: Tutup semua - open_file_location: Buka lokasi fail - pin: Pin - pin_to_center: Pin ke pusat - close: Tutup - run_as: Jalankan sebagai pentadbir - unpin: Unpin - copy_handles: Salin pemegang - pin_to_right: Pin ke kanan - pin_to_left: Pin ke kiri -media_menu: - remove: Keluarkan modul media -start_menu: - remove: Keluarkan Modul Mula +taskbar_menu: + settings: Buka Tetapan + media: Tambah Modul Media + start: Tambah Modul Mula +app_menu: + close_multiple: Tutup semua + open_file_location: Buka lokasi fail + pin: Pin + pin_to_center: Pin ke pusat + close: Tutup + run_as: Jalankan sebagai pentadbir + unpin: Unpin + copy_handles: Salin pemegang + pin_to_right: Pin ke kanan + pin_to_left: Pin ke kiri +media_menu: + remove: Keluarkan modul media +start_menu: + remove: Keluarkan Modul Mula diff --git a/src/apps/seelenweg/i18n/translations/mt.yml b/src/apps/seelenweg/i18n/translations/mt.yml index a5b58136..de736b7a 100644 --- a/src/apps/seelenweg/i18n/translations/mt.yml +++ b/src/apps/seelenweg/i18n/translations/mt.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Żid il-modulu tal-midja - settings: Settings miftuħa - start: Żid il-modulu tal-bidu -app_menu: - pin_to_center: Pin għal ċentru - run_as: Mexxi bħala amministratur - close_multiple: Agħlaq ilkoll - pin_to_left: Pin lejn ix-xellug - pin_to_right: Pin għal dritt - unpin: Unpin - close: Viċin - copy_handles: Kopja pumi - pin: Pin - open_file_location: Post tal-fajl miftuħ -media_menu: - remove: Neħħi l-modulu tal-midja -start_menu: - remove: Neħħi l-modulu tal-bidu +taskbar_menu: + media: Żid il-modulu tal-midja + settings: Settings miftuħa + start: Żid il-modulu tal-bidu +app_menu: + pin_to_center: Pin għal ċentru + run_as: Mexxi bħala amministratur + close_multiple: Agħlaq ilkoll + pin_to_left: Pin lejn ix-xellug + pin_to_right: Pin għal dritt + unpin: Unpin + close: Viċin + copy_handles: Kopja pumi + pin: Pin + open_file_location: Post tal-fajl miftuħ +media_menu: + remove: Neħħi l-modulu tal-midja +start_menu: + remove: Neħħi l-modulu tal-bidu diff --git a/src/apps/seelenweg/i18n/translations/ne.yml b/src/apps/seelenweg/i18n/translations/ne.yml index c12cd344..81a306fe 100644 --- a/src/apps/seelenweg/i18n/translations/ne.yml +++ b/src/apps/seelenweg/i18n/translations/ne.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: खुला सेटिंग्स - media: मिडिया मोड्युल थप्नुहोस् - start: स्टार्ट मोड्युल थप्नुहोस् -app_menu: - run_as: प्रशासक रूपमा चलाउन - pin_to_left: बाँया बायाँ - open_file_location: फाइल स्थान खोल्नुहोस् - close_multiple: चौमा - pin_to_center: केन्द्रमा पिन - copy_handles: मुख्य ह्यान्डल - pin: आलपिन - unpin: चुस्नु - pin_to_right: दायाँ राख्न पिन - close: घनिष्ट -media_menu: - remove: मिडिया मोड्युल हटाउनुहोस् -start_menu: - remove: सुरु मोड्युल हटाउनुहोस् +taskbar_menu: + settings: खुला सेटिंग्स + media: मिडिया मोड्युल थप्नुहोस् + start: स्टार्ट मोड्युल थप्नुहोस् +app_menu: + run_as: प्रशासक रूपमा चलाउन + pin_to_left: बाँया बायाँ + open_file_location: फाइल स्थान खोल्नुहोस् + close_multiple: चौमा + pin_to_center: केन्द्रमा पिन + copy_handles: मुख्य ह्यान्डल + pin: आलपिन + unpin: चुस्नु + pin_to_right: दायाँ राख्न पिन + close: घनिष्ट +media_menu: + remove: मिडिया मोड्युल हटाउनुहोस् +start_menu: + remove: सुरु मोड्युल हटाउनुहोस् diff --git a/src/apps/seelenweg/i18n/translations/nl.yml b/src/apps/seelenweg/i18n/translations/nl.yml index 770daffa..8677741a 100644 --- a/src/apps/seelenweg/i18n/translations/nl.yml +++ b/src/apps/seelenweg/i18n/translations/nl.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Open instellingen - media: Voeg mediamodule toe - start: Startmodule toevoegen -app_menu: - close_multiple: Sluit alles - pin_to_left: Pin naar links - run_as: Als administrator uitvoeren - pin: Pin - close: Dichtbij - pin_to_right: Pin naar rechts - open_file_location: Open de bestandslocatie - pin_to_center: Pin tot het midden - copy_handles: Kopieer handgrepen - unpin: Losmaken -media_menu: - remove: Verwijder de mediamodule -start_menu: - remove: Verwijder de startmodule +taskbar_menu: + settings: Open instellingen + media: Voeg mediamodule toe + start: Startmodule toevoegen +app_menu: + close_multiple: Sluit alles + pin_to_left: Pin naar links + run_as: Als administrator uitvoeren + pin: Pin + close: Dichtbij + pin_to_right: Pin naar rechts + open_file_location: Open de bestandslocatie + pin_to_center: Pin tot het midden + copy_handles: Kopieer handgrepen + unpin: Losmaken +media_menu: + remove: Verwijder de mediamodule +start_menu: + remove: Verwijder de startmodule diff --git a/src/apps/seelenweg/i18n/translations/no.yml b/src/apps/seelenweg/i18n/translations/no.yml index d2ec9d0f..afe81c4d 100644 --- a/src/apps/seelenweg/i18n/translations/no.yml +++ b/src/apps/seelenweg/i18n/translations/no.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Åpne innstillinger - start: Legg til startmodul - media: Legg til mediemodul -app_menu: - open_file_location: Åpne fil plassering - close: Lukk - close_multiple: Lukk alle - run_as: Kjør som administrator - pin_to_center: Pin til sentrum - pin_to_right: Pin til høyre - copy_handles: Kopier håndtak - unpin: Upinn - pin: Pin - pin_to_left: Pin til venstre -media_menu: - remove: Fjern mediemodulen -start_menu: - remove: Fjern startmodulen +taskbar_menu: + settings: Åpne innstillinger + start: Legg til startmodul + media: Legg til mediemodul +app_menu: + open_file_location: Åpne fil plassering + close: Lukk + close_multiple: Lukk alle + run_as: Kjør som administrator + pin_to_center: Pin til sentrum + pin_to_right: Pin til høyre + copy_handles: Kopier håndtak + unpin: Upinn + pin: Pin + pin_to_left: Pin til venstre +media_menu: + remove: Fjern mediemodulen +start_menu: + remove: Fjern startmodulen diff --git a/src/apps/seelenweg/i18n/translations/pa.yml b/src/apps/seelenweg/i18n/translations/pa.yml index e6e7b0d4..02065fe6 100644 --- a/src/apps/seelenweg/i18n/translations/pa.yml +++ b/src/apps/seelenweg/i18n/translations/pa.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ - media: ਮੀਡੀਆ ਮੋਡੀ .ਲ ਸ਼ਾਮਲ ਕਰੋ - start: ਸਟਾਰਟ ਮੋਡੀ ule ਲ ਸ਼ਾਮਲ ਕਰੋ -app_menu: - close_multiple: ਸਾਰੇ ਬੰਦ ਕਰੋ - pin_to_center: ਕੇਂਦਰ ਨੂੰ ਪਿੰਨ - run_as: ਪ੍ਰਬੰਧਕ ਦੇ ਤੌਰ ਤੇ ਚਲਾਓ - copy_handles: ਕਾੱਪੀ ਹੈਂਡਲ - open_file_location: ਓਪਨ ਫਾਈਲ ਟਿਕਾਣਾ - pin_to_left: ਪਿੰਨ ਛੱਡ ਕੇ - pin_to_right: ਪਿੰਨ ਕਰਨ ਲਈ - unpin: Unpin - close: ਨੇੜੇ - pin: ਪਿੰਨ -media_menu: - remove: ਮੀਡੀਆ ਮੋਡੀ .ਲ ਹਟਾਓ -start_menu: - remove: ਸਟਾਰਟ ਮੋਡੀ .ਲ ਹਟਾਓ +taskbar_menu: + settings: ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ + media: ਮੀਡੀਆ ਮੋਡੀ .ਲ ਸ਼ਾਮਲ ਕਰੋ + start: ਸਟਾਰਟ ਮੋਡੀ ule ਲ ਸ਼ਾਮਲ ਕਰੋ +app_menu: + close_multiple: ਸਾਰੇ ਬੰਦ ਕਰੋ + pin_to_center: ਕੇਂਦਰ ਨੂੰ ਪਿੰਨ + run_as: ਪ੍ਰਬੰਧਕ ਦੇ ਤੌਰ ਤੇ ਚਲਾਓ + copy_handles: ਕਾੱਪੀ ਹੈਂਡਲ + open_file_location: ਓਪਨ ਫਾਈਲ ਟਿਕਾਣਾ + pin_to_left: ਪਿੰਨ ਛੱਡ ਕੇ + pin_to_right: ਪਿੰਨ ਕਰਨ ਲਈ + unpin: Unpin + close: ਨੇੜੇ + pin: ਪਿੰਨ +media_menu: + remove: ਮੀਡੀਆ ਮੋਡੀ .ਲ ਹਟਾਓ +start_menu: + remove: ਸਟਾਰਟ ਮੋਡੀ .ਲ ਹਟਾਓ diff --git a/src/apps/seelenweg/i18n/translations/pl.yml b/src/apps/seelenweg/i18n/translations/pl.yml index d23c20f4..abf92c81 100644 --- a/src/apps/seelenweg/i18n/translations/pl.yml +++ b/src/apps/seelenweg/i18n/translations/pl.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Otwórz ustawienia - start: Dodaj moduł Start - media: Dodaj moduł nośnika -app_menu: - unpin: Odpiąć - pin: Szpilka - run_as: Uruchom jako administrator - open_file_location: Otwórz lokalizację pliku - close: Zamknąć - pin_to_center: Pin do środka - pin_to_right: Pin po prawej - copy_handles: Kopiuj uchwyty - close_multiple: Zamknij wszystko - pin_to_left: Szpilka do lewej -media_menu: - remove: Usuń moduł multimediów -start_menu: - remove: Usuń moduł startowy +taskbar_menu: + settings: Otwórz ustawienia + start: Dodaj moduł Start + media: Dodaj moduł nośnika +app_menu: + unpin: Odpiąć + pin: Szpilka + run_as: Uruchom jako administrator + open_file_location: Otwórz lokalizację pliku + close: Zamknąć + pin_to_center: Pin do środka + pin_to_right: Pin po prawej + copy_handles: Kopiuj uchwyty + close_multiple: Zamknij wszystko + pin_to_left: Szpilka do lewej +media_menu: + remove: Usuń moduł multimediów +start_menu: + remove: Usuń moduł startowy diff --git a/src/apps/seelenweg/i18n/translations/ps.yml b/src/apps/seelenweg/i18n/translations/ps.yml index ecfe48dc..52cb546e 100644 --- a/src/apps/seelenweg/i18n/translations/ps.yml +++ b/src/apps/seelenweg/i18n/translations/ps.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: خلاص امستنې - media: د میډیا موډول اضافه کړئ - start: د پیل ماډل اضافه کړئ -app_menu: - copy_handles: لاسوندونه کاپي کوي - pin_to_center: مرکز ته پن - pin_to_right: ښیې خوا ته - pin_to_left: د کی to اړخ ته پن - open_file_location: د فایل ځای خلاص کړئ - close_multiple: ټول وتړئ - unpin: غیر رنګ - close: بندول - run_as: د مدیر په توګه چلول - pin: پن -media_menu: - remove: د میډیا ماډل لرې کړئ -start_menu: - remove: د پیل ماډل لرې کړئ +taskbar_menu: + settings: خلاص امستنې + media: د میډیا موډول اضافه کړئ + start: د پیل ماډل اضافه کړئ +app_menu: + copy_handles: لاسوندونه کاپي کوي + pin_to_center: مرکز ته پن + pin_to_right: ښیې خوا ته + pin_to_left: د کی to اړخ ته پن + open_file_location: د فایل ځای خلاص کړئ + close_multiple: ټول وتړئ + unpin: غیر رنګ + close: بندول + run_as: د مدیر په توګه چلول + pin: پن +media_menu: + remove: د میډیا ماډل لرې کړئ +start_menu: + remove: د پیل ماډل لرې کړئ diff --git a/src/apps/seelenweg/i18n/translations/pt.yml b/src/apps/seelenweg/i18n/translations/pt.yml index 4cce01ca..35a607e6 100644 --- a/src/apps/seelenweg/i18n/translations/pt.yml +++ b/src/apps/seelenweg/i18n/translations/pt.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Adicionar módulo de mídia - start: Adicionar módulo inicial - settings: Abrir configurações -app_menu: - unpin: Liberar - pin: Alfinete - pin_to_left: Fixar à esquerda - pin_to_center: Fixar no centro - pin_to_right: Fixar à direita - open_file_location: Abrir local do Ficheiro - run_as: Executar como administrador - copy_handles: Alças de cópia - close: Fechar - close_multiple: Feche tudo -media_menu: - remove: Remover módulo de mídia -start_menu: - remove: Remover módulo inicial +taskbar_menu: + media: Adicionar módulo de mídia + start: Adicionar módulo inicial + settings: Abrir configurações +app_menu: + unpin: Liberar + pin: Alfinete + pin_to_left: Fixar à esquerda + pin_to_center: Fixar no centro + pin_to_right: Fixar à direita + open_file_location: Abrir local do Ficheiro + run_as: Executar como administrador + copy_handles: Alças de cópia + close: Fechar + close_multiple: Feche tudo +media_menu: + remove: Remover módulo de mídia +start_menu: + remove: Remover módulo inicial diff --git a/src/apps/seelenweg/i18n/translations/ro.yml b/src/apps/seelenweg/i18n/translations/ro.yml index 12cfab94..c0c6bfd7 100644 --- a/src/apps/seelenweg/i18n/translations/ro.yml +++ b/src/apps/seelenweg/i18n/translations/ro.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Deschide setările - media: Adăugați modul media - start: Adăugați modulul de pornire -app_menu: - open_file_location: Deschide locația fișierului - close: Închide - close_multiple: Inchide tot - run_as: Rulat ca administrator - pin_to_center: Pin în centru - copy_handles: Copiați mânerele - pin_to_right: Pin la dreapta - unpin: Unpin - pin: Ac - pin_to_left: Pin la stânga -media_menu: - remove: Eliminați modulul media -start_menu: - remove: Eliminați modulul de pornire +taskbar_menu: + settings: Deschide setările + media: Adăugați modul media + start: Adăugați modulul de pornire +app_menu: + open_file_location: Deschide locația fișierului + close: Închide + close_multiple: Inchide tot + run_as: Rulat ca administrator + pin_to_center: Pin în centru + copy_handles: Copiați mânerele + pin_to_right: Pin la dreapta + unpin: Unpin + pin: Ac + pin_to_left: Pin la stânga +media_menu: + remove: Eliminați modulul media +start_menu: + remove: Eliminați modulul de pornire diff --git a/src/apps/seelenweg/i18n/translations/ru.yml b/src/apps/seelenweg/i18n/translations/ru.yml index 91d80a63..49ae45d0 100644 --- a/src/apps/seelenweg/i18n/translations/ru.yml +++ b/src/apps/seelenweg/i18n/translations/ru.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Добавить медиа-модуль - start: Добавить стартовый модуль - settings: Открыть настройки -app_menu: - unpin: Открепить - pin: Приколоть - pin_to_left: Закрепить слева - pin_to_center: Закрепить в центре - pin_to_right: Закрепить вправо - open_file_location: Местонахождение открытого файла - run_as: Запустить от имени администратора - copy_handles: Копировать дескрипторы - close: Закрывать - close_multiple: Закрыть все -media_menu: - remove: Удаление медиа-модуля -start_menu: - remove: Удалить стартовый модуль +taskbar_menu: + media: Добавить медиа-модуль + start: Добавить стартовый модуль + settings: Открыть настройки +app_menu: + unpin: Открепить + pin: Приколоть + pin_to_left: Закрепить слева + pin_to_center: Закрепить в центре + pin_to_right: Закрепить вправо + open_file_location: Местонахождение открытого файла + run_as: Запустить от имени администратора + copy_handles: Копировать дескрипторы + close: Закрывать + close_multiple: Закрыть все +media_menu: + remove: Удаление медиа-модуля +start_menu: + remove: Удалить стартовый модуль diff --git a/src/apps/seelenweg/i18n/translations/si.yml b/src/apps/seelenweg/i18n/translations/si.yml index 68050230..c7b50514 100644 --- a/src/apps/seelenweg/i18n/translations/si.yml +++ b/src/apps/seelenweg/i18n/translations/si.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: විවෘත සැකසුම් - media: මාධ්ය මොඩියුලය එක් කරන්න - start: ආරම්භක මොඩියුලය එක් කරන්න -app_menu: - open_file_location: ගොනුව විවෘත ස්ථානය - run_as: පරිපාලක ලෙස ක්රියාත්මක වන්න - pin_to_right: පින් කරන්න දකුණට - copy_handles: හසුරුමය - pin_to_center: මධ්යස්ථානයට පින් කරන්න - close_multiple: සියල්ල වසා දමන්න - unpin: UNTIN - pin_to_left: වමට - close: වසන්න - pin: පින් -media_menu: - remove: මාධ්ය මොඩියුලය ඉවත් කරන්න -start_menu: - remove: ආරම්භක මොඩියුලය ඉවත් කරන්න +taskbar_menu: + settings: විවෘත සැකසුම් + media: මාධ්ය මොඩියුලය එක් කරන්න + start: ආරම්භක මොඩියුලය එක් කරන්න +app_menu: + open_file_location: ගොනුව විවෘත ස්ථානය + run_as: පරිපාලක ලෙස ක්රියාත්මක වන්න + pin_to_right: පින් කරන්න දකුණට + copy_handles: හසුරුමය + pin_to_center: මධ්යස්ථානයට පින් කරන්න + close_multiple: සියල්ල වසා දමන්න + unpin: UNTIN + pin_to_left: වමට + close: වසන්න + pin: පින් +media_menu: + remove: මාධ්ය මොඩියුලය ඉවත් කරන්න +start_menu: + remove: ආරම්භක මොඩියුලය ඉවත් කරන්න diff --git a/src/apps/seelenweg/i18n/translations/sk.yml b/src/apps/seelenweg/i18n/translations/sk.yml index 7772e1d9..18a4238b 100644 --- a/src/apps/seelenweg/i18n/translations/sk.yml +++ b/src/apps/seelenweg/i18n/translations/sk.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Pridať mediálny modul - settings: Otvorené nastavenia - start: Pridať štartový modul -app_menu: - close: Zavrieť - run_as: Spustiť ako správca - close_multiple: Zavrieť - open_file_location: Otvorte umiestnenie súboru - pin_to_center: Špendlík - pin_to_right: Špendlík - unpin: Zaniknúť - pin: Pin - copy_handles: Kopírovanie rukovätí - pin_to_left: Špendlík doľava -media_menu: - remove: Odstráňte mediálny modul -start_menu: - remove: Odstráňte modul Štart +taskbar_menu: + media: Pridať mediálny modul + settings: Otvorené nastavenia + start: Pridať štartový modul +app_menu: + close: Zavrieť + run_as: Spustiť ako správca + close_multiple: Zavrieť + open_file_location: Otvorte umiestnenie súboru + pin_to_center: Špendlík + pin_to_right: Špendlík + unpin: Zaniknúť + pin: Pin + copy_handles: Kopírovanie rukovätí + pin_to_left: Špendlík doľava +media_menu: + remove: Odstráňte mediálny modul +start_menu: + remove: Odstráňte modul Štart diff --git a/src/apps/seelenweg/i18n/translations/so.yml b/src/apps/seelenweg/i18n/translations/so.yml index 04280cec..7e0ca301 100644 --- a/src/apps/seelenweg/i18n/translations/so.yml +++ b/src/apps/seelenweg/i18n/translations/so.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Meel furan - media: Ku dar module warbaahinta - start: Ku dar cutubka bilowga -app_menu: - pin_to_left: PIN ilaa bidix - pin_to_center: PIN ilaa Xarunta - open_file_location: Goobta faylka furan - run_as: U ordo sidii maamule - close: Xirid - close_multiple: Xir dhammaan - pin_to_right: PIN ilaa midig - copy_handles: Nuqullada gacanta - unpin: Aan qarin - pin: Musbaar yar -media_menu: - remove: Ka saar cutubka warbaahinta -start_menu: - remove: Ka saar cutubka bilowga +taskbar_menu: + settings: Meel furan + media: Ku dar module warbaahinta + start: Ku dar cutubka bilowga +app_menu: + pin_to_left: PIN ilaa bidix + pin_to_center: PIN ilaa Xarunta + open_file_location: Goobta faylka furan + run_as: U ordo sidii maamule + close: Xirid + close_multiple: Xir dhammaan + pin_to_right: PIN ilaa midig + copy_handles: Nuqullada gacanta + unpin: Aan qarin + pin: Musbaar yar +media_menu: + remove: Ka saar cutubka warbaahinta +start_menu: + remove: Ka saar cutubka bilowga diff --git a/src/apps/seelenweg/i18n/translations/sr.yml b/src/apps/seelenweg/i18n/translations/sr.yml index 0350fcd4..f5b35e3f 100644 --- a/src/apps/seelenweg/i18n/translations/sr.yml +++ b/src/apps/seelenweg/i18n/translations/sr.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Отвори подешавања - media: Додајте медијски модул - start: Додајте почетни модул -app_menu: - close_multiple: Затворите све - run_as: Покрени као администратор - close: Близу - pin_to_center: ПИН до центра - open_file_location: Отворите локацију датотеке - pin_to_left: Игните лево - copy_handles: Копирајте ручке - pin: Пин - unpin: Развелити - pin_to_right: Пин удесно -media_menu: - remove: Уклоните медијски модул -start_menu: - remove: Уклоните покретни модул +taskbar_menu: + settings: Отвори подешавања + media: Додајте медијски модул + start: Додајте почетни модул +app_menu: + close_multiple: Затворите све + run_as: Покрени као администратор + close: Близу + pin_to_center: ПИН до центра + open_file_location: Отворите локацију датотеке + pin_to_left: Игните лево + copy_handles: Копирајте ручке + pin: Пин + unpin: Развелити + pin_to_right: Пин удесно +media_menu: + remove: Уклоните медијски модул +start_menu: + remove: Уклоните покретни модул diff --git a/src/apps/seelenweg/i18n/translations/sv.yml b/src/apps/seelenweg/i18n/translations/sv.yml index 71ca6e46..c32ed464 100644 --- a/src/apps/seelenweg/i18n/translations/sv.yml +++ b/src/apps/seelenweg/i18n/translations/sv.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Öppna Inställningar - start: Lägg till startmodul - media: Lägg till mediemodul -app_menu: - pin: Stift - close_multiple: Stäng alla - run_as: Kör som administratör - open_file_location: Öppna filplats - close: Stänga - copy_handles: Kopieringshandtag - pin_to_center: Stift till mitten - pin_to_right: Nöja sig till höger - unpin: Lutande - pin_to_left: Stämma till vänster -media_menu: - remove: Ta bort mediemodulen -start_menu: - remove: Ta bort startmodulen +taskbar_menu: + settings: Öppna Inställningar + start: Lägg till startmodul + media: Lägg till mediemodul +app_menu: + pin: Stift + close_multiple: Stäng alla + run_as: Kör som administratör + open_file_location: Öppna filplats + close: Stänga + copy_handles: Kopieringshandtag + pin_to_center: Stift till mitten + pin_to_right: Nöja sig till höger + unpin: Lutande + pin_to_left: Stämma till vänster +media_menu: + remove: Ta bort mediemodulen +start_menu: + remove: Ta bort startmodulen diff --git a/src/apps/seelenweg/i18n/translations/sw.yml b/src/apps/seelenweg/i18n/translations/sw.yml index 50b031f7..0703c3a9 100644 --- a/src/apps/seelenweg/i18n/translations/sw.yml +++ b/src/apps/seelenweg/i18n/translations/sw.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Mipangilio ya Fungua - start: Ongeza moduli ya kuanza - media: Ongeza moduli ya media -app_menu: - close_multiple: Funga yote - pin: Pini - open_file_location: Fungua eneo la faili - run_as: Kukimbia kama msimamizi - pin_to_left: Pini kushoto - copy_handles: Nakili Hushughulikia - close: Karibu - unpin: Unpin - pin_to_right: Pini kulia - pin_to_center: Pini katikati -media_menu: - remove: Ondoa moduli ya media -start_menu: - remove: Ondoa moduli ya kuanza +taskbar_menu: + settings: Mipangilio ya Fungua + start: Ongeza moduli ya kuanza + media: Ongeza moduli ya media +app_menu: + close_multiple: Funga yote + pin: Pini + open_file_location: Fungua eneo la faili + run_as: Kukimbia kama msimamizi + pin_to_left: Pini kushoto + copy_handles: Nakili Hushughulikia + close: Karibu + unpin: Unpin + pin_to_right: Pini kulia + pin_to_center: Pini katikati +media_menu: + remove: Ondoa moduli ya media +start_menu: + remove: Ondoa moduli ya kuanza diff --git a/src/apps/seelenweg/i18n/translations/ta.yml b/src/apps/seelenweg/i18n/translations/ta.yml index 17b22533..ff1b91c2 100644 --- a/src/apps/seelenweg/i18n/translations/ta.yml +++ b/src/apps/seelenweg/i18n/translations/ta.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: திறந்த அமைப்புகள் - media: மீடியா தொகுதி சேர்க்கவும் - start: தொடக்க தொகுதி சேர்க்கவும் -app_menu: - close: நெருக்கமான - run_as: நிர்வாகியாக செயல்படுங்கள் - close_multiple: அனைத்தையும் மூடு - copy_handles: நகல் கைப்பிடிகள் - pin_to_left: இடதுபுறம் முள் - pin_to_right: வலதுபுறம் முள் - pin_to_center: மையத்திற்கு முள் - pin: முள் - open_file_location: கோப்பு இருப்பிடத்தைத் திறக்கவும் - unpin: Unpin -media_menu: - remove: மீடியா தொகுதியை அகற்று -start_menu: - remove: தொடக்க தொகுதியை அகற்று +taskbar_menu: + settings: திறந்த அமைப்புகள் + media: மீடியா தொகுதி சேர்க்கவும் + start: தொடக்க தொகுதி சேர்க்கவும் +app_menu: + close: நெருக்கமான + run_as: நிர்வாகியாக செயல்படுங்கள் + close_multiple: அனைத்தையும் மூடு + copy_handles: நகல் கைப்பிடிகள் + pin_to_left: இடதுபுறம் முள் + pin_to_right: வலதுபுறம் முள் + pin_to_center: மையத்திற்கு முள் + pin: முள் + open_file_location: கோப்பு இருப்பிடத்தைத் திறக்கவும் + unpin: Unpin +media_menu: + remove: மீடியா தொகுதியை அகற்று +start_menu: + remove: தொடக்க தொகுதியை அகற்று diff --git a/src/apps/seelenweg/i18n/translations/te.yml b/src/apps/seelenweg/i18n/translations/te.yml index bad4ed18..456128fc 100644 --- a/src/apps/seelenweg/i18n/translations/te.yml +++ b/src/apps/seelenweg/i18n/translations/te.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: సెట్టింగులు తెరవండి - media: మీడియా మాడ్యూల్ జోడించండి - start: ప్రారంభ మాడ్యూల్ జోడించండి -app_menu: - close: దగ్గరగా - pin_to_center: పిన్ టు సెంటర్ - pin_to_left: పిన్ టు లెఫ్ట్ - open_file_location: ఫైల్ స్థానం తెరవండి - pin_to_right: కుడి నుండి పిన్ - unpin: అన్పిన్ - pin: పిన్ - copy_handles: కాపీ హ్యాండిల్స్ - close_multiple: అన్నీ మూసివేయండి - run_as: నిర్వాహకుడిగా అమలు చేయండి -media_menu: - remove: మీడియా మాడ్యూల్ తొలగించండి -start_menu: - remove: ప్రారంభ మాడ్యూల్ తొలగించండి +taskbar_menu: + settings: సెట్టింగులు తెరవండి + media: మీడియా మాడ్యూల్ జోడించండి + start: ప్రారంభ మాడ్యూల్ జోడించండి +app_menu: + close: దగ్గరగా + pin_to_center: పిన్ టు సెంటర్ + pin_to_left: పిన్ టు లెఫ్ట్ + open_file_location: ఫైల్ స్థానం తెరవండి + pin_to_right: కుడి నుండి పిన్ + unpin: అన్పిన్ + pin: పిన్ + copy_handles: కాపీ హ్యాండిల్స్ + close_multiple: అన్నీ మూసివేయండి + run_as: నిర్వాహకుడిగా అమలు చేయండి +media_menu: + remove: మీడియా మాడ్యూల్ తొలగించండి +start_menu: + remove: ప్రారంభ మాడ్యూల్ తొలగించండి diff --git a/src/apps/seelenweg/i18n/translations/tg.yml b/src/apps/seelenweg/i18n/translations/tg.yml index 763c4ad5..84f51909 100644 --- a/src/apps/seelenweg/i18n/translations/tg.yml +++ b/src/apps/seelenweg/i18n/translations/tg.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Иловаи модули ВАО - settings: Танзимоти кушода - start: Иловаи модули оғоз -app_menu: - copy_handles: Дасткор - pin_to_center: PIN ба марказ - pin_to_left: PIN ба чап - pin_to_right: PIN ба рост - close_multiple: Ҳамаашро пӯшед - pin: PIN - run_as: Ҳамчун мудир кор кунед - unpin: Ватанӣ - close: Наздик - open_file_location: Кушодани макони кушод -media_menu: - remove: Модули ВАО-ро хориҷ кунед -start_menu: - remove: Модули оғозро хориҷ кунед +taskbar_menu: + media: Иловаи модули ВАО + settings: Танзимоти кушода + start: Иловаи модули оғоз +app_menu: + copy_handles: Дасткор + pin_to_center: PIN ба марказ + pin_to_left: PIN ба чап + pin_to_right: PIN ба рост + close_multiple: Ҳамаашро пӯшед + pin: PIN + run_as: Ҳамчун мудир кор кунед + unpin: Ватанӣ + close: Наздик + open_file_location: Кушодани макони кушод +media_menu: + remove: Модули ВАО-ро хориҷ кунед +start_menu: + remove: Модули оғозро хориҷ кунед diff --git a/src/apps/seelenweg/i18n/translations/th.yml b/src/apps/seelenweg/i18n/translations/th.yml index 5ade29b0..989ee045 100644 --- a/src/apps/seelenweg/i18n/translations/th.yml +++ b/src/apps/seelenweg/i18n/translations/th.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: เปิดการตั้งค่า - start: เพิ่มโมดูลเริ่มต้น - media: เพิ่มโมดูลสื่อ -app_menu: - close: ปิด - pin: เข็มหมุด - pin_to_center: พินไปยังศูนย์ - open_file_location: เปิดตำแหน่งไฟล์ - unpin: คลาย - close_multiple: ปิดทั้งหมด - run_as: เรียกใช้เป็นผู้ดูแลระบบ - pin_to_right: พินไปทางขวา - pin_to_left: พินไปทางซ้าย - copy_handles: สำเนามือจับ -media_menu: - remove: ลบโมดูลสื่อ -start_menu: - remove: ลบโมดูลเริ่มต้น +taskbar_menu: + settings: เปิดการตั้งค่า + start: เพิ่มโมดูลเริ่มต้น + media: เพิ่มโมดูลสื่อ +app_menu: + close: ปิด + pin: เข็มหมุด + pin_to_center: พินไปยังศูนย์ + open_file_location: เปิดตำแหน่งไฟล์ + unpin: คลาย + close_multiple: ปิดทั้งหมด + run_as: เรียกใช้เป็นผู้ดูแลระบบ + pin_to_right: พินไปทางขวา + pin_to_left: พินไปทางซ้าย + copy_handles: สำเนามือจับ +media_menu: + remove: ลบโมดูลสื่อ +start_menu: + remove: ลบโมดูลเริ่มต้น diff --git a/src/apps/seelenweg/i18n/translations/tl.yml b/src/apps/seelenweg/i18n/translations/tl.yml index f0d6f229..7f0f3163 100644 --- a/src/apps/seelenweg/i18n/translations/tl.yml +++ b/src/apps/seelenweg/i18n/translations/tl.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Buksan ang settings - media: Magdagdag ng module ng media - start: Magdagdag ng Start Module -app_menu: - pin_to_left: Pin sa kaliwa - pin_to_center: Pin sa gitna - close_multiple: Isara ang lahat - close: Malapit - pin: Pin - pin_to_right: Pin sa kanan - run_as: Tumakbo bilang Administrator - unpin: Unpin - open_file_location: Buksan ang lokasyon ng file - copy_handles: Kopyahin ang mga hawakan -media_menu: - remove: Alisin ang module ng media -start_menu: - remove: Alisin ang Start Module +taskbar_menu: + settings: Buksan ang settings + media: Magdagdag ng module ng media + start: Magdagdag ng Start Module +app_menu: + pin_to_left: Pin sa kaliwa + pin_to_center: Pin sa gitna + close_multiple: Isara ang lahat + close: Malapit + pin: Pin + pin_to_right: Pin sa kanan + run_as: Tumakbo bilang Administrator + unpin: Unpin + open_file_location: Buksan ang lokasyon ng file + copy_handles: Kopyahin ang mga hawakan +media_menu: + remove: Alisin ang module ng media +start_menu: + remove: Alisin ang Start Module diff --git a/src/apps/seelenweg/i18n/translations/tr.yml b/src/apps/seelenweg/i18n/translations/tr.yml index 19636291..7669edac 100644 --- a/src/apps/seelenweg/i18n/translations/tr.yml +++ b/src/apps/seelenweg/i18n/translations/tr.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Ayarları aç - media: Medya Modülü Ekle - start: Başlat modülü ekle -app_menu: - open_file_location: Dosya konumunu aç - run_as: Yönetici olarak çalıştır - pin: Toplu iğne - close_multiple: Hepsini kapat - close: Kapalı - pin_to_center: Merkeze pin - copy_handles: Kopyala Kulpları - pin_to_right: Sağa sabit - unpin: Bitirmek - pin_to_left: Sola pin -media_menu: - remove: Medya Modülünü Kaldır -start_menu: - remove: Başlat modülü kaldır +taskbar_menu: + settings: Ayarları aç + media: Medya Modülü Ekle + start: Başlat modülü ekle +app_menu: + open_file_location: Dosya konumunu aç + run_as: Yönetici olarak çalıştır + pin: Toplu iğne + close_multiple: Hepsini kapat + close: Kapalı + pin_to_center: Merkeze pin + copy_handles: Kopyala Kulpları + pin_to_right: Sağa sabit + unpin: Bitirmek + pin_to_left: Sola pin +media_menu: + remove: Medya Modülünü Kaldır +start_menu: + remove: Başlat modülü kaldır diff --git a/src/apps/seelenweg/i18n/translations/uk.yml b/src/apps/seelenweg/i18n/translations/uk.yml index d67f7d54..79ae539e 100644 --- a/src/apps/seelenweg/i18n/translations/uk.yml +++ b/src/apps/seelenweg/i18n/translations/uk.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Додати медіа -модуль - start: Додайте модуль запуску - settings: Відкриті налаштування -app_menu: - run_as: Запустити від імені адміністратора - pin_to_center: Шпилька до центру - copy_handles: Копіювати ручки - open_file_location: Розташування відкритого файлу - close_multiple: Закрити все - pin_to_right: Праворуч праворуч - close: Закривати - unpin: Розмивати - pin: Шпилька - pin_to_left: Шпилька зліва -media_menu: - remove: Видалити медіа -модуль -start_menu: - remove: Зніміть модуль запуску +taskbar_menu: + media: Додати медіа -модуль + start: Додайте модуль запуску + settings: Відкриті налаштування +app_menu: + run_as: Запустити від імені адміністратора + pin_to_center: Шпилька до центру + copy_handles: Копіювати ручки + open_file_location: Розташування відкритого файлу + close_multiple: Закрити все + pin_to_right: Праворуч праворуч + close: Закривати + unpin: Розмивати + pin: Шпилька + pin_to_left: Шпилька зліва +media_menu: + remove: Видалити медіа -модуль +start_menu: + remove: Зніміть модуль запуску diff --git a/src/apps/seelenweg/i18n/translations/ur.yml b/src/apps/seelenweg/i18n/translations/ur.yml index 2860910c..07083eae 100644 --- a/src/apps/seelenweg/i18n/translations/ur.yml +++ b/src/apps/seelenweg/i18n/translations/ur.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: کھلی ترتیبات - media: میڈیا ماڈیول شامل کریں - start: اسٹارٹ ماڈیول شامل کریں -app_menu: - close_multiple: سب بند کرو - run_as: انتظامیہ کے طورپر چلانا - close: بند کریں - pin_to_left: بائیں سے پن - pin: پن - unpin: انپن - pin_to_right: دائیں سے دائیں - pin_to_center: سنٹر ٹو سینٹر - open_file_location: فائل کا مقام کھولیں - copy_handles: کاپی ہینڈلز -media_menu: - remove: میڈیا ماڈیول کو ہٹا دیں -start_menu: - remove: اسٹارٹ ماڈیول کو ہٹا دیں +taskbar_menu: + settings: کھلی ترتیبات + media: میڈیا ماڈیول شامل کریں + start: اسٹارٹ ماڈیول شامل کریں +app_menu: + close_multiple: سب بند کرو + run_as: انتظامیہ کے طورپر چلانا + close: بند کریں + pin_to_left: بائیں سے پن + pin: پن + unpin: انپن + pin_to_right: دائیں سے دائیں + pin_to_center: سنٹر ٹو سینٹر + open_file_location: فائل کا مقام کھولیں + copy_handles: کاپی ہینڈلز +media_menu: + remove: میڈیا ماڈیول کو ہٹا دیں +start_menu: + remove: اسٹارٹ ماڈیول کو ہٹا دیں diff --git a/src/apps/seelenweg/i18n/translations/uz.yml b/src/apps/seelenweg/i18n/translations/uz.yml index f464d07b..59ad7fd0 100644 --- a/src/apps/seelenweg/i18n/translations/uz.yml +++ b/src/apps/seelenweg/i18n/translations/uz.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Ochiq sozlamalar - start: Boshlash moduli qo'shing - media: Media modul qo'shing -app_menu: - unpin: Chetlashmoq - pin_to_right: O'ngga pin - close: Yaqin - close_multiple: Hammasini yaqin - open_file_location: Fayl joylashuvi - pin_to_center: Markazga PIN - run_as: Administrator sifatida yugurish - copy_handles: Nusxalash vositasi - pin: Pin - pin_to_left: Chapga o'ting -media_menu: - remove: Media modulini olib tashlang -start_menu: - remove: Boshlash moduliini olib tashlang +taskbar_menu: + settings: Ochiq sozlamalar + start: Boshlash moduli qo'shing + media: Media modul qo'shing +app_menu: + unpin: Chetlashmoq + pin_to_right: O'ngga pin + close: Yaqin + close_multiple: Hammasini yaqin + open_file_location: Fayl joylashuvi + pin_to_center: Markazga PIN + run_as: Administrator sifatida yugurish + copy_handles: Nusxalash vositasi + pin: Pin + pin_to_left: Chapga o'ting +media_menu: + remove: Media modulini olib tashlang +start_menu: + remove: Boshlash moduliini olib tashlang diff --git a/src/apps/seelenweg/i18n/translations/vi.yml b/src/apps/seelenweg/i18n/translations/vi.yml index 5e4d7de2..20bfb98c 100644 --- a/src/apps/seelenweg/i18n/translations/vi.yml +++ b/src/apps/seelenweg/i18n/translations/vi.yml @@ -1,19 +1,19 @@ -taskbar_menu: - settings: Mở cài đặt - media: Thêm mô -đun phương tiện - start: Thêm mô -đun bắt đầu -app_menu: - open_file_location: Mở vị trí file - close_multiple: Đóng tất cả - close: Đóng - run_as: Chạy như quản trị viên - pin: Ghim - pin_to_center: Ghim đến trung tâm - unpin: Giải nén - pin_to_left: Ghim sang trái - copy_handles: Sao chép tay cầm - pin_to_right: Ghim sang phải -media_menu: - remove: Loại bỏ mô -đun phương tiện -start_menu: - remove: Xóa mô -đun bắt đầu +taskbar_menu: + settings: Mở cài đặt + media: Thêm mô -đun phương tiện + start: Thêm mô -đun bắt đầu +app_menu: + open_file_location: Mở vị trí file + close_multiple: Đóng tất cả + close: Đóng + run_as: Chạy như quản trị viên + pin: Ghim + pin_to_center: Ghim đến trung tâm + unpin: Giải nén + pin_to_left: Ghim sang trái + copy_handles: Sao chép tay cầm + pin_to_right: Ghim sang phải +media_menu: + remove: Loại bỏ mô -đun phương tiện +start_menu: + remove: Xóa mô -đun bắt đầu diff --git a/src/apps/seelenweg/i18n/translations/yo.yml b/src/apps/seelenweg/i18n/translations/yo.yml index 92ca715d..e8a8c2b8 100644 --- a/src/apps/seelenweg/i18n/translations/yo.yml +++ b/src/apps/seelenweg/i18n/translations/yo.yml @@ -1,19 +1,19 @@ -taskbar_menu: - start: Ṣafikun module Bẹrẹ - media: Ṣafikun module Media - settings: Ṣi Eto -app_menu: - run_as: Run bi alakoso - pin_to_center: PIN si ile-iṣẹ - copy_handles: Daakọ mu - unpin: Ainidi - close: Sunmọ - pin_to_left: PIN si osi - close_multiple: Sunmọ gbogbo - open_file_location: Ṣii ipo faili ṣii - pin_to_right: Pin si ọtun - pin: Pini -media_menu: - remove: Mu Module Media kuro -start_menu: - remove: Yọ module bẹrẹ +taskbar_menu: + start: Ṣafikun module Bẹrẹ + media: Ṣafikun module Media + settings: Ṣi Eto +app_menu: + run_as: Run bi alakoso + pin_to_center: PIN si ile-iṣẹ + copy_handles: Daakọ mu + unpin: Ainidi + close: Sunmọ + pin_to_left: PIN si osi + close_multiple: Sunmọ gbogbo + open_file_location: Ṣii ipo faili ṣii + pin_to_right: Pin si ọtun + pin: Pini +media_menu: + remove: Mu Module Media kuro +start_menu: + remove: Yọ module bẹrẹ diff --git a/src/apps/seelenweg/i18n/translations/zh.yml b/src/apps/seelenweg/i18n/translations/zh.yml index 9b22eae9..fb49cb57 100644 --- a/src/apps/seelenweg/i18n/translations/zh.yml +++ b/src/apps/seelenweg/i18n/translations/zh.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: 添加媒体模块 - start: 添加启动模块 - settings: 打开设置 -app_menu: - unpin: 取消固定 - pin: 固定 - pin_to_left: 固定到左侧 - pin_to_center: 固定到中心 - pin_to_right: 固定到右侧 - open_file_location: 打开文件位置 - run_as: 以管理员身份运行 - copy_handles: 复制句柄 - close: 关闭 - close_multiple: 全部关闭 -media_menu: - remove: 移除媒体模块 -start_menu: - remove: 移除启动模块 +taskbar_menu: + media: 添加媒体模块 + start: 添加启动模块 + settings: 打开设置 +app_menu: + unpin: 取消固定 + pin: 固定 + pin_to_left: 固定到左侧 + pin_to_center: 固定到中心 + pin_to_right: 固定到右侧 + open_file_location: 打开文件位置 + run_as: 以管理员身份运行 + copy_handles: 复制句柄 + close: 关闭 + close_multiple: 全部关闭 +media_menu: + remove: 移除媒体模块 +start_menu: + remove: 移除启动模块 diff --git a/src/apps/seelenweg/i18n/translations/zu.yml b/src/apps/seelenweg/i18n/translations/zu.yml index 8893f347..f4dfea1d 100644 --- a/src/apps/seelenweg/i18n/translations/zu.yml +++ b/src/apps/seelenweg/i18n/translations/zu.yml @@ -1,19 +1,19 @@ -taskbar_menu: - media: Faka imodyuli yabezindaba - settings: Vula Izilungiselelo - start: Faka imodyuli yokuqala -app_menu: - pin_to_center: Pin esikhungweni - close: Ngokuminyanisa - close_multiple: Vala konke - open_file_location: Vula Indawo yefayela - pin_to_left: Pin kwesokunxele - pin_to_right: Pin kwesokudla - run_as: Gijima njengomlawuli - copy_handles: Kopisha izibambo - unpin: Unpin - pin: Isipeletu -media_menu: - remove: Susa imodyuli yabezindaba -start_menu: - remove: Susa imodyuli yokuqala +taskbar_menu: + media: Faka imodyuli yabezindaba + settings: Vula Izilungiselelo + start: Faka imodyuli yokuqala +app_menu: + pin_to_center: Pin esikhungweni + close: Ngokuminyanisa + close_multiple: Vala konke + open_file_location: Vula Indawo yefayela + pin_to_left: Pin kwesokunxele + pin_to_right: Pin kwesokudla + run_as: Gijima njengomlawuli + copy_handles: Kopisha izibambo + unpin: Unpin + pin: Isipeletu +media_menu: + remove: Susa imodyuli yabezindaba +start_menu: + remove: Susa imodyuli yokuqala diff --git a/src/apps/seelenweg/index.html b/src/apps/seelenweg/index.html index 8efb9d13..9466ecf5 100644 --- a/src/apps/seelenweg/index.html +++ b/src/apps/seelenweg/index.html @@ -1,13 +1,13 @@ - - - - - - - - - - -
- - + + + + + + + + + + +
+ + diff --git a/src/apps/seelenweg/index.tsx b/src/apps/seelenweg/index.tsx index 245d80c0..5f64e1ab 100644 --- a/src/apps/seelenweg/index.tsx +++ b/src/apps/seelenweg/index.tsx @@ -1,39 +1,39 @@ -import { getRootContainer } from '../shared'; -import { wrapConsole } from '../shared/ConsoleWrapper'; -import { registerDocumentEvents } from './events'; -import i18n, { loadTranslations } from './i18n'; -import { createRoot } from 'react-dom/client'; -import { I18nextProvider } from 'react-i18next'; -import { Provider } from 'react-redux'; - -import { loadStore, registerStoreEvents, store } from './modules/shared/store/infra'; -import { loadConstants } from './modules/shared/utils/infra'; - -import { App } from './app'; - -import './styles/colors.css'; -import './styles/variables.css'; -import './styles/reset.css'; -import './styles/global.css'; - -async function Main() { - wrapConsole(); - const container = getRootContainer(); - - registerDocumentEvents(); - - await loadConstants(); - await loadStore(); - await registerStoreEvents(); - await loadTranslations(); - - createRoot(container).render( - - - - - , - ); -} - -Main(); +import { getRootContainer } from '../shared'; +import { wrapConsole } from '../shared/ConsoleWrapper'; +import { registerDocumentEvents } from './events'; +import i18n, { loadTranslations } from './i18n'; +import { createRoot } from 'react-dom/client'; +import { I18nextProvider } from 'react-i18next'; +import { Provider } from 'react-redux'; + +import { loadStore, registerStoreEvents, store } from './modules/shared/store/infra'; +import { loadConstants } from './modules/shared/utils/infra'; + +import { App } from './app'; + +import './styles/colors.css'; +import './styles/variables.css'; +import './styles/reset.css'; +import './styles/global.css'; + +async function Main() { + wrapConsole(); + const container = getRootContainer(); + + registerDocumentEvents(); + + await loadConstants(); + await loadStore(); + await registerStoreEvents(); + await loadTranslations(); + + createRoot(container).render( + + + + + , + ); +} + +Main(); diff --git a/src/apps/seelenweg/modules/bar/app.ts b/src/apps/seelenweg/modules/bar/app.ts index e0fa16dd..ab10b33f 100644 --- a/src/apps/seelenweg/modules/bar/app.ts +++ b/src/apps/seelenweg/modules/bar/app.ts @@ -1,12 +1,12 @@ -import { parseAsCamel } from '../../../shared/schemas'; -import { Seelenweg, SeelenWegSchema } from '../../../shared/schemas/Seelenweg'; -import { createSlice } from '@reduxjs/toolkit'; - -const initialState: Seelenweg = parseAsCamel(SeelenWegSchema, {}); - -export const SeelenWegSlice = createSlice({ - name: 'seelenweg', - initialState, - reducers: {}, -}); - +import { parseAsCamel } from '../../../shared/schemas'; +import { Seelenweg, SeelenWegSchema } from '../../../shared/schemas/Seelenweg'; +import { createSlice } from '@reduxjs/toolkit'; + +const initialState: Seelenweg = parseAsCamel(SeelenWegSchema, {}); + +export const SeelenWegSlice = createSlice({ + name: 'seelenweg', + initialState, + reducers: {}, +}); + diff --git a/src/apps/seelenweg/modules/bar/index.css b/src/apps/seelenweg/modules/bar/index.css index eb7d3ef5..993418aa 100644 --- a/src/apps/seelenweg/modules/bar/index.css +++ b/src/apps/seelenweg/modules/bar/index.css @@ -1,27 +1,27 @@ - - -.side-container, .center-container { - display: flex; - gap: var(--config-space-between-items); - flex-direction: var(--config-by-position-flex-direction); - align-items: var(--config-by-position-align-items); - justify-content: var(--config-by-position-justify-content); - position: relative; -} - -.center-container { - position: absolute; - overflow: visible; - - .horizontal & { - height: var(--config-item-size); - left: 50%; - transform: translateX(-50%); - } - - .vertical & { - width: var(--config-item-size); - top: 50%; - transform: translateY(-50%); - } + + +.side-container, .center-container { + display: flex; + gap: var(--config-space-between-items); + flex-direction: var(--config-by-position-flex-direction); + align-items: var(--config-by-position-align-items); + justify-content: var(--config-by-position-justify-content); + position: relative; +} + +.center-container { + position: absolute; + overflow: visible; + + .horizontal & { + height: var(--config-item-size); + left: 50%; + transform: translateX(-50%); + } + + .vertical & { + width: var(--config-item-size); + top: 50%; + transform: translateY(-50%); + } } \ No newline at end of file diff --git a/src/apps/seelenweg/modules/bar/index.tsx b/src/apps/seelenweg/modules/bar/index.tsx index 0d4e1037..749d7cb3 100644 --- a/src/apps/seelenweg/modules/bar/index.tsx +++ b/src/apps/seelenweg/modules/bar/index.tsx @@ -1,178 +1,178 @@ -import { SeelenWegHideMode, SeelenWegMode, SeelenWegSide } from '../../../shared/schemas/Seelenweg'; -import { SavedSeparatorItem } from '../../../shared/schemas/SeelenWegItems'; -import { cx } from '../../../shared/styles'; -import { WithContextMenu } from '../../components/WithContextMenu'; -import { savePinnedItems } from '../shared/store/storeApi'; -import { getSeelenWegMenu } from './menu'; -import { Reorder } from 'framer-motion'; -import { useCallback, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useDispatch, useSelector } from 'react-redux'; - -import { BackgroundByLayersV2 } from '../../components/BackgroundByLayers/infra'; -import { MediaSession } from '../item/infra/MediaSession'; -import { StartMenu } from '../item/infra/StartMenu'; -import { UserApplication } from '../item/infra/UserApplication'; -import { useAppActivation, useAppBlur } from '../shared/hooks/infra'; - -import { RootActions, Selectors } from '../shared/store/app'; - -import { SpecialItemType, SwItem } from '../shared/store/domain'; - -import './index.css'; - -const Separator1: SavedSeparatorItem = { - type: SpecialItemType.Separator, -}; - -const Separator2: SavedSeparatorItem = { - type: SpecialItemType.Separator, -}; - -function shouldBeHidden(hideMode: SeelenWegHideMode, isActive: boolean, isOverlaped: boolean) { - let shouldBeHidden = false; - switch (hideMode) { - case SeelenWegHideMode.Always: - shouldBeHidden = !isActive; - break; - case SeelenWegHideMode.Never: - shouldBeHidden = false; - break; - case SeelenWegHideMode.OnOverlap: - shouldBeHidden = !isActive && isOverlaped; - } - return shouldBeHidden; -} - -export function SeelenWeg() { - const settings = useSelector(Selectors.settings); - const isOverlaped = useSelector(Selectors.isOverlaped); - - const pinnedOnLeft = useSelector(Selectors.itemsOnLeft); - const pinnedOnCenter = useSelector(Selectors.itemsOnCenter); - const pinnedOnRight = useSelector(Selectors.itemsOnRight); - - const [isActive, setActive] = useState(false); - - const dispatch = useDispatch(); - const { t } = useTranslation(); - - useAppBlur(() => { - setActive(false); - }, [settings]); - - useAppActivation(() => { - setActive(true); - }, [settings]); - - const getSeparatorComplementarySize = useCallback( - (sideElements: number, centerElements: number) => { - let size = '1px'; - - if (settings.mode === SeelenWegMode.FULL_WIDTH) { - size = `calc(50% - (${settings.size + settings.spaceBetweenItems}px * ${ - sideElements + centerElements / 2 - }) - ${settings.spaceBetweenItems}px)`; - } - - if (settings.position === SeelenWegSide.TOP || settings.position === SeelenWegSide.BOTTOM) { - return { - width: size, - }; - } - - return { - height: size, - }; - }, - [settings], - ); - - const onReorderPinned = useCallback((apps: (SavedSeparatorItem | SwItem)[]) => { - let extractedPinned: SwItem[] = []; - - apps.forEach((app) => { - if (app === Separator1) { - dispatch(RootActions.setItemsOnLeft(extractedPinned)); - extractedPinned = []; - return; - } - - if (app === Separator2) { - dispatch(RootActions.setItemsOnCenter(extractedPinned)); - extractedPinned = []; - return; - } - - if (app.type !== SpecialItemType.Separator) { - extractedPinned.push(app); - } - }); - - dispatch(RootActions.setItemsOnRight(extractedPinned)); - savePinnedItems(); - }, []); - - const isHorizontal = - settings.position === SeelenWegSide.TOP || settings.position === SeelenWegSide.BOTTOM; - - return ( - - - - {[ - ...pinnedOnLeft.map(ItemByType), - , - ...pinnedOnCenter.map(ItemByType), - , - ...pinnedOnRight.map(ItemByType), - ]} - - - ); -} - -function ItemByType(item: SwItem) { - if (item.type === SpecialItemType.PinnedApp || item.type === SpecialItemType.TemporalApp) { - return ; - } - - if (item.type === SpecialItemType.Media) { - return ; - } - - if (item.type === SpecialItemType.Start) { - return ; - } - - return null; -} +import { SeelenWegHideMode, SeelenWegMode, SeelenWegSide } from '../../../shared/schemas/Seelenweg'; +import { SavedSeparatorItem } from '../../../shared/schemas/SeelenWegItems'; +import { cx } from '../../../shared/styles'; +import { WithContextMenu } from '../../components/WithContextMenu'; +import { savePinnedItems } from '../shared/store/storeApi'; +import { getSeelenWegMenu } from './menu'; +import { Reorder } from 'framer-motion'; +import { useCallback, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useDispatch, useSelector } from 'react-redux'; + +import { BackgroundByLayersV2 } from '../../components/BackgroundByLayers/infra'; +import { MediaSession } from '../item/infra/MediaSession'; +import { StartMenu } from '../item/infra/StartMenu'; +import { UserApplication } from '../item/infra/UserApplication'; +import { useAppActivation, useAppBlur } from '../shared/hooks/infra'; + +import { RootActions, Selectors } from '../shared/store/app'; + +import { SpecialItemType, SwItem } from '../shared/store/domain'; + +import './index.css'; + +const Separator1: SavedSeparatorItem = { + type: SpecialItemType.Separator, +}; + +const Separator2: SavedSeparatorItem = { + type: SpecialItemType.Separator, +}; + +function shouldBeHidden(hideMode: SeelenWegHideMode, isActive: boolean, isOverlaped: boolean) { + let shouldBeHidden = false; + switch (hideMode) { + case SeelenWegHideMode.Always: + shouldBeHidden = !isActive; + break; + case SeelenWegHideMode.Never: + shouldBeHidden = false; + break; + case SeelenWegHideMode.OnOverlap: + shouldBeHidden = !isActive && isOverlaped; + } + return shouldBeHidden; +} + +export function SeelenWeg() { + const settings = useSelector(Selectors.settings); + const isOverlaped = useSelector(Selectors.isOverlaped); + + const pinnedOnLeft = useSelector(Selectors.itemsOnLeft); + const pinnedOnCenter = useSelector(Selectors.itemsOnCenter); + const pinnedOnRight = useSelector(Selectors.itemsOnRight); + + const [isActive, setActive] = useState(false); + + const dispatch = useDispatch(); + const { t } = useTranslation(); + + useAppBlur(() => { + setActive(false); + }, [settings]); + + useAppActivation(() => { + setActive(true); + }, [settings]); + + const getSeparatorComplementarySize = useCallback( + (sideElements: number, centerElements: number) => { + let size = '1px'; + + if (settings.mode === SeelenWegMode.FULL_WIDTH) { + size = `calc(50% - (${settings.size + settings.spaceBetweenItems}px * ${ + sideElements + centerElements / 2 + }) - ${settings.spaceBetweenItems}px)`; + } + + if (settings.position === SeelenWegSide.TOP || settings.position === SeelenWegSide.BOTTOM) { + return { + width: size, + }; + } + + return { + height: size, + }; + }, + [settings], + ); + + const onReorderPinned = useCallback((apps: (SavedSeparatorItem | SwItem)[]) => { + let extractedPinned: SwItem[] = []; + + apps.forEach((app) => { + if (app === Separator1) { + dispatch(RootActions.setItemsOnLeft(extractedPinned)); + extractedPinned = []; + return; + } + + if (app === Separator2) { + dispatch(RootActions.setItemsOnCenter(extractedPinned)); + extractedPinned = []; + return; + } + + if (app.type !== SpecialItemType.Separator) { + extractedPinned.push(app); + } + }); + + dispatch(RootActions.setItemsOnRight(extractedPinned)); + savePinnedItems(); + }, []); + + const isHorizontal = + settings.position === SeelenWegSide.TOP || settings.position === SeelenWegSide.BOTTOM; + + return ( + + + + {[ + ...pinnedOnLeft.map(ItemByType), + , + ...pinnedOnCenter.map(ItemByType), + , + ...pinnedOnRight.map(ItemByType), + ]} + + + ); +} + +function ItemByType(item: SwItem) { + if (item.type === SpecialItemType.PinnedApp || item.type === SpecialItemType.TemporalApp) { + return ; + } + + if (item.type === SpecialItemType.Media) { + return ; + } + + if (item.type === SpecialItemType.Start) { + return ; + } + + return null; +} diff --git a/src/apps/seelenweg/modules/bar/menu.tsx b/src/apps/seelenweg/modules/bar/menu.tsx index 128415eb..31caba93 100644 --- a/src/apps/seelenweg/modules/bar/menu.tsx +++ b/src/apps/seelenweg/modules/bar/menu.tsx @@ -1,142 +1,142 @@ -import { savePinnedItems } from '../shared/store/storeApi'; -import { invoke } from '@tauri-apps/api/core'; -import { Menu, MenuProps, Popover } from 'antd'; -import { ItemType } from 'antd/es/menu/interface'; -import { TFunction } from 'i18next'; - -import { BackgroundByLayersV2 } from '../../components/BackgroundByLayers/infra'; -import { store } from '../shared/store/infra'; - -import { isPinnedApp, isTemporalApp, RootActions } from '../shared/store/app'; - -import { AppsSides, SwPinnedApp, SwTemporalApp } from '../shared/store/domain'; - -export function getSeelenWegMenu(t: TFunction): ItemType[] { - return [ - { - key: 'add-media-module', - label: t('taskbar_menu.media'), - onClick() { - store.dispatch(RootActions.addMediaModule()); - }, - }, - { - key: 'add-start-module', - label: t('taskbar_menu.start'), - onClick() { - store.dispatch(RootActions.addStartModule()); - }, - }, - { - key: 'settings', - label: t('taskbar_menu.settings'), - onClick() { - invoke('show_app_settings'); - }, - }, - ]; -} - -export function getMenuForItem(t: TFunction, item: SwPinnedApp | SwTemporalApp): ItemType[] { - const isPinned = isPinnedApp(item); - - const pin = (side: AppsSides) => { - if (isTemporalApp(item)) { - store.dispatch(RootActions.pinApp({ app: item, side })); - savePinnedItems(); - } - }; - - const menu: MenuProps['items'] = []; - - if (isPinned) { - menu.push({ - label: t('app_menu.unpin'), - key: 'weg_unpin_app', - onClick: () => { - store.dispatch(RootActions.unPin(item)); - savePinnedItems(); - }, - }); - } else { - menu.push({ - key: 'weg_pin_app', - label: ( - - pin(AppsSides.Left), - }, - { - key: 'weg_pin_app_center', - label: t('app_menu.pin_to_center'), - onClick: () => pin(AppsSides.Center), - }, - { - key: 'weg_pin_app_right', - label: t('app_menu.pin_to_right'), - onClick: () => pin(AppsSides.Right), - }, - ]} - /> - - } - > -
- {t('app_menu.pin')} -
- - ), - }); - } - - menu.push( - { - type: 'divider', - }, - { - key: 'weg_select_file_on_explorer', - label: t('app_menu.open_file_location'), - onClick: () => invoke('select_file_on_explorer', { path: item.exe }), - }, - { - key: 'weg_runas', - label: t('app_menu.run_as'), - onClick: () => invoke('run_as_admin', { path: item.execution_path }), - }, - ); - - if (item.opens.length) { - menu.push( - { - key: 'weg_copy_hwnd', - label: t('app_menu.copy_handles'), - onClick: () => - navigator.clipboard.writeText( - JSON.stringify(item.opens.map((hwnd) => hwnd.toString(16))), - ), - }, - { - key: 'weg_close_app', - label: item.opens.length > 1 ? t('app_menu.close_multiple') : t('app_menu.close'), - onClick() { - item.opens.forEach((hwnd) => { - invoke('weg_close_app', { hwnd }); - }); - }, - danger: true, - }, - ); - } - - return menu; -} +import { savePinnedItems } from '../shared/store/storeApi'; +import { invoke } from '@tauri-apps/api/core'; +import { Menu, MenuProps, Popover } from 'antd'; +import { ItemType } from 'antd/es/menu/interface'; +import { TFunction } from 'i18next'; + +import { BackgroundByLayersV2 } from '../../components/BackgroundByLayers/infra'; +import { store } from '../shared/store/infra'; + +import { isPinnedApp, isTemporalApp, RootActions } from '../shared/store/app'; + +import { AppsSides, SwPinnedApp, SwTemporalApp } from '../shared/store/domain'; + +export function getSeelenWegMenu(t: TFunction): ItemType[] { + return [ + { + key: 'add-media-module', + label: t('taskbar_menu.media'), + onClick() { + store.dispatch(RootActions.addMediaModule()); + }, + }, + { + key: 'add-start-module', + label: t('taskbar_menu.start'), + onClick() { + store.dispatch(RootActions.addStartModule()); + }, + }, + { + key: 'settings', + label: t('taskbar_menu.settings'), + onClick() { + invoke('show_app_settings'); + }, + }, + ]; +} + +export function getMenuForItem(t: TFunction, item: SwPinnedApp | SwTemporalApp): ItemType[] { + const isPinned = isPinnedApp(item); + + const pin = (side: AppsSides) => { + if (isTemporalApp(item)) { + store.dispatch(RootActions.pinApp({ app: item, side })); + savePinnedItems(); + } + }; + + const menu: MenuProps['items'] = []; + + if (isPinned) { + menu.push({ + label: t('app_menu.unpin'), + key: 'weg_unpin_app', + onClick: () => { + store.dispatch(RootActions.unPin(item)); + savePinnedItems(); + }, + }); + } else { + menu.push({ + key: 'weg_pin_app', + label: ( + + pin(AppsSides.Left), + }, + { + key: 'weg_pin_app_center', + label: t('app_menu.pin_to_center'), + onClick: () => pin(AppsSides.Center), + }, + { + key: 'weg_pin_app_right', + label: t('app_menu.pin_to_right'), + onClick: () => pin(AppsSides.Right), + }, + ]} + /> + + } + > +
+ {t('app_menu.pin')} +
+ + ), + }); + } + + menu.push( + { + type: 'divider', + }, + { + key: 'weg_select_file_on_explorer', + label: t('app_menu.open_file_location'), + onClick: () => invoke('select_file_on_explorer', { path: item.exe }), + }, + { + key: 'weg_runas', + label: t('app_menu.run_as'), + onClick: () => invoke('run_as_admin', { path: item.execution_path }), + }, + ); + + if (item.opens.length) { + menu.push( + { + key: 'weg_copy_hwnd', + label: t('app_menu.copy_handles'), + onClick: () => + navigator.clipboard.writeText( + JSON.stringify(item.opens.map((hwnd) => hwnd.toString(16))), + ), + }, + { + key: 'weg_close_app', + label: item.opens.length > 1 ? t('app_menu.close_multiple') : t('app_menu.close'), + onClick() { + item.opens.forEach((hwnd) => { + invoke('weg_close_app', { hwnd }); + }); + }, + danger: true, + }, + ); + } + + return menu; +} diff --git a/src/apps/seelenweg/modules/item/app/PinnedApp.ts b/src/apps/seelenweg/modules/item/app/PinnedApp.ts index bedd6ed6..6f71ecc2 100644 --- a/src/apps/seelenweg/modules/item/app/PinnedApp.ts +++ b/src/apps/seelenweg/modules/item/app/PinnedApp.ts @@ -1,28 +1,28 @@ -import { SavedPinnedApp } from '../../../../shared/schemas/SeelenWegItems'; -import { convertFileSrc, invoke } from '@tauri-apps/api/core'; - -import { getImageBase64FromUrl, LAZY_CONSTANTS } from '../../shared/utils/infra'; - -import { SpecialItemType, SwPinnedApp } from '../../shared/store/domain'; - -export class SwPinnedAppUtils { - static async fromSaved(item: SavedPinnedApp): Promise { - let icon = ''; - let icon_path = await invoke('get_icon', { path: item.exe }) || LAZY_CONSTANTS.MISSING_ICON_PATH; - - try { - icon = await getImageBase64FromUrl(convertFileSrc(icon_path)); - } catch { - icon = convertFileSrc(icon_path); - } - - return { - type: SpecialItemType.PinnedApp, - icon, - exe: item.exe, - execution_path: item.execution_path, - title: '', - opens: [], - }; - } -} +import { SavedPinnedApp } from '../../../../shared/schemas/SeelenWegItems'; +import { convertFileSrc, invoke } from '@tauri-apps/api/core'; + +import { getImageBase64FromUrl, LAZY_CONSTANTS } from '../../shared/utils/infra'; + +import { SpecialItemType, SwPinnedApp } from '../../shared/store/domain'; + +export class SwPinnedAppUtils { + static async fromSaved(item: SavedPinnedApp): Promise { + let icon = ''; + let icon_path = await invoke('get_icon', { path: item.exe }) || LAZY_CONSTANTS.MISSING_ICON_PATH; + + try { + icon = await getImageBase64FromUrl(convertFileSrc(icon_path)); + } catch { + icon = convertFileSrc(icon_path); + } + + return { + type: SpecialItemType.PinnedApp, + icon, + exe: item.exe, + execution_path: item.execution_path, + title: '', + opens: [], + }; + } +} diff --git a/src/apps/seelenweg/modules/item/app/TemporalApp.ts b/src/apps/seelenweg/modules/item/app/TemporalApp.ts index 1928109f..32cd7d88 100644 --- a/src/apps/seelenweg/modules/item/app/TemporalApp.ts +++ b/src/apps/seelenweg/modules/item/app/TemporalApp.ts @@ -1,32 +1,32 @@ -import { convertFileSrc } from '@tauri-apps/api/core'; - -import { fs } from '../../../../settings/modules/shared/tauri/infra'; -import { getImageBase64FromUrl, LAZY_CONSTANTS } from '../../shared/utils/infra'; - -import { AppFromBackground, SpecialItemType, SwTemporalApp } from '../../shared/store/domain'; - -export class SwTemporalAppUtils { - static async clean(item: AppFromBackground): Promise { - if (!(await fs.exists(item.icon_path))) { - item.icon_path = LAZY_CONSTANTS.MISSING_ICON_PATH; - } - - try { - item.icon = await getImageBase64FromUrl(convertFileSrc(item.icon_path)); - } catch { - item.icon = convertFileSrc(item.icon_path); - } - return item; - } - - static fromBackground(item: AppFromBackground): SwTemporalApp { - return { - type: SpecialItemType.TemporalApp, - icon: item.icon || '', - exe: item.exe, - execution_path: item.execution_path, - title: item.exe.split('\\').at(-1) || 'Unknown', - opens: [item.hwnd], - }; - } -} +import { convertFileSrc } from '@tauri-apps/api/core'; + +import { fs } from '../../../../settings/modules/shared/tauri/infra'; +import { getImageBase64FromUrl, LAZY_CONSTANTS } from '../../shared/utils/infra'; + +import { AppFromBackground, SpecialItemType, SwTemporalApp } from '../../shared/store/domain'; + +export class SwTemporalAppUtils { + static async clean(item: AppFromBackground): Promise { + if (!(await fs.exists(item.icon_path))) { + item.icon_path = LAZY_CONSTANTS.MISSING_ICON_PATH; + } + + try { + item.icon = await getImageBase64FromUrl(convertFileSrc(item.icon_path)); + } catch { + item.icon = convertFileSrc(item.icon_path); + } + return item; + } + + static fromBackground(item: AppFromBackground): SwTemporalApp { + return { + type: SpecialItemType.TemporalApp, + icon: item.icon || '', + exe: item.exe, + execution_path: item.execution_path, + title: item.exe.split('\\').at(-1) || 'Unknown', + opens: [item.hwnd], + }; + } +} diff --git a/src/apps/seelenweg/modules/item/infra/DraggableItem.tsx b/src/apps/seelenweg/modules/item/infra/DraggableItem.tsx index ddf40eb4..7077584d 100644 --- a/src/apps/seelenweg/modules/item/infra/DraggableItem.tsx +++ b/src/apps/seelenweg/modules/item/infra/DraggableItem.tsx @@ -1,35 +1,35 @@ -import { Reorder } from 'framer-motion'; -import { PropsWithChildren, useRef } from 'react'; - -import { SwItem } from '../../shared/store/domain'; - -interface Props extends PropsWithChildren { - item: SwItem; -} - -export function DraggableItem({ children, item }: Props) { - const isDragging = useRef(false); - - return ( - { - isDragging.current = true; - }} - onDragEnd={() => { - setTimeout(() => { - isDragging.current = false; - }, 150); - }} - onClickCapture={(e) => { - if (isDragging.current) { - e.stopPropagation(); - } - }} - > - {children} - - ); -} +import { Reorder } from 'framer-motion'; +import { PropsWithChildren, useRef } from 'react'; + +import { SwItem } from '../../shared/store/domain'; + +interface Props extends PropsWithChildren { + item: SwItem; +} + +export function DraggableItem({ children, item }: Props) { + const isDragging = useRef(false); + + return ( + { + isDragging.current = true; + }} + onDragEnd={() => { + setTimeout(() => { + isDragging.current = false; + }, 150); + }} + onClickCapture={(e) => { + if (isDragging.current) { + e.stopPropagation(); + } + }} + > + {children} + + ); +} diff --git a/src/apps/seelenweg/modules/item/infra/MediaSession.css b/src/apps/seelenweg/modules/item/infra/MediaSession.css index 4777d144..99ceec67 100644 --- a/src/apps/seelenweg/modules/item/infra/MediaSession.css +++ b/src/apps/seelenweg/modules/item/infra/MediaSession.css @@ -1,60 +1,60 @@ -.media-session-container { - border-radius: 10px; - box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5); -} - -.media-session { - display: grid; - grid-template-columns: var(--config-item-size) 1fr; - height: var(--config-item-size); - width: calc( - var(--config-item-size) * 3 + var(--config-space-between-items) * 2 - ); /* 3 items + 2 spaces between */ - position: relative; - overflow: hidden; - border-radius: 10px; - - .media-session-thumbnail { - z-index: 2; - width: 100%; - aspect-ratio: 1/1; - object-fit: contain; - background: #0004; - } - - .media-session-blurred-thumbnail { - filter: blur(10px) brightness(125%) contrast(125%); - position: absolute; - width: 100%; - height: 100%; - object-fit: fill; - } - - .media-session-info { - position: relative; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - overflow: hidden; - padding: 4px; - - .media-session-title { - font-size: 0.7rem; - line-height: 1rem; - font-weight: 600; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - max-width: 100%; - } - - .media-session-actions { - height: 16px; - .ant-btn { - color: inherit !important; - height: 16px; - } - } - } -} +.media-session-container { + border-radius: 10px; + box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5); +} + +.media-session { + display: grid; + grid-template-columns: var(--config-item-size) 1fr; + height: var(--config-item-size); + width: calc( + var(--config-item-size) * 3 + var(--config-space-between-items) * 2 + ); /* 3 items + 2 spaces between */ + position: relative; + overflow: hidden; + border-radius: 10px; + + .media-session-thumbnail { + z-index: 2; + width: 100%; + aspect-ratio: 1/1; + object-fit: contain; + background: #0004; + } + + .media-session-blurred-thumbnail { + filter: blur(10px) brightness(125%) contrast(125%); + position: absolute; + width: 100%; + height: 100%; + object-fit: fill; + } + + .media-session-info { + position: relative; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + overflow: hidden; + padding: 4px; + + .media-session-title { + font-size: 0.7rem; + line-height: 1rem; + font-weight: 600; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + max-width: 100%; + } + + .media-session-actions { + height: 16px; + .ant-btn { + color: inherit !important; + height: 16px; + } + } + } +} diff --git a/src/apps/seelenweg/modules/item/infra/MediaSession.tsx b/src/apps/seelenweg/modules/item/infra/MediaSession.tsx index cdf7f341..139c0633 100644 --- a/src/apps/seelenweg/modules/item/infra/MediaSession.tsx +++ b/src/apps/seelenweg/modules/item/infra/MediaSession.tsx @@ -1,97 +1,97 @@ -import { Icon } from '../../../../shared/components/Icon'; -import { SavedMediaItem } from '../../../../shared/schemas/SeelenWegItems'; -import { WithContextMenu } from '../../../components/WithContextMenu'; -import { DraggableItem } from './DraggableItem'; -import { getMenuForItem } from './Menu'; -import { convertFileSrc, invoke } from '@tauri-apps/api/core'; -import { emit } from '@tauri-apps/api/event'; -import { Button } from 'antd'; -import { useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; - -import { LAZY_CONSTANTS } from '../../shared/utils/infra'; - -import { calcLuminance } from '../../../../toolbar/modules/media/application'; -import { Selectors } from '../../shared/store/app'; - -import './MediaSession.css'; - -const MAX_LUMINANCE = 210; -const MIN_LUMINANCE = 40; -const BRIGHTNESS_MULTIPLIER = 1.5; // used in css - -export function MediaSession({ item }: { item: SavedMediaItem }) { - const [luminance, setLuminance] = useState(0); - - const sessions = useSelector(Selectors.mediaSessions); - const session = sessions.find((s) => s.default); - - let src = convertFileSrc( - session?.thumbnail ? session.thumbnail : LAZY_CONSTANTS.DEFAULT_THUMBNAIL, - ); - - const { t } = useTranslation(); - - useEffect(() => { - calcLuminance(src).then(setLuminance).catch(console.error); - }, [src]); - - useEffect(() => { - emit('register-media-events'); - }, []); - - const filteredLuminance = Math.max( - Math.min(luminance * BRIGHTNESS_MULTIPLIER, MAX_LUMINANCE), - MIN_LUMINANCE, - ); - const color = filteredLuminance < 125 ? '#efefef' : '#222222'; - - const onClickBtn = (cmd: string) => { - if (session) { - invoke(cmd, { id: session.id }).catch(console.error); - } - }; - - return ( - - -
e.stopPropagation()}> -
- - - -
- - {session?.title || 'No Media'} - -
- - - -
-
-
-
-
-
- ); -} +import { Icon } from '../../../../shared/components/Icon'; +import { SavedMediaItem } from '../../../../shared/schemas/SeelenWegItems'; +import { WithContextMenu } from '../../../components/WithContextMenu'; +import { DraggableItem } from './DraggableItem'; +import { getMenuForItem } from './Menu'; +import { convertFileSrc, invoke } from '@tauri-apps/api/core'; +import { emit } from '@tauri-apps/api/event'; +import { Button } from 'antd'; +import { useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; + +import { LAZY_CONSTANTS } from '../../shared/utils/infra'; + +import { calcLuminance } from '../../../../toolbar/modules/media/application'; +import { Selectors } from '../../shared/store/app'; + +import './MediaSession.css'; + +const MAX_LUMINANCE = 210; +const MIN_LUMINANCE = 40; +const BRIGHTNESS_MULTIPLIER = 1.5; // used in css + +export function MediaSession({ item }: { item: SavedMediaItem }) { + const [luminance, setLuminance] = useState(0); + + const sessions = useSelector(Selectors.mediaSessions); + const session = sessions.find((s) => s.default); + + let src = convertFileSrc( + session?.thumbnail ? session.thumbnail : LAZY_CONSTANTS.DEFAULT_THUMBNAIL, + ); + + const { t } = useTranslation(); + + useEffect(() => { + calcLuminance(src).then(setLuminance).catch(console.error); + }, [src]); + + useEffect(() => { + emit('register-media-events'); + }, []); + + const filteredLuminance = Math.max( + Math.min(luminance * BRIGHTNESS_MULTIPLIER, MAX_LUMINANCE), + MIN_LUMINANCE, + ); + const color = filteredLuminance < 125 ? '#efefef' : '#222222'; + + const onClickBtn = (cmd: string) => { + if (session) { + invoke(cmd, { id: session.id }).catch(console.error); + } + }; + + return ( + + +
e.stopPropagation()}> +
+ + + +
+ + {session?.title || 'No Media'} + +
+ + + +
+
+
+
+
+
+ ); +} diff --git a/src/apps/seelenweg/modules/item/infra/Menu.tsx b/src/apps/seelenweg/modules/item/infra/Menu.tsx index 31233973..f18b518c 100644 --- a/src/apps/seelenweg/modules/item/infra/Menu.tsx +++ b/src/apps/seelenweg/modules/item/infra/Menu.tsx @@ -1,37 +1,37 @@ -import { SwItemType } from '../../../../shared/schemas/SeelenWegItems'; -import { ItemType } from 'antd/es/menu/interface'; -import { TFunction } from 'i18next'; - -import { store } from '../../shared/store/infra'; - -import { RootActions } from '../../shared/store/app'; - -import { SwItem } from '../../shared/store/domain'; - -export function getMenuForItem(t: TFunction, item: SwItem): ItemType[] { - if (item.type === SwItemType.Media) { - return [ - { - key: 'remove', - label: t('media_menu.remove'), - onClick() { - store.dispatch(RootActions.removeMediaModule()); - }, - }, - ]; - } - - if (item.type === SwItemType.Start) { - return [ - { - key: 'remove', - label: t('start_menu.remove'), - onClick() { - store.dispatch(RootActions.removeStartModule()); - }, - }, - ]; - } - - return []; -} +import { SwItemType } from '../../../../shared/schemas/SeelenWegItems'; +import { ItemType } from 'antd/es/menu/interface'; +import { TFunction } from 'i18next'; + +import { store } from '../../shared/store/infra'; + +import { RootActions } from '../../shared/store/app'; + +import { SwItem } from '../../shared/store/domain'; + +export function getMenuForItem(t: TFunction, item: SwItem): ItemType[] { + if (item.type === SwItemType.Media) { + return [ + { + key: 'remove', + label: t('media_menu.remove'), + onClick() { + store.dispatch(RootActions.removeMediaModule()); + }, + }, + ]; + } + + if (item.type === SwItemType.Start) { + return [ + { + key: 'remove', + label: t('start_menu.remove'), + onClick() { + store.dispatch(RootActions.removeStartModule()); + }, + }, + ]; + } + + return []; +} diff --git a/src/apps/seelenweg/modules/item/infra/StartMenu.tsx b/src/apps/seelenweg/modules/item/infra/StartMenu.tsx index 6d1b214d..d49b580a 100644 --- a/src/apps/seelenweg/modules/item/infra/StartMenu.tsx +++ b/src/apps/seelenweg/modules/item/infra/StartMenu.tsx @@ -1,67 +1,67 @@ -import { StartMenuItem } from '../../../../shared/schemas/SeelenWegItems'; -import { WithContextMenu } from '../../../components/WithContextMenu'; -import { DraggableItem } from './DraggableItem'; -import { getMenuForItem } from './Menu'; -import { invoke } from '@tauri-apps/api/core'; -import { motion } from 'framer-motion'; -import { memo, useEffect, useRef } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; - -import { BackgroundByLayersV2 } from '../../../components/BackgroundByLayers/infra'; - -import { Selectors } from '../../shared/store/app'; - -import { RootState } from '../../shared/store/domain'; - -interface Props { - item: StartMenuItem; -} - -const startMenuExes = ['SearchHost.exe', 'StartMenuExperienceHost.exe']; - -export const StartMenu = memo(({ item }: Props) => { - const startMenuOpenRef = useRef(false); - - const size = useSelector(Selectors.settings.size); - - const isStartMenuOpen = useSelector((state: RootState) => - startMenuExes.includes(Selectors.focusedExecutable(state)), - ); - - const { t } = useTranslation(); - - useEffect(() => { - if (!isStartMenuOpen) { - setTimeout(() => { - startMenuOpenRef.current = isStartMenuOpen; - }, 100); - } else { - startMenuOpenRef.current = isStartMenuOpen; - } - }, [isStartMenuOpen]); - - return ( - - - { - if (!startMenuOpenRef.current) { - invoke('send_keys', { keys: '{win}' }); - } - }} - onContextMenu={(e) => e.stopPropagation()} - > - -
-
-
- - - - ); -}); +import { StartMenuItem } from '../../../../shared/schemas/SeelenWegItems'; +import { WithContextMenu } from '../../../components/WithContextMenu'; +import { DraggableItem } from './DraggableItem'; +import { getMenuForItem } from './Menu'; +import { invoke } from '@tauri-apps/api/core'; +import { motion } from 'framer-motion'; +import { memo, useEffect, useRef } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; + +import { BackgroundByLayersV2 } from '../../../components/BackgroundByLayers/infra'; + +import { Selectors } from '../../shared/store/app'; + +import { RootState } from '../../shared/store/domain'; + +interface Props { + item: StartMenuItem; +} + +const startMenuExes = ['SearchHost.exe', 'StartMenuExperienceHost.exe']; + +export const StartMenu = memo(({ item }: Props) => { + const startMenuOpenRef = useRef(false); + + const size = useSelector(Selectors.settings.size); + + const isStartMenuOpen = useSelector((state: RootState) => + startMenuExes.includes(Selectors.focusedExecutable(state)), + ); + + const { t } = useTranslation(); + + useEffect(() => { + if (!isStartMenuOpen) { + setTimeout(() => { + startMenuOpenRef.current = isStartMenuOpen; + }, 100); + } else { + startMenuOpenRef.current = isStartMenuOpen; + } + }, [isStartMenuOpen]); + + return ( + + + { + if (!startMenuOpenRef.current) { + invoke('send_keys', { keys: '{win}' }); + } + }} + onContextMenu={(e) => e.stopPropagation()} + > + +
+
+
+ + + + ); +}); diff --git a/src/apps/seelenweg/modules/item/infra/UserApplication.tsx b/src/apps/seelenweg/modules/item/infra/UserApplication.tsx index ccbdfca6..542b544d 100644 --- a/src/apps/seelenweg/modules/item/infra/UserApplication.tsx +++ b/src/apps/seelenweg/modules/item/infra/UserApplication.tsx @@ -1,95 +1,95 @@ -import { cx } from '../../../../shared/styles'; -import { WithContextMenu } from '../../../components/WithContextMenu'; -import { getMenuForItem } from '../../bar/menu'; -import { DraggableItem } from './DraggableItem'; -import { UserApplicationPreview } from './UserApplicationPreview'; -import { invoke } from '@tauri-apps/api/core'; -import { Popover } from 'antd'; -import { motion } from 'framer-motion'; -import { memo, useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; - -import { BackgroundByLayersV2 } from '../../../components/BackgroundByLayers/infra'; -import { useAppBlur } from '../../shared/hooks/infra'; -import { updatePreviews } from '../../shared/utils/infra'; - -import { Selectors } from '../../shared/store/app'; - -import { RootState, SwPinnedApp, SwTemporalApp } from '../../shared/store/domain'; - -interface Props { - item: SwPinnedApp | SwTemporalApp; -} - -export const UserApplication = memo(({ item }: Props) => { - const size = useSelector(Selectors.settings.size); - const isFocused = useSelector((state: RootState) => item.opens.includes(state.focusedHandle)); - - const [openPreview, setOpenPreview] = useState(false); - - const { t } = useTranslation(); - - useAppBlur(() => { - setOpenPreview(false); - }); - - useEffect(() => { - if (openPreview) { - updatePreviews(item.opens); - } - }, [openPreview]); - - useEffect(() => { - if (!item.opens.length) { - setOpenPreview(false); - } - }, [item]); - - return ( - - - setOpenPreview(open && !!item.opens.length)} - trigger="hover" - arrow={false} - content={ - e.stopPropagation()} - prefix="preview" - > - {item.opens.map((hwnd) => ( - - ))} - - } - > - { - let hwnd = item.opens[0] || 0; - invoke('weg_toggle_window_state', { hwnd, exePath: item.execution_path }); - }} - onContextMenu={(e) => e.stopPropagation()} - > - - -
- - - - - ); -}); +import { cx } from '../../../../shared/styles'; +import { WithContextMenu } from '../../../components/WithContextMenu'; +import { getMenuForItem } from '../../bar/menu'; +import { DraggableItem } from './DraggableItem'; +import { UserApplicationPreview } from './UserApplicationPreview'; +import { invoke } from '@tauri-apps/api/core'; +import { Popover } from 'antd'; +import { motion } from 'framer-motion'; +import { memo, useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; + +import { BackgroundByLayersV2 } from '../../../components/BackgroundByLayers/infra'; +import { useAppBlur } from '../../shared/hooks/infra'; +import { updatePreviews } from '../../shared/utils/infra'; + +import { Selectors } from '../../shared/store/app'; + +import { RootState, SwPinnedApp, SwTemporalApp } from '../../shared/store/domain'; + +interface Props { + item: SwPinnedApp | SwTemporalApp; +} + +export const UserApplication = memo(({ item }: Props) => { + const size = useSelector(Selectors.settings.size); + const isFocused = useSelector((state: RootState) => item.opens.includes(state.focusedHandle)); + + const [openPreview, setOpenPreview] = useState(false); + + const { t } = useTranslation(); + + useAppBlur(() => { + setOpenPreview(false); + }); + + useEffect(() => { + if (openPreview) { + updatePreviews(item.opens); + } + }, [openPreview]); + + useEffect(() => { + if (!item.opens.length) { + setOpenPreview(false); + } + }, [item]); + + return ( + + + setOpenPreview(open && !!item.opens.length)} + trigger="hover" + arrow={false} + content={ + e.stopPropagation()} + prefix="preview" + > + {item.opens.map((hwnd) => ( + + ))} + + } + > + { + let hwnd = item.opens[0] || 0; + invoke('weg_toggle_window_state', { hwnd, exePath: item.execution_path }); + }} + onContextMenu={(e) => e.stopPropagation()} + > + + +
+ + + + + ); +}); diff --git a/src/apps/seelenweg/modules/item/infra/UserApplicationPreview.tsx b/src/apps/seelenweg/modules/item/infra/UserApplicationPreview.tsx index 08c25b6e..0dffdab5 100644 --- a/src/apps/seelenweg/modules/item/infra/UserApplicationPreview.tsx +++ b/src/apps/seelenweg/modules/item/infra/UserApplicationPreview.tsx @@ -1,71 +1,71 @@ -import { Icon } from '../../../../shared/components/Icon'; -import { convertFileSrc, invoke } from '@tauri-apps/api/core'; -import { listen } from '@tauri-apps/api/event'; -import { Spin } from 'antd'; -import { MouseEvent, useEffect, useReducer, useState } from 'react'; -import { useSelector } from 'react-redux'; - -import { LAZY_CONSTANTS } from '../../shared/utils/infra'; - -import { SelectOpenApp } from '../../shared/store/app'; - -import { HWND } from '../../shared/store/domain'; - -interface PreviewProps { - hwnd: HWND; -} - -export const UserApplicationPreview = ({ hwnd }: PreviewProps) => { - const app = useSelector(SelectOpenApp(hwnd)); - - const imageUrl = convertFileSrc(`${LAZY_CONSTANTS.TEMP_FOLDER}${app?.process_hwnd || 0}.png`); - - const [imageSrc, setImageSrc] = useState(imageUrl); - const [_, forceUpdate] = useReducer((x) => x + 1, 0); - - useEffect(() => { - const unlisten = listen(`weg-preview-update-${app?.process_hwnd || 0}`, () => { - setImageSrc(imageUrl); - forceUpdate(); - }); - return () => { - unlisten.then((unlisten) => unlisten()).catch(console.error); - }; - }, []); - - const onClose = (e: MouseEvent) => { - e.stopPropagation(); - invoke('weg_close_app', { hwnd }); - }; - - if (!app) { - return null; - } - - return ( -
- invoke('weg_toggle_window_state', { hwnd: app.hwnd || 0, exePath: app.execution_path }) - } - > -
-
{app.title}
-
- -
-
-
- {imageSrc ? ( - setImageSrc(null)} - /> - ) : ( - - )} -
-
- ); -}; +import { Icon } from '../../../../shared/components/Icon'; +import { convertFileSrc, invoke } from '@tauri-apps/api/core'; +import { listen } from '@tauri-apps/api/event'; +import { Spin } from 'antd'; +import { MouseEvent, useEffect, useReducer, useState } from 'react'; +import { useSelector } from 'react-redux'; + +import { LAZY_CONSTANTS } from '../../shared/utils/infra'; + +import { SelectOpenApp } from '../../shared/store/app'; + +import { HWND } from '../../shared/store/domain'; + +interface PreviewProps { + hwnd: HWND; +} + +export const UserApplicationPreview = ({ hwnd }: PreviewProps) => { + const app = useSelector(SelectOpenApp(hwnd)); + + const imageUrl = convertFileSrc(`${LAZY_CONSTANTS.TEMP_FOLDER}${app?.process_hwnd || 0}.png`); + + const [imageSrc, setImageSrc] = useState(imageUrl); + const [_, forceUpdate] = useReducer((x) => x + 1, 0); + + useEffect(() => { + const unlisten = listen(`weg-preview-update-${app?.process_hwnd || 0}`, () => { + setImageSrc(imageUrl); + forceUpdate(); + }); + return () => { + unlisten.then((unlisten) => unlisten()).catch(console.error); + }; + }, []); + + const onClose = (e: MouseEvent) => { + e.stopPropagation(); + invoke('weg_close_app', { hwnd }); + }; + + if (!app) { + return null; + } + + return ( +
+ invoke('weg_toggle_window_state', { hwnd: app.hwnd || 0, exePath: app.execution_path }) + } + > +
+
{app.title}
+
+ +
+
+
+ {imageSrc ? ( + setImageSrc(null)} + /> + ) : ( + + )} +
+
+ ); +}; diff --git a/src/apps/seelenweg/modules/shared/hooks/infra.ts b/src/apps/seelenweg/modules/shared/hooks/infra.ts index a87928c2..7a365677 100644 --- a/src/apps/seelenweg/modules/shared/hooks/infra.ts +++ b/src/apps/seelenweg/modules/shared/hooks/infra.ts @@ -1,24 +1,24 @@ -import { ExtraCallbacksOnActivate, ExtraCallbacksOnLeave } from '../../../events'; -import { useEffect, useRef } from 'react'; - -export function useAppBlur(cb: () => void, deps: any[] = []) { - const key = useRef(crypto.randomUUID()); - useEffect(() => { - ExtraCallbacksOnLeave.remove(key.current); - ExtraCallbacksOnLeave.add(cb, key.current); - return () => { - ExtraCallbacksOnLeave.remove(key.current); - }; - }, deps); -} - -export function useAppActivation(cb: () => void, deps: any[] = []) { - const key = useRef(crypto.randomUUID()); - useEffect(() => { - ExtraCallbacksOnActivate.remove(key.current); - ExtraCallbacksOnActivate.add(cb, key.current); - return () => { - ExtraCallbacksOnActivate.remove(key.current); - }; - }, deps); +import { ExtraCallbacksOnActivate, ExtraCallbacksOnLeave } from '../../../events'; +import { useEffect, useRef } from 'react'; + +export function useAppBlur(cb: () => void, deps: any[] = []) { + const key = useRef(crypto.randomUUID()); + useEffect(() => { + ExtraCallbacksOnLeave.remove(key.current); + ExtraCallbacksOnLeave.add(cb, key.current); + return () => { + ExtraCallbacksOnLeave.remove(key.current); + }; + }, deps); +} + +export function useAppActivation(cb: () => void, deps: any[] = []) { + const key = useRef(crypto.randomUUID()); + useEffect(() => { + ExtraCallbacksOnActivate.remove(key.current); + ExtraCallbacksOnActivate.add(cb, key.current); + return () => { + ExtraCallbacksOnActivate.remove(key.current); + }; + }, deps); } \ No newline at end of file diff --git a/src/apps/seelenweg/modules/shared/store/app.ts b/src/apps/seelenweg/modules/shared/store/app.ts index 50b1e3a5..9da76871 100644 --- a/src/apps/seelenweg/modules/shared/store/app.ts +++ b/src/apps/seelenweg/modules/shared/store/app.ts @@ -1,224 +1,224 @@ -import { StateBuilder } from '../../../../shared/StateBuilder'; -import { savePinnedItems } from './storeApi'; -import { createSlice, current, PayloadAction } from '@reduxjs/toolkit'; - -import { SeelenWegSlice } from '../../bar/app'; -import { SwTemporalAppUtils } from '../../item/app/TemporalApp'; - -import { - AppFromBackground, - AppsSides, - HWND, - RootState, - SpecialItemType, - SwItem, - SwPinnedApp, - SwTemporalApp, -} from './domain'; - -const initialState: RootState = { - itemsOnLeft: [], - itemsOnCenter: [], - itemsOnRight: [], - openApps: {}, - focusedHandle: 0, - focusedExecutable: '', - isOverlaped: false, - settings: SeelenWegSlice.getInitialState(), - mediaSessions: [], - colors: { - background: '#ffffff', - foreground: '#000000', - accent_darkest: '#000000', - accent_darker: '#000000', - accent_dark: '#000000', - accent: '#000000', - accent_light: '#000000', - accent_lighter: '#000000', - accent_lightest: '#000000', - complement: null, - }, -}; - -function removeAppFromState(state: RootState, searched: SwPinnedApp | SwTemporalApp) { - const search = (app: SwItem) => 'exe' in app && app.exe === searched.exe; - - let index = state.itemsOnLeft.findIndex(search); - if (index !== -1) { - state.itemsOnLeft.splice(index, 1); - return; - } - - index = state.itemsOnCenter.findIndex(search); - if (index !== -1) { - state.itemsOnCenter.splice(index, 1); - return; - } - - index = state.itemsOnRight.findIndex(search); - if (index !== -1) { - state.itemsOnRight.splice(index, 1); - return; - } -} - -function removeHwnd(state: SwItem[], searched: HWND) { - for (let i = 0; i < state.length; i++) { - const current = state[i]!; - if ( - current.type !== SpecialItemType.PinnedApp && - current.type !== SpecialItemType.TemporalApp - ) { - continue; - } - - const index = current.opens.findIndex((hwnd) => hwnd === searched); - - if (index !== -1) { - current.opens.splice(index, 1); - if (current.type === SpecialItemType.TemporalApp && current.opens.length === 0) { - state.splice(i, 1); - } - break; - } - } -} - -function findApp(state: RootState, searched: SwPinnedApp | SwTemporalApp) { - return (state.itemsOnLeft.find((app) => 'exe' in app && app.exe === searched.exe) || - state.itemsOnCenter.find((app) => 'exe' in app && app.exe === searched.exe) || - state.itemsOnRight.find((app) => 'exe' in app && app.exe === searched.exe)) as - | SwPinnedApp - | SwTemporalApp - | undefined; -} - -export const RootSlice = createSlice({ - name: 'root', - initialState, - reducers: { - ...StateBuilder.reducersFor(initialState), - unPin(state, action: PayloadAction) { - const found = findApp(state, action.payload); - if (found) { - found.type = SpecialItemType.TemporalApp; - if (found.opens.length === 0) { - removeAppFromState(state, found); - } - } - }, - pinApp(state, action: PayloadAction<{ app: SwTemporalApp; side: AppsSides }>) { - const { app, side } = action.payload; - - const appToPin = findApp(state, app) || app; - appToPin.type = SpecialItemType.PinnedApp; - - switch (side) { - case AppsSides.Left: - removeAppFromState(state, appToPin); - state.itemsOnLeft.unshift(appToPin); - break; - case AppsSides.Center: - removeAppFromState(state, appToPin); - state.itemsOnCenter.unshift(appToPin); - break; - case AppsSides.Right: - removeAppFromState(state, appToPin); - state.itemsOnRight.push(appToPin); - break; - default: - } - }, - addMediaModule(state) { - const all = [...state.itemsOnLeft, ...state.itemsOnCenter, ...state.itemsOnRight]; - if (!all.some((current) => current.type === SpecialItemType.Media)) { - state.itemsOnRight.push({ - type: SpecialItemType.Media, - }); - } - savePinnedItems(current(state)); - }, - removeMediaModule(state) { - const filter = (current: SwItem) => current.type !== SpecialItemType.Media; - state.itemsOnLeft = state.itemsOnLeft.filter(filter); - state.itemsOnCenter = state.itemsOnCenter.filter(filter); - state.itemsOnRight = state.itemsOnRight.filter(filter); - savePinnedItems(current(state)); - }, - addStartModule(state) { - const all = [...state.itemsOnLeft, ...state.itemsOnCenter, ...state.itemsOnRight]; - if (!all.some((current) => current.type === SpecialItemType.Start)) { - state.itemsOnLeft.unshift({ - type: SpecialItemType.Start, - }); - } - savePinnedItems(current(state)); - }, - removeStartModule(state) { - const filter = (current: SwItem) => current.type !== SpecialItemType.Start; - state.itemsOnLeft = state.itemsOnLeft.filter(filter); - state.itemsOnCenter = state.itemsOnCenter.filter(filter); - state.itemsOnRight = state.itemsOnRight.filter(filter); - savePinnedItems(current(state)); - }, - addOpenApp(state, action: PayloadAction) { - const app = action.payload; - - if (state.openApps[app.hwnd]) { - return; - } - - state.openApps[app.hwnd] = app; - - const appFilename = app.exe.split('\\').pop(); - if (appFilename) { - const pinedApp = (state.itemsOnLeft.find( - (current) => 'exe' in current && current.exe.endsWith(appFilename), - ) || - state.itemsOnCenter.find( - (current) => 'exe' in current && current.exe.endsWith(appFilename), - ) || - state.itemsOnRight.find( - (current) => 'exe' in current && current.exe.endsWith(appFilename), - )) as SwPinnedApp | undefined; - - if (pinedApp) { - pinedApp.opens.push(app.hwnd); - - if (pinedApp.exe !== app.exe) { - pinedApp.exe = app.exe; - pinedApp.execution_path = app.execution_path; - savePinnedItems(current(state)); - } - return; - } - } - - state.itemsOnCenter.push(SwTemporalAppUtils.fromBackground(app)); - }, - updateOpenAppInfo(state, action: PayloadAction) { - const found = state.openApps[action.payload.hwnd]; - if (found) { - found.title = action.payload.title; - } - }, - removeOpenApp(state, action: PayloadAction) { - delete state.openApps[action.payload]; - removeHwnd(state.itemsOnLeft, action.payload); - removeHwnd(state.itemsOnCenter, action.payload); - removeHwnd(state.itemsOnRight, action.payload); - }, - }, -}); - -export const RootActions = RootSlice.actions; -export const Selectors = StateBuilder.compositeSelector(initialState); -export const SelectOpenApp = (hwnd: HWND) => (state: RootState) => state.openApps[hwnd]; - -export const isPinnedApp = (item: SwItem): item is SwPinnedApp => { - return item.type === SpecialItemType.PinnedApp; -}; - -export const isTemporalApp = (item: SwItem): item is SwTemporalApp => { - return item.type === SpecialItemType.TemporalApp; -}; +import { StateBuilder } from '../../../../shared/StateBuilder'; +import { savePinnedItems } from './storeApi'; +import { createSlice, current, PayloadAction } from '@reduxjs/toolkit'; + +import { SeelenWegSlice } from '../../bar/app'; +import { SwTemporalAppUtils } from '../../item/app/TemporalApp'; + +import { + AppFromBackground, + AppsSides, + HWND, + RootState, + SpecialItemType, + SwItem, + SwPinnedApp, + SwTemporalApp, +} from './domain'; + +const initialState: RootState = { + itemsOnLeft: [], + itemsOnCenter: [], + itemsOnRight: [], + openApps: {}, + focusedHandle: 0, + focusedExecutable: '', + isOverlaped: false, + settings: SeelenWegSlice.getInitialState(), + mediaSessions: [], + colors: { + background: '#ffffff', + foreground: '#000000', + accent_darkest: '#000000', + accent_darker: '#000000', + accent_dark: '#000000', + accent: '#000000', + accent_light: '#000000', + accent_lighter: '#000000', + accent_lightest: '#000000', + complement: null, + }, +}; + +function removeAppFromState(state: RootState, searched: SwPinnedApp | SwTemporalApp) { + const search = (app: SwItem) => 'exe' in app && app.exe === searched.exe; + + let index = state.itemsOnLeft.findIndex(search); + if (index !== -1) { + state.itemsOnLeft.splice(index, 1); + return; + } + + index = state.itemsOnCenter.findIndex(search); + if (index !== -1) { + state.itemsOnCenter.splice(index, 1); + return; + } + + index = state.itemsOnRight.findIndex(search); + if (index !== -1) { + state.itemsOnRight.splice(index, 1); + return; + } +} + +function removeHwnd(state: SwItem[], searched: HWND) { + for (let i = 0; i < state.length; i++) { + const current = state[i]!; + if ( + current.type !== SpecialItemType.PinnedApp && + current.type !== SpecialItemType.TemporalApp + ) { + continue; + } + + const index = current.opens.findIndex((hwnd) => hwnd === searched); + + if (index !== -1) { + current.opens.splice(index, 1); + if (current.type === SpecialItemType.TemporalApp && current.opens.length === 0) { + state.splice(i, 1); + } + break; + } + } +} + +function findApp(state: RootState, searched: SwPinnedApp | SwTemporalApp) { + return (state.itemsOnLeft.find((app) => 'exe' in app && app.exe === searched.exe) || + state.itemsOnCenter.find((app) => 'exe' in app && app.exe === searched.exe) || + state.itemsOnRight.find((app) => 'exe' in app && app.exe === searched.exe)) as + | SwPinnedApp + | SwTemporalApp + | undefined; +} + +export const RootSlice = createSlice({ + name: 'root', + initialState, + reducers: { + ...StateBuilder.reducersFor(initialState), + unPin(state, action: PayloadAction) { + const found = findApp(state, action.payload); + if (found) { + found.type = SpecialItemType.TemporalApp; + if (found.opens.length === 0) { + removeAppFromState(state, found); + } + } + }, + pinApp(state, action: PayloadAction<{ app: SwTemporalApp; side: AppsSides }>) { + const { app, side } = action.payload; + + const appToPin = findApp(state, app) || app; + appToPin.type = SpecialItemType.PinnedApp; + + switch (side) { + case AppsSides.Left: + removeAppFromState(state, appToPin); + state.itemsOnLeft.unshift(appToPin); + break; + case AppsSides.Center: + removeAppFromState(state, appToPin); + state.itemsOnCenter.unshift(appToPin); + break; + case AppsSides.Right: + removeAppFromState(state, appToPin); + state.itemsOnRight.push(appToPin); + break; + default: + } + }, + addMediaModule(state) { + const all = [...state.itemsOnLeft, ...state.itemsOnCenter, ...state.itemsOnRight]; + if (!all.some((current) => current.type === SpecialItemType.Media)) { + state.itemsOnRight.push({ + type: SpecialItemType.Media, + }); + } + savePinnedItems(current(state)); + }, + removeMediaModule(state) { + const filter = (current: SwItem) => current.type !== SpecialItemType.Media; + state.itemsOnLeft = state.itemsOnLeft.filter(filter); + state.itemsOnCenter = state.itemsOnCenter.filter(filter); + state.itemsOnRight = state.itemsOnRight.filter(filter); + savePinnedItems(current(state)); + }, + addStartModule(state) { + const all = [...state.itemsOnLeft, ...state.itemsOnCenter, ...state.itemsOnRight]; + if (!all.some((current) => current.type === SpecialItemType.Start)) { + state.itemsOnLeft.unshift({ + type: SpecialItemType.Start, + }); + } + savePinnedItems(current(state)); + }, + removeStartModule(state) { + const filter = (current: SwItem) => current.type !== SpecialItemType.Start; + state.itemsOnLeft = state.itemsOnLeft.filter(filter); + state.itemsOnCenter = state.itemsOnCenter.filter(filter); + state.itemsOnRight = state.itemsOnRight.filter(filter); + savePinnedItems(current(state)); + }, + addOpenApp(state, action: PayloadAction) { + const app = action.payload; + + if (state.openApps[app.hwnd]) { + return; + } + + state.openApps[app.hwnd] = app; + + const appFilename = app.exe.split('\\').pop(); + if (appFilename) { + const pinedApp = (state.itemsOnLeft.find( + (current) => 'exe' in current && current.exe.endsWith(appFilename), + ) || + state.itemsOnCenter.find( + (current) => 'exe' in current && current.exe.endsWith(appFilename), + ) || + state.itemsOnRight.find( + (current) => 'exe' in current && current.exe.endsWith(appFilename), + )) as SwPinnedApp | undefined; + + if (pinedApp) { + pinedApp.opens.push(app.hwnd); + + if (pinedApp.exe !== app.exe) { + pinedApp.exe = app.exe; + pinedApp.execution_path = app.execution_path; + savePinnedItems(current(state)); + } + return; + } + } + + state.itemsOnCenter.push(SwTemporalAppUtils.fromBackground(app)); + }, + updateOpenAppInfo(state, action: PayloadAction) { + const found = state.openApps[action.payload.hwnd]; + if (found) { + found.title = action.payload.title; + } + }, + removeOpenApp(state, action: PayloadAction) { + delete state.openApps[action.payload]; + removeHwnd(state.itemsOnLeft, action.payload); + removeHwnd(state.itemsOnCenter, action.payload); + removeHwnd(state.itemsOnRight, action.payload); + }, + }, +}); + +export const RootActions = RootSlice.actions; +export const Selectors = StateBuilder.compositeSelector(initialState); +export const SelectOpenApp = (hwnd: HWND) => (state: RootState) => state.openApps[hwnd]; + +export const isPinnedApp = (item: SwItem): item is SwPinnedApp => { + return item.type === SpecialItemType.PinnedApp; +}; + +export const isTemporalApp = (item: SwItem): item is SwTemporalApp => { + return item.type === SpecialItemType.TemporalApp; +}; diff --git a/src/apps/seelenweg/modules/shared/store/domain.ts b/src/apps/seelenweg/modules/shared/store/domain.ts index 2ed82847..be37d7bb 100644 --- a/src/apps/seelenweg/modules/shared/store/domain.ts +++ b/src/apps/seelenweg/modules/shared/store/domain.ts @@ -1,84 +1,84 @@ -import { IRootState } from '../../../../../shared.interfaces'; -import { Seelenweg } from '../../../../shared/schemas/Seelenweg'; -import { - SavedMediaItem, - SavedPinnedApp, - SavedSeparatorItem, - StartMenuItem, - SwItemType as SpecialItemType, -} from '../../../../shared/schemas/SeelenWegItems'; -import { modify } from 'readable-types'; - -export type HWND = number & {}; - -export { SpecialItemType }; - -export interface AppFromBackground { - title: string; - exe: string; - execution_path: string; - icon: string; - icon_path: string; - hwnd: HWND; - process_hwnd: HWND; -} - -export enum AppsSides { - Left = 'left', - Center = 'center', - Right = 'right', - Current = 'current', -} - -export interface MediaSession { - id: string; - title: string; - author: string; - thumbnail: string | null; - playing: boolean; - default: boolean; -} - -export type SwPinnedApp = modify< - SavedPinnedApp, - { - icon: string; - title: string; - opens: HWND[]; - } ->; - -export type SwTemporalApp = modify< - SwPinnedApp, - { - type: SpecialItemType.TemporalApp; - } ->; - -export type SwItem = SwPinnedApp | SwTemporalApp | SavedSeparatorItem | SavedMediaItem | StartMenuItem; - -export interface UIColors { - background: string; - foreground: string; - accent_darkest: string; - accent_darker: string; - accent_dark: string; - accent: string; - accent_light: string; - accent_lighter: string; - accent_lightest: string; - complement: string | null; -} - -export interface RootState extends IRootState { - itemsOnLeft: SwItem[]; - itemsOnCenter: SwItem[]; - itemsOnRight: SwItem[]; - openApps: Record; - // ---------------------- - focusedHandle: HWND; - focusedExecutable: string; - isOverlaped: boolean; - mediaSessions: MediaSession[]; - colors: UIColors; -} +import { IRootState } from '../../../../../shared.interfaces'; +import { Seelenweg } from '../../../../shared/schemas/Seelenweg'; +import { + SavedMediaItem, + SavedPinnedApp, + SavedSeparatorItem, + StartMenuItem, + SwItemType as SpecialItemType, +} from '../../../../shared/schemas/SeelenWegItems'; +import { modify } from 'readable-types'; + +export type HWND = number & {}; + +export { SpecialItemType }; + +export interface AppFromBackground { + title: string; + exe: string; + execution_path: string; + icon: string; + icon_path: string; + hwnd: HWND; + process_hwnd: HWND; +} + +export enum AppsSides { + Left = 'left', + Center = 'center', + Right = 'right', + Current = 'current', +} + +export interface MediaSession { + id: string; + title: string; + author: string; + thumbnail: string | null; + playing: boolean; + default: boolean; +} + +export type SwPinnedApp = modify< + SavedPinnedApp, + { + icon: string; + title: string; + opens: HWND[]; + } +>; + +export type SwTemporalApp = modify< + SwPinnedApp, + { + type: SpecialItemType.TemporalApp; + } +>; + +export type SwItem = SwPinnedApp | SwTemporalApp | SavedSeparatorItem | SavedMediaItem | StartMenuItem; + +export interface UIColors { + background: string; + foreground: string; + accent_darkest: string; + accent_darker: string; + accent_dark: string; + accent: string; + accent_light: string; + accent_lighter: string; + accent_lightest: string; + complement: string | null; +} + +export interface RootState extends IRootState { + itemsOnLeft: SwItem[]; + itemsOnCenter: SwItem[]; + itemsOnRight: SwItem[]; + openApps: Record; + // ---------------------- + focusedHandle: HWND; + focusedExecutable: string; + isOverlaped: boolean; + mediaSessions: MediaSession[]; + colors: UIColors; +} diff --git a/src/apps/seelenweg/modules/shared/store/infra.ts b/src/apps/seelenweg/modules/shared/store/infra.ts index 1d45121b..ad427871 100644 --- a/src/apps/seelenweg/modules/shared/store/infra.ts +++ b/src/apps/seelenweg/modules/shared/store/infra.ts @@ -1,189 +1,189 @@ -import { UserSettingsLoader } from '../../../../settings/modules/shared/store/storeApi'; -import { loadThemeCSS, setColorsAsCssVariables } from '../../../../shared'; -import { FileChange } from '../../../../shared/events'; -import { Seelenweg, SeelenWegMode, SeelenWegSide } from '../../../../shared/schemas/Seelenweg'; -import { SwItemType, SwSavedItem } from '../../../../shared/schemas/SeelenWegItems'; -import { Theme } from '../../../../shared/schemas/Theme'; -import { updateHitbox } from '../../../events'; -import i18n from '../../../i18n'; -import { IsSavingPinnedItems, loadPinnedItems } from './storeApi'; -import { configureStore } from '@reduxjs/toolkit'; -import { listen as listenGlobal } from '@tauri-apps/api/event'; -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; -import { debounce } from 'lodash'; - -import { SwPinnedAppUtils } from '../../item/app/PinnedApp'; -import { SwTemporalAppUtils } from '../../item/app/TemporalApp'; -import { RootActions, RootSlice } from './app'; - -import { AppFromBackground, HWND, MediaSession, SwItem, UIColors } from './domain'; - -export const store = configureStore({ - reducer: RootSlice.reducer, -}); - -async function cleanItems(items: AppFromBackground[]): Promise { - const result: AppFromBackground[] = []; - for (const item of items) { - const cleaned = await SwTemporalAppUtils.clean(item); - result.push(cleaned); - } - return result; -} - -async function cleanSavedItems(items: SwSavedItem[]): Promise { - const result: SwItem[] = []; - - for (const item of items) { - if (item.type === SwItemType.PinnedApp) { - result.push(await SwPinnedAppUtils.fromSaved(item)); - } else { - result.push(item); - } - } - - return result; -} - -export async function registerStoreEvents() { - const view = getCurrentWebviewWindow(); - const updateHitboxIfNeeded = () => { - const { mode } = store.getState().settings; - if (mode === SeelenWegMode.MIN_CONTENT) { - updateHitbox(); - } - }; - - await view.listen('set-auto-hide', (event) => { - store.dispatch(RootActions.setIsOverlaped(event.payload)); - updateHitbox(); - }); - - await listenGlobal('add-multiple-open-apps', async (event) => { - const items = await cleanItems(event.payload); - for (const item of items) { - store.dispatch(RootActions.addOpenApp(item)); - } - updateHitboxIfNeeded(); - }); - - await listenGlobal('add-open-app', async (event) => { - const item = (await cleanItems([event.payload]))[0]!; - store.dispatch(RootActions.addOpenApp(item)); - updateHitboxIfNeeded(); - }); - - await listenGlobal('remove-open-app', (event) => { - store.dispatch(RootActions.removeOpenApp(event.payload)); - updateHitboxIfNeeded(); - }); - - await listenGlobal('update-open-app-info', async (event) => { - const item = (await cleanItems([event.payload]))[0]!; - store.dispatch(RootActions.updateOpenAppInfo(item)); - }); - - await listenGlobal('replace-open-app', async (event) => { - const item = (await cleanItems([event.payload]))[0]!; - store.dispatch(RootActions.addOpenApp(item)); - store.dispatch(RootActions.removeOpenApp(item.process_hwnd)); - }); - - await listenGlobal('set-focused-handle', (event) => { - store.dispatch(RootActions.setFocusedHandle(event.payload)); - }); - - await listenGlobal('set-focused-executable', (event) => { - store.dispatch(RootActions.setFocusedExecutable(event.payload)); - }); - - await listenGlobal('media-sessions', (event) => { - store.dispatch(RootActions.setMediaSessions(event.payload)); - }); - - await listenGlobal('colors', (event) => { - setColorsAsCssVariables(event.payload); - store.dispatch(RootActions.setColors(event.payload)); - }); - - await listenGlobal(FileChange.Themes, async () => { - const userSettings = await new UserSettingsLoader().load(); - loadThemeCSS(userSettings); - }); - - await listenGlobal( - FileChange.WegItems, - debounce(async () => { - if (IsSavingPinnedItems.current) { - IsSavingPinnedItems.current = false; - return; - } - - const apps = await loadPinnedItems(); - store.dispatch(RootActions.setItemsOnLeft(await cleanSavedItems(apps.left))); - store.dispatch(RootActions.setItemsOnCenter(await cleanSavedItems(apps.center))); - store.dispatch(RootActions.setItemsOnRight(await cleanSavedItems(apps.right))); - }, 100), - ); - - await listenGlobal( - FileChange.Settings, - debounce(async () => { - await loadSettingsToStore(); - updateHitbox(); - }, 100), - ); - - await view.emitTo(view.label, 'store-events-ready'); -} - -function loadSettingsCSS(settings: Seelenweg) { - const styles = document.documentElement.style; - - styles.setProperty('--config-margin', `${settings.margin}px`); - styles.setProperty('--config-padding', `${settings.padding}px`); - - styles.setProperty('--config-item-size', `${settings.size}px`); - styles.setProperty('--config-item-zoom-size', `${settings.zoomSize}px`); - styles.setProperty('--config-space-between-items', `${settings.spaceBetweenItems}px`); - - switch (settings.position) { - case SeelenWegSide.TOP: - styles.setProperty('--config-by-position-justify-content', 'center'); - styles.setProperty('--config-by-position-align-items', 'flex-start'); - styles.setProperty('--config-by-position-flex-direction', 'row'); - break; - case SeelenWegSide.BOTTOM: - styles.setProperty('--config-by-position-justify-content', 'center'); - styles.setProperty('--config-by-position-align-items', 'flex-end'); - styles.setProperty('--config-by-position-flex-direction', 'row'); - break; - case SeelenWegSide.LEFT: - styles.setProperty('--config-by-position-justify-content', 'flex-start'); - styles.setProperty('--config-by-position-align-items', 'center'); - styles.setProperty('--config-by-position-flex-direction', 'column'); - break; - case SeelenWegSide.RIGHT: - styles.setProperty('--config-by-position-justify-content', 'flex-end'); - styles.setProperty('--config-by-position-align-items', 'center'); - styles.setProperty('--config-by-position-flex-direction', 'column'); - break; - } -} - -async function loadSettingsToStore() { - const userSettings = await new UserSettingsLoader().load(); - i18n.changeLanguage(userSettings.jsonSettings.language); - const settings = userSettings.jsonSettings.seelenweg; - store.dispatch(RootActions.setSettings(settings)); - loadSettingsCSS(settings); - loadThemeCSS(userSettings); -} - -export async function loadStore() { - await loadSettingsToStore(); - const apps = await loadPinnedItems(); - store.dispatch(RootActions.setItemsOnLeft(await cleanSavedItems(apps.left))); - store.dispatch(RootActions.setItemsOnCenter(await cleanSavedItems(apps.center))); - store.dispatch(RootActions.setItemsOnRight(await cleanSavedItems(apps.right))); -} +import { UserSettingsLoader } from '../../../../settings/modules/shared/store/storeApi'; +import { loadThemeCSS, setColorsAsCssVariables } from '../../../../shared'; +import { FileChange } from '../../../../shared/events'; +import { Seelenweg, SeelenWegMode, SeelenWegSide } from '../../../../shared/schemas/Seelenweg'; +import { SwItemType, SwSavedItem } from '../../../../shared/schemas/SeelenWegItems'; +import { Theme } from '../../../../shared/schemas/Theme'; +import { updateHitbox } from '../../../events'; +import i18n from '../../../i18n'; +import { IsSavingPinnedItems, loadPinnedItems } from './storeApi'; +import { configureStore } from '@reduxjs/toolkit'; +import { listen as listenGlobal } from '@tauri-apps/api/event'; +import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; +import { debounce } from 'lodash'; + +import { SwPinnedAppUtils } from '../../item/app/PinnedApp'; +import { SwTemporalAppUtils } from '../../item/app/TemporalApp'; +import { RootActions, RootSlice } from './app'; + +import { AppFromBackground, HWND, MediaSession, SwItem, UIColors } from './domain'; + +export const store = configureStore({ + reducer: RootSlice.reducer, +}); + +async function cleanItems(items: AppFromBackground[]): Promise { + const result: AppFromBackground[] = []; + for (const item of items) { + const cleaned = await SwTemporalAppUtils.clean(item); + result.push(cleaned); + } + return result; +} + +async function cleanSavedItems(items: SwSavedItem[]): Promise { + const result: SwItem[] = []; + + for (const item of items) { + if (item.type === SwItemType.PinnedApp) { + result.push(await SwPinnedAppUtils.fromSaved(item)); + } else { + result.push(item); + } + } + + return result; +} + +export async function registerStoreEvents() { + const view = getCurrentWebviewWindow(); + const updateHitboxIfNeeded = () => { + const { mode } = store.getState().settings; + if (mode === SeelenWegMode.MIN_CONTENT) { + updateHitbox(); + } + }; + + await view.listen('set-auto-hide', (event) => { + store.dispatch(RootActions.setIsOverlaped(event.payload)); + updateHitbox(); + }); + + await listenGlobal('add-multiple-open-apps', async (event) => { + const items = await cleanItems(event.payload); + for (const item of items) { + store.dispatch(RootActions.addOpenApp(item)); + } + updateHitboxIfNeeded(); + }); + + await listenGlobal('add-open-app', async (event) => { + const item = (await cleanItems([event.payload]))[0]!; + store.dispatch(RootActions.addOpenApp(item)); + updateHitboxIfNeeded(); + }); + + await listenGlobal('remove-open-app', (event) => { + store.dispatch(RootActions.removeOpenApp(event.payload)); + updateHitboxIfNeeded(); + }); + + await listenGlobal('update-open-app-info', async (event) => { + const item = (await cleanItems([event.payload]))[0]!; + store.dispatch(RootActions.updateOpenAppInfo(item)); + }); + + await listenGlobal('replace-open-app', async (event) => { + const item = (await cleanItems([event.payload]))[0]!; + store.dispatch(RootActions.addOpenApp(item)); + store.dispatch(RootActions.removeOpenApp(item.process_hwnd)); + }); + + await listenGlobal('set-focused-handle', (event) => { + store.dispatch(RootActions.setFocusedHandle(event.payload)); + }); + + await listenGlobal('set-focused-executable', (event) => { + store.dispatch(RootActions.setFocusedExecutable(event.payload)); + }); + + await listenGlobal('media-sessions', (event) => { + store.dispatch(RootActions.setMediaSessions(event.payload)); + }); + + await listenGlobal('colors', (event) => { + setColorsAsCssVariables(event.payload); + store.dispatch(RootActions.setColors(event.payload)); + }); + + await listenGlobal(FileChange.Themes, async () => { + const userSettings = await new UserSettingsLoader().load(); + loadThemeCSS(userSettings); + }); + + await listenGlobal( + FileChange.WegItems, + debounce(async () => { + if (IsSavingPinnedItems.current) { + IsSavingPinnedItems.current = false; + return; + } + + const apps = await loadPinnedItems(); + store.dispatch(RootActions.setItemsOnLeft(await cleanSavedItems(apps.left))); + store.dispatch(RootActions.setItemsOnCenter(await cleanSavedItems(apps.center))); + store.dispatch(RootActions.setItemsOnRight(await cleanSavedItems(apps.right))); + }, 100), + ); + + await listenGlobal( + FileChange.Settings, + debounce(async () => { + await loadSettingsToStore(); + updateHitbox(); + }, 100), + ); + + await view.emitTo(view.label, 'store-events-ready'); +} + +function loadSettingsCSS(settings: Seelenweg) { + const styles = document.documentElement.style; + + styles.setProperty('--config-margin', `${settings.margin}px`); + styles.setProperty('--config-padding', `${settings.padding}px`); + + styles.setProperty('--config-item-size', `${settings.size}px`); + styles.setProperty('--config-item-zoom-size', `${settings.zoomSize}px`); + styles.setProperty('--config-space-between-items', `${settings.spaceBetweenItems}px`); + + switch (settings.position) { + case SeelenWegSide.TOP: + styles.setProperty('--config-by-position-justify-content', 'center'); + styles.setProperty('--config-by-position-align-items', 'flex-start'); + styles.setProperty('--config-by-position-flex-direction', 'row'); + break; + case SeelenWegSide.BOTTOM: + styles.setProperty('--config-by-position-justify-content', 'center'); + styles.setProperty('--config-by-position-align-items', 'flex-end'); + styles.setProperty('--config-by-position-flex-direction', 'row'); + break; + case SeelenWegSide.LEFT: + styles.setProperty('--config-by-position-justify-content', 'flex-start'); + styles.setProperty('--config-by-position-align-items', 'center'); + styles.setProperty('--config-by-position-flex-direction', 'column'); + break; + case SeelenWegSide.RIGHT: + styles.setProperty('--config-by-position-justify-content', 'flex-end'); + styles.setProperty('--config-by-position-align-items', 'center'); + styles.setProperty('--config-by-position-flex-direction', 'column'); + break; + } +} + +async function loadSettingsToStore() { + const userSettings = await new UserSettingsLoader().load(); + i18n.changeLanguage(userSettings.jsonSettings.language); + const settings = userSettings.jsonSettings.seelenweg; + store.dispatch(RootActions.setSettings(settings)); + loadSettingsCSS(settings); + loadThemeCSS(userSettings); +} + +export async function loadStore() { + await loadSettingsToStore(); + const apps = await loadPinnedItems(); + store.dispatch(RootActions.setItemsOnLeft(await cleanSavedItems(apps.left))); + store.dispatch(RootActions.setItemsOnCenter(await cleanSavedItems(apps.center))); + store.dispatch(RootActions.setItemsOnRight(await cleanSavedItems(apps.right))); +} diff --git a/src/apps/seelenweg/modules/shared/store/storeApi.ts b/src/apps/seelenweg/modules/shared/store/storeApi.ts index cbd5944e..623de6cf 100644 --- a/src/apps/seelenweg/modules/shared/store/storeApi.ts +++ b/src/apps/seelenweg/modules/shared/store/storeApi.ts @@ -1,57 +1,57 @@ -import { - SwItemType, - SwSavedItem, - SwSaveFile, - SwSaveFileSchema, -} from '../../../../shared/schemas/SeelenWegItems'; -import { path } from '@tauri-apps/api'; -import { invoke } from '@tauri-apps/api/core'; -import { writeTextFile } from '@tauri-apps/plugin-fs'; -import yaml from 'js-yaml'; -import { debounce } from 'lodash'; - -import { store } from './infra'; - -import { RootState, SwItem } from './domain'; - -export const IsSavingPinnedItems = { - current: false, -}; - -export const savePinnedItems = debounce( - async (state: RootState = store.getState()): Promise => { - const cb = (acc: SwSavedItem[], item: SwItem) => { - switch (item.type) { - case SwItemType.TemporalApp: - break; - case SwItemType.PinnedApp: - acc.push({ - type: item.type, - exe: item.exe, - execution_path: item.execution_path, - }); - break; - default: - acc.push(item); - break; - } - return acc; - }; - - const data: SwSaveFile = { - left: state.itemsOnLeft.reduce(cb, []), - center: state.itemsOnCenter.reduce(cb, []), - right: state.itemsOnRight.reduce(cb, []), - }; - - const yaml_route = await path.join(await path.appDataDir(), 'seelenweg_items.yaml'); - IsSavingPinnedItems.current = true; - await writeTextFile(yaml_route, yaml.dump(data)); - }, - 1000, -); - -export const loadPinnedItems = async (): Promise => { - let items = await invoke('state_get_weg_items'); - return SwSaveFileSchema.parse(items || {}); -}; +import { + SwItemType, + SwSavedItem, + SwSaveFile, + SwSaveFileSchema, +} from '../../../../shared/schemas/SeelenWegItems'; +import { path } from '@tauri-apps/api'; +import { invoke } from '@tauri-apps/api/core'; +import { writeTextFile } from '@tauri-apps/plugin-fs'; +import yaml from 'js-yaml'; +import { debounce } from 'lodash'; + +import { store } from './infra'; + +import { RootState, SwItem } from './domain'; + +export const IsSavingPinnedItems = { + current: false, +}; + +export const savePinnedItems = debounce( + async (state: RootState = store.getState()): Promise => { + const cb = (acc: SwSavedItem[], item: SwItem) => { + switch (item.type) { + case SwItemType.TemporalApp: + break; + case SwItemType.PinnedApp: + acc.push({ + type: item.type, + exe: item.exe, + execution_path: item.execution_path, + }); + break; + default: + acc.push(item); + break; + } + return acc; + }; + + const data: SwSaveFile = { + left: state.itemsOnLeft.reduce(cb, []), + center: state.itemsOnCenter.reduce(cb, []), + right: state.itemsOnRight.reduce(cb, []), + }; + + const yaml_route = await path.join(await path.appDataDir(), 'seelenweg_items.yaml'); + IsSavingPinnedItems.current = true; + await writeTextFile(yaml_route, yaml.dump(data)); + }, + 1000, +); + +export const loadPinnedItems = async (): Promise => { + let items = await invoke('state_get_weg_items'); + return SwSaveFileSchema.parse(items || {}); +}; diff --git a/src/apps/seelenweg/modules/shared/utils/app.ts b/src/apps/seelenweg/modules/shared/utils/app.ts index b0683f5d..d9199a1b 100644 --- a/src/apps/seelenweg/modules/shared/utils/app.ts +++ b/src/apps/seelenweg/modules/shared/utils/app.ts @@ -1,26 +1,26 @@ -import { path } from '@tauri-apps/api'; - -export function filenameFromPath(path: string): string { - const parts = path.split('\\'); - return parts[parts.length - 1] || ''; -} - -export async function getGeneratedFilesPath(): Promise { - return await path.appDataDir(); -} - -export class CallbacksManager { - callbacks: Record void> = {}; - - add(cb: () => void, key: string) { - this.callbacks[key] = cb; - } - - remove(key: string) { - delete this.callbacks[key]; - } - - execute() { - Object.values(this.callbacks).forEach((cb) => cb()); - } +import { path } from '@tauri-apps/api'; + +export function filenameFromPath(path: string): string { + const parts = path.split('\\'); + return parts[parts.length - 1] || ''; +} + +export async function getGeneratedFilesPath(): Promise { + return await path.appDataDir(); +} + +export class CallbacksManager { + callbacks: Record void> = {}; + + add(cb: () => void, key: string) { + this.callbacks[key] = cb; + } + + remove(key: string) { + delete this.callbacks[key]; + } + + execute() { + Object.values(this.callbacks).forEach((cb) => cb()); + } } \ No newline at end of file diff --git a/src/apps/seelenweg/modules/shared/utils/infra.ts b/src/apps/seelenweg/modules/shared/utils/infra.ts index 91a4bf4e..c6366f4a 100644 --- a/src/apps/seelenweg/modules/shared/utils/infra.ts +++ b/src/apps/seelenweg/modules/shared/utils/infra.ts @@ -1,118 +1,118 @@ -import { path } from '@tauri-apps/api'; -import { invoke } from '@tauri-apps/api/core'; - -import { store } from '../store/infra'; - -import { getGeneratedFilesPath } from './app'; - -import { HWND } from '../store/domain'; - -export const LAZY_CONSTANTS = { - MISSING_ICON_PATH: '', - DEFAULT_THUMBNAIL: '', - TEMP_FOLDER: '', -}; - -export async function loadConstants() { - LAZY_CONSTANTS.TEMP_FOLDER = await path.tempDir(); - LAZY_CONSTANTS.MISSING_ICON_PATH = await getMissingIconPath(); - LAZY_CONSTANTS.DEFAULT_THUMBNAIL = await path.resolve( - await path.resourceDir(), - 'static', - 'icons', - 'default_thumbnail.jpg', - ); -} - -export async function getMissingIconPath() { - return await path.resolve(await path.resourceDir(), 'static', 'icons', 'missing.png'); -} - -export async function updatePreviews(hwnds: HWND[]) { - const state = store.getState(); - const process = hwnds.map((hwnd) => { - return { - hwnd, - process_hwnd: state.openApps[hwnd]?.process_hwnd || (0 as HWND), - }; - }); - invoke('weg_request_update_previews', { hwnds: process }); -} - -export async function iconPathFromExePath(exePath: string) { - const parts = exePath.split('\\'); - const fileName = parts.at(-1)?.replace('.exe', '.png') || 'missing.png'; - return await path.resolve(await getGeneratedFilesPath(), 'icons', fileName); -} - -export function getImageBase64FromUrl(url: string): Promise { - let image = new Image(); - let canvas = document.createElement('canvas'); - let ctx = canvas.getContext('2d')!; - - return new Promise((resolve, reject) => { - image.onload = function () { - canvas.width = image.width; - canvas.height = image.height; - ctx.drawImage(image, 0, 0); - resolve(trimCanvas(canvas).toDataURL()); - }; - - image.onerror = function () { - console.error('Error while loading image: ', url); - reject(); - }; - - image.crossOrigin = ''; - image.src = url; - }); -} - -function trimCanvas(canvas: HTMLCanvasElement) { - function rowBlank(imageData: ImageData, width: number, y: number) { - for (let x = 0; x < width; ++x) { - if (imageData.data[y * width * 4 + x * 4 + 3] !== 0) return false; - } - return true; - } - - function columnBlank( - imageData: ImageData, - width: number, - x: number, - top: number, - bottom: number, - ) { - for (let y = top; y < bottom; ++y) { - if (imageData.data[y * width * 4 + x * 4 + 3] !== 0) return false; - } - return true; - } - - canvas.setAttribute; - const ctx = canvas.getContext('2d', { willReadFrequently: true })!; - const width = canvas.width; - const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); - let top = 0, - bottom = imageData.height, - left = 0, - right = imageData.width; - - while (top < bottom && rowBlank(imageData, width, top)) ++top; - while (bottom - 1 > top && rowBlank(imageData, width, bottom - 1)) --bottom; - while (left < right && columnBlank(imageData, width, left, top, bottom)) ++left; - while (right - 1 > left && columnBlank(imageData, width, right - 1, top, bottom)) --right; - - const trimmed = ctx.getImageData(left, top, right - left, bottom - top); - const copy = canvas.ownerDocument.createElement('canvas'); - const copyCtx = copy.getContext('2d', { willReadFrequently: true })!; - copy.width = trimmed.width; - copy.height = trimmed.height; - copyCtx.putImageData(trimmed, 0, 0); - - return copy; -} - -export async function isDevMode() { - return await invoke('is_dev_mode'); -} +import { path } from '@tauri-apps/api'; +import { invoke } from '@tauri-apps/api/core'; + +import { store } from '../store/infra'; + +import { getGeneratedFilesPath } from './app'; + +import { HWND } from '../store/domain'; + +export const LAZY_CONSTANTS = { + MISSING_ICON_PATH: '', + DEFAULT_THUMBNAIL: '', + TEMP_FOLDER: '', +}; + +export async function loadConstants() { + LAZY_CONSTANTS.TEMP_FOLDER = await path.tempDir(); + LAZY_CONSTANTS.MISSING_ICON_PATH = await getMissingIconPath(); + LAZY_CONSTANTS.DEFAULT_THUMBNAIL = await path.resolve( + await path.resourceDir(), + 'static', + 'icons', + 'default_thumbnail.jpg', + ); +} + +export async function getMissingIconPath() { + return await path.resolve(await path.resourceDir(), 'static', 'icons', 'missing.png'); +} + +export async function updatePreviews(hwnds: HWND[]) { + const state = store.getState(); + const process = hwnds.map((hwnd) => { + return { + hwnd, + process_hwnd: state.openApps[hwnd]?.process_hwnd || (0 as HWND), + }; + }); + invoke('weg_request_update_previews', { hwnds: process }); +} + +export async function iconPathFromExePath(exePath: string) { + const parts = exePath.split('\\'); + const fileName = parts.at(-1)?.replace('.exe', '.png') || 'missing.png'; + return await path.resolve(await getGeneratedFilesPath(), 'icons', fileName); +} + +export function getImageBase64FromUrl(url: string): Promise { + let image = new Image(); + let canvas = document.createElement('canvas'); + let ctx = canvas.getContext('2d')!; + + return new Promise((resolve, reject) => { + image.onload = function () { + canvas.width = image.width; + canvas.height = image.height; + ctx.drawImage(image, 0, 0); + resolve(trimCanvas(canvas).toDataURL()); + }; + + image.onerror = function () { + console.error('Error while loading image: ', url); + reject(); + }; + + image.crossOrigin = ''; + image.src = url; + }); +} + +function trimCanvas(canvas: HTMLCanvasElement) { + function rowBlank(imageData: ImageData, width: number, y: number) { + for (let x = 0; x < width; ++x) { + if (imageData.data[y * width * 4 + x * 4 + 3] !== 0) return false; + } + return true; + } + + function columnBlank( + imageData: ImageData, + width: number, + x: number, + top: number, + bottom: number, + ) { + for (let y = top; y < bottom; ++y) { + if (imageData.data[y * width * 4 + x * 4 + 3] !== 0) return false; + } + return true; + } + + canvas.setAttribute; + const ctx = canvas.getContext('2d', { willReadFrequently: true })!; + const width = canvas.width; + const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); + let top = 0, + bottom = imageData.height, + left = 0, + right = imageData.width; + + while (top < bottom && rowBlank(imageData, width, top)) ++top; + while (bottom - 1 > top && rowBlank(imageData, width, bottom - 1)) --bottom; + while (left < right && columnBlank(imageData, width, left, top, bottom)) ++left; + while (right - 1 > left && columnBlank(imageData, width, right - 1, top, bottom)) --right; + + const trimmed = ctx.getImageData(left, top, right - left, bottom - top); + const copy = canvas.ownerDocument.createElement('canvas'); + const copyCtx = copy.getContext('2d', { willReadFrequently: true })!; + copy.width = trimmed.width; + copy.height = trimmed.height; + copyCtx.putImageData(trimmed, 0, 0); + + return copy; +} + +export async function isDevMode() { + return await invoke('is_dev_mode'); +} diff --git a/src/apps/seelenweg/styles/colors.css b/src/apps/seelenweg/styles/colors.css index ec8ed844..f12ab260 100644 --- a/src/apps/seelenweg/styles/colors.css +++ b/src/apps/seelenweg/styles/colors.css @@ -1,599 +1,599 @@ -:root { - /* Persisted colors variables (not changed on dark mode) */ - --color-persist-white: #ffffff; - --color-persist-gray-50: #fdfdfd; - --color-persist-gray-100: #f8f8f8; - --color-persist-gray-200: #e6e6e6; - --color-persist-gray-300: #d5d5d5; - --color-persist-gray-400: #b1b1b1; - --color-persist-gray-500: #909090; - --color-persist-gray-600: #6d6d6d; - --color-persist-gray-700: #464646; - --color-persist-gray-800: #222222; - --color-persist-gray-900: #151515; - --color-persist-black: #000000; - - --color-persist-blue-100: #e0f2ff; - --color-persist-blue-200: #cae8ff; - --color-persist-blue-300: #b5deff; - --color-persist-blue-400: #96cefd; - --color-persist-blue-500: #78bbfa; - --color-persist-blue-600: #59a7f6; - --color-persist-blue-700: #3892f3; - --color-persist-blue-800: #147af3; - --color-persist-blue-900: #0265dc; - --color-persist-blue-1000: #0054b6; - --color-persist-blue-1100: #004491; - --color-persist-blue-1200: #003571; - --color-persist-blue-1300: #002754; - - --color-persist-green-100: #cef8e0; - --color-persist-green-200: #adf4ce; - --color-persist-green-300: #89ecbc; - --color-persist-green-400: #67dea8; - --color-persist-green-500: #49cc93; - --color-persist-green-600: #2fb880; - --color-persist-green-700: #15a46e; - --color-persist-green-800: #008f5d; - --color-persist-green-900: #007a4d; - --color-persist-green-1000: #00653e; - --color-persist-green-1100: #005132; - --color-persist-green-1200: #053f27; - --color-persist-green-1300: #0a2e1d; - - --color-persist-orange-100: #ffeccc; - --color-persist-orange-200: #ffdfad; - --color-persist-orange-300: #fdd291; - --color-persist-orange-400: #ffbb63; - --color-persist-orange-500: #ffa037; - --color-persist-orange-600: #f68511; - --color-persist-orange-700: #e46f00; - --color-persist-orange-800: #cb5d00; - --color-persist-orange-900: #b14c00; - --color-persist-orange-1000: #953d00; - --color-persist-orange-1100: #7a2f00; - --color-persist-orange-1200: #612300; - --color-persist-orange-1300: #491901; - - --color-persist-red-100: #ffebe7; - --color-persist-red-200: #ffddd6; - --color-persist-red-300: #ffcdc3; - --color-persist-red-400: #ffb7a9; - --color-persist-red-500: #ff9b88; - --color-persist-red-600: #ff7c65; - --color-persist-red-700: #f75c46; - --color-persist-red-800: #ea3829; - --color-persist-red-900: #d31510; - --color-persist-red-1000: #b40000; - --color-persist-red-1100: #930000; - --color-persist-red-1200: #740000; - --color-persist-red-1300: #590000; - - --color-persist-celery-100: #cdfcbf; - --color-persist-celery-200: #aef69d; - --color-persist-celery-300: #96ee85; - --color-persist-celery-400: #72e06a; - --color-persist-celery-500: #4ecf50; - --color-persist-celery-600: #27bb36; - --color-persist-celery-700: #07a721; - --color-persist-celery-800: #009112; - --color-persist-celery-900: #007c0f; - --color-persist-celery-1000: #00670f; - --color-persist-celery-1100: #00530d; - --color-persist-celery-1200: #00400a; - --color-persist-celery-1300: #003007; - - --color-persist-chartreuse-100: #dbfc6e; - --color-persist-chartreuse-200: #cbf443; - --color-persist-chartreuse-300: #bce92a; - --color-persist-chartreuse-400: #aad816; - --color-persist-chartreuse-500: #98c50a; - --color-persist-chartreuse-600: #87b103; - --color-persist-chartreuse-700: #769c00; - --color-persist-chartreuse-800: #678800; - --color-persist-chartreuse-900: #577400; - --color-persist-chartreuse-1000: #486000; - --color-persist-chartreuse-1100: #3a4d00; - --color-persist-chartreuse-1200: #2c3b00; - --color-persist-chartreuse-1300: #212c00; - - --color-persist-cyan-100: #c5f8ff; - --color-persist-cyan-200: #a4f0ff; - --color-persist-cyan-300: #88e7fa; - --color-persist-cyan-400: #60d8f3; - --color-persist-cyan-500: #33c5e8; - --color-persist-cyan-600: #12b0da; - --color-persist-cyan-700: #019cc8; - --color-persist-cyan-800: #0086b4; - --color-persist-cyan-900: #00719f; - --color-persist-cyan-1000: #005d89; - --color-persist-cyan-1100: #004a73; - --color-persist-cyan-1200: #00395d; - --color-persist-cyan-1300: #002a46; - - --color-persist-fuchsia-100: #ffe9fc; - --color-persist-fuchsia-200: #ffdafa; - --color-persist-fuchsia-300: #fec7f8; - --color-persist-fuchsia-400: #fbaef6; - --color-persist-fuchsia-500: #f592f3; - --color-persist-fuchsia-600: #ed74ed; - --color-persist-fuchsia-700: #e055e2; - --color-persist-fuchsia-800: #cd3ace; - --color-persist-fuchsia-900: #b622b7; - --color-persist-fuchsia-1000: #9d039e; - --color-persist-fuchsia-1100: #800081; - --color-persist-fuchsia-1200: #640664; - --color-persist-fuchsia-1300: #470e46; - - --color-persist-indigo-100: #edeeff; - --color-persist-indigo-200: #e0e2ff; - --color-persist-indigo-300: #d3d5ff; - --color-persist-indigo-400: #c1c4ff; - --color-persist-indigo-500: #acafff; - --color-persist-indigo-600: #9599ff; - --color-persist-indigo-700: #7e84fc; - --color-persist-indigo-800: #686df4; - --color-persist-indigo-900: #5258e4; - --color-persist-indigo-1000: #4046ca; - --color-persist-indigo-1100: #3236a8; - --color-persist-indigo-1200: #262986; - --color-persist-indigo-1300: #1b1e64; - - --color-persist-magenta-100: #ffeaf1; - --color-persist-magenta-200: #ffdce8; - --color-persist-magenta-300: #ffcadd; - --color-persist-magenta-400: #ffb2ce; - --color-persist-magenta-500: #ff95bd; - --color-persist-magenta-600: #fa77aa; - --color-persist-magenta-700: #ef5a98; - --color-persist-magenta-800: #de3d82; - --color-persist-magenta-900: #c82269; - --color-persist-magenta-1000: #ad0955; - --color-persist-magenta-1100: #8e0045; - --color-persist-magenta-1200: #700037; - --color-persist-magenta-1300: #54032a; - - --color-persist-purple-100: #f6ebff; - --color-persist-purple-200: #eeddff; - --color-persist-purple-300: #e6d0ff; - --color-persist-purple-400: #dbbbfe; - --color-persist-purple-500: #cca4fd; - --color-persist-purple-600: #bd8bfc; - --color-persist-purple-700: #ae72f9; - --color-persist-purple-800: #9d57f4; - --color-persist-purple-900: #893de7; - --color-persist-purple-1000: #7326d3; - --color-persist-purple-1100: #5d13b7; - --color-persist-purple-1200: #470c94; - --color-persist-purple-1300: #33106a; - - --color-persist-seafoam-100: #cef7f3; - --color-persist-seafoam-200: #aaf1ea; - --color-persist-seafoam-300: #8ce9e2; - --color-persist-seafoam-400: #65dad2; - --color-persist-seafoam-500: #3fc9c1; - --color-persist-seafoam-600: #0fb5ae; - --color-persist-seafoam-700: #00a19a; - --color-persist-seafoam-800: #008c87; - --color-persist-seafoam-900: #007772; - --color-persist-seafoam-1000: #00635f; - --color-persist-seafoam-1100: #0c4f4c; - --color-persist-seafoam-1200: #123c3a; - --color-persist-seafoam-1300: #122c2b; - - --color-persist-yellow-100: #fbf198; - --color-persist-yellow-200: #f8e750; - --color-persist-yellow-300: #f8d904; - --color-persist-yellow-400: #e8c600; - --color-persist-yellow-500: #d7b300; - --color-persist-yellow-600: #c49f00; - --color-persist-yellow-700: #b08c00; - --color-persist-yellow-800: #9b7800; - --color-persist-yellow-900: #856600; - --color-persist-yellow-1000: #705300; - --color-persist-yellow-1100: #5b4300; - --color-persist-yellow-1200: #483300; - --color-persist-yellow-1300: #362500; -} - -@media (prefers-color-scheme: dark) { - :root { - --color-white: #000000; - - --color-gray-50: #151515; - --color-gray-100: #222222; - --color-gray-200: #464646; - --color-gray-300: #6d6d6d; - --color-gray-400: #909090; - --color-gray-500: #b1b1b1; - --color-gray-600: #d5d5d5; - --color-gray-700: #e6e6e6; - --color-gray-800: #f8f8f8; - --color-gray-900: #fdfdfd; - - --color-black: #ffffff; - - --color-blue-100: #003877; - --color-blue-200: #00418a; - --color-blue-300: #004da3; - --color-blue-400: #0059c2; - --color-blue-500: #0367e0; - --color-blue-600: #1379f3; - --color-blue-700: #348ff4; - --color-blue-800: #54a3f6; - --color-blue-900: #72b7f9; - --color-blue-1000: #8fcafc; - --color-blue-1100: #aedbfe; - --color-blue-1200: #cce9ff; - --color-blue-1300: #e8f6ff; - - --color-green-100: #044329; - --color-green-200: #004e2f; - --color-green-300: #005c38; - --color-green-400: #006c43; - --color-green-500: #007d4e; - --color-green-600: #008f5d; - --color-green-700: #12a26c; - --color-green-800: #2bb47d; - --color-green-900: #43c78f; - --color-green-1000: #5ed9a2; - --color-green-1100: #81e9b8; - --color-green-1200: #b1f4d1; - --color-green-1300: #dffaea; - - --color-orange-100: #662500; - --color-orange-200: #752d00; - --color-orange-300: #893700; - --color-orange-400: #9e4200; - --color-orange-500: #b44e00; - --color-orange-600: #ca5d00; - --color-orange-700: #e16d00; - --color-orange-800: #f4810c; - --color-orange-900: #fe9a2e; - --color-orange-1000: #ffb558; - --color-orange-1100: #fdce88; - --color-orange-1200: #ffe1b3; - --color-orange-1300: #fff2dd; - - --color-red-100: #7b0000; - --color-red-200: #8d0000; - --color-red-300: #a50000; - --color-red-400: #be0403; - --color-red-500: #d71913; - --color-red-600: #ea3829; - --color-red-700: #f65843; - --color-red-800: #ff755e; - --color-red-900: #ff9581; - --color-red-1000: #ffb0a1; - --color-red-1100: #ffc9bd; - --color-red-1200: #ffded8; - --color-red-1300: #fff1ee; - - --color-celery-100: #00450a; - --color-celery-200: #00500c; - --color-celery-300: #005e0e; - --color-celery-400: #006d0f; - --color-celery-500: #007f0f; - --color-celery-600: #009112; - --color-celery-700: #04a51e; - --color-celery-800: #22b833; - --color-celery-900: #44ca49; - --color-celery-1000: #69dc63; - --color-celery-1100: #8eeb7f; - --color-celery-1200: #b4f7a2; - --color-celery-1300: #ddfdd3; - - --color-chartreuse-100: #304000; - --color-chartreuse-200: #374a00; - --color-chartreuse-300: #415700; - --color-chartreuse-400: #4c6600; - --color-chartreuse-500: #597600; - --color-chartreuse-600: #668800; - --color-chartreuse-700: #759a00; - --color-chartreuse-800: #84ad01; - --color-chartreuse-900: #94c008; - --color-chartreuse-1000: #a6d312; - --color-chartreuse-1100: #b8e525; - --color-chartreuse-1200: #cdf547; - --color-chartreuse-1300: #e7fe9a; - - --color-cyan-100: #003d62; - --color-cyan-200: #00476f; - --color-cyan-300: #00557f; - --color-cyan-400: #006491; - --color-cyan-500: #0074a2; - --color-cyan-600: #0086b4; - --color-cyan-700: #0099c6; - --color-cyan-800: #0eadd7; - --color-cyan-900: #2cc1e6; - --color-cyan-1000: #54d3f1; - --color-cyan-1100: #7fe4f9; - --color-cyan-1200: #a7f1ff; - --color-cyan-1300: #d7faff; - - --color-fuchsia-100: #6b036a; - --color-fuchsia-200: #7b007b; - --color-fuchsia-300: #900091; - --color-fuchsia-400: #a50da6; - --color-fuchsia-500: #b925b9; - --color-fuchsia-600: #cd39ce; - --color-fuchsia-700: #df51e0; - --color-fuchsia-800: #eb6eec; - --color-fuchsia-900: #f48cf2; - --color-fuchsia-1000: #faa8f5; - --color-fuchsia-1100: #fec2f8; - --color-fuchsia-1200: #ffdbfa; - --color-fuchsia-1300: #ffeffc; - - --color-indigo-100: #282c8c; - --color-indigo-200: #2f34a3; - --color-indigo-300: #393fbb; - --color-indigo-400: #464bd3; - --color-indigo-500: #555be7; - --color-indigo-600: #686df4; - --color-indigo-700: #7c81fb; - --color-indigo-800: #9195ff; - --color-indigo-900: #a7aaff; - --color-indigo-1000: #bcbeff; - --color-indigo-1100: #d0d2ff; - --color-indigo-1200: #e2e4ff; - --color-indigo-1300: #f3f3fe; - - --color-magenta-100: #76003a; - --color-magenta-200: #890042; - --color-magenta-300: #a0004d; - --color-magenta-400: #b6125a; - --color-magenta-500: #cb266d; - --color-magenta-600: #de3d82; - --color-magenta-700: #ed5795; - --color-magenta-800: #f972a7; - --color-magenta-900: #ff8fb9; - --color-magenta-1000: #ffacca; - --color-magenta-1100: #ffc6da; - --color-magenta-1200: #ffdde9; - --color-magenta-1300: #fff0f5; - - --color-purple-100: #4c0d9d; - --color-purple-200: #5911b1; - --color-purple-300: #691cc8; - --color-purple-400: #7a2dda; - --color-purple-500: #8c41e9; - --color-purple-600: #9d57f3; - --color-purple-700: #ac6ff9; - --color-purple-800: #bb87fb; - --color-purple-900: #ca9ffc; - --color-purple-1000: #d7b6fe; - --color-purple-1100: #e4ccfe; - --color-purple-1200: #efdfff; - --color-purple-1300: #f9f0ff; - - --color-seafoam-100: #12413f; - --color-seafoam-200: #0e4c49; - --color-seafoam-300: #045a57; - --color-seafoam-400: #006965; - --color-seafoam-500: #007a75; - --color-seafoam-600: #008c87; - --color-seafoam-700: #009e98; - --color-seafoam-800: #03b2ab; - --color-seafoam-900: #36c5bd; - --color-seafoam-1000: #5dd6cf; - --color-seafoam-1100: #84e6df; - --color-seafoam-1200: #b0f2ec; - --color-seafoam-1300: #dff9f6; - - --color-yellow-100: #4c3600; - --color-yellow-200: #584000; - --color-yellow-300: #674c00; - --color-yellow-400: #775900; - --color-yellow-500: #886800; - --color-yellow-600: #9b7800; - --color-yellow-700: #ae8900; - --color-yellow-800: #c09c00; - --color-yellow-900: #d3ae00; - --color-yellow-1000: #e4c200; - --color-yellow-1100: #f4d500; - --color-yellow-1200: #f9e85c; - --color-yellow-1300: #fcf6bb; - } -} - -@media (prefers-color-scheme: light) { - :root { - --color-white: #ffffff; - - --color-gray-50: #fdfdfd; - --color-gray-100: #f8f8f8; - --color-gray-200: #e6e6e6; - --color-gray-300: #d5d5d5; - --color-gray-400: #b1b1b1; - --color-gray-500: #909090; - --color-gray-600: #6d6d6d; - --color-gray-700: #464646; - --color-gray-800: #222222; - --color-gray-900: #151515; - - --color-black: #000000; - - --color-blue-100: #e0f2ff; - --color-blue-200: #cae8ff; - --color-blue-300: #b5deff; - --color-blue-400: #96cefd; - --color-blue-500: #78bbfa; - --color-blue-600: #59a7f6; - --color-blue-700: #3892f3; - --color-blue-800: #147af3; - --color-blue-900: #0265dc; - --color-blue-1000: #0054b6; - --color-blue-1100: #004491; - --color-blue-1200: #003571; - --color-blue-1300: #002754; - - --color-green-100: #cef8e0; - --color-green-200: #adf4ce; - --color-green-300: #89ecbc; - --color-green-400: #67dea8; - --color-green-500: #49cc93; - --color-green-600: #2fb880; - --color-green-700: #15a46e; - --color-green-800: #008f5d; - --color-green-900: #007a4d; - --color-green-1000: #00653e; - --color-green-1100: #005132; - --color-green-1200: #053f27; - --color-green-1300: #0a2e1d; - - --color-orange-100: #ffeccc; - --color-orange-200: #ffdfad; - --color-orange-300: #fdd291; - --color-orange-400: #ffbb63; - --color-orange-500: #ffa037; - --color-orange-600: #f68511; - --color-orange-700: #e46f00; - --color-orange-800: #cb5d00; - --color-orange-900: #b14c00; - --color-orange-1000: #953d00; - --color-orange-1100: #7a2f00; - --color-orange-1200: #612300; - --color-orange-1300: #491901; - - --color-red-100: #ffebe7; - --color-red-200: #ffddd6; - --color-red-300: #ffcdc3; - --color-red-400: #ffb7a9; - --color-red-500: #ff9b88; - --color-red-600: #ff7c65; - --color-red-700: #f75c46; - --color-red-800: #ea3829; - --color-red-900: #d31510; - --color-red-1000: #b40000; - --color-red-1100: #930000; - --color-red-1200: #740000; - --color-red-1300: #590000; - - --color-celery-100: #cdfcbf; - --color-celery-200: #aef69d; - --color-celery-300: #96ee85; - --color-celery-400: #72e06a; - --color-celery-500: #4ecf50; - --color-celery-600: #27bb36; - --color-celery-700: #07a721; - --color-celery-800: #009112; - --color-celery-900: #007c0f; - --color-celery-1000: #00670f; - --color-celery-1100: #00530d; - --color-celery-1200: #00400a; - --color-celery-1300: #003007; - - --color-chartreuse-100: #dbfc6e; - --color-chartreuse-200: #cbf443; - --color-chartreuse-300: #bce92a; - --color-chartreuse-400: #aad816; - --color-chartreuse-500: #98c50a; - --color-chartreuse-600: #87b103; - --color-chartreuse-700: #769c00; - --color-chartreuse-800: #678800; - --color-chartreuse-900: #577400; - --color-chartreuse-1000: #486000; - --color-chartreuse-1100: #3a4d00; - --color-chartreuse-1200: #2c3b00; - --color-chartreuse-1300: #212c00; - - --color-cyan-100: #c5f8ff; - --color-cyan-200: #a4f0ff; - --color-cyan-300: #88e7fa; - --color-cyan-400: #60d8f3; - --color-cyan-500: #33c5e8; - --color-cyan-600: #12b0da; - --color-cyan-700: #019cc8; - --color-cyan-800: #0086b4; - --color-cyan-900: #00719f; - --color-cyan-1000: #005d89; - --color-cyan-1100: #004a73; - --color-cyan-1200: #00395d; - --color-cyan-1300: #002a46; - - --color-fuchsia-100: #ffe9fc; - --color-fuchsia-200: #ffdafa; - --color-fuchsia-300: #fec7f8; - --color-fuchsia-400: #fbaef6; - --color-fuchsia-500: #f592f3; - --color-fuchsia-600: #ed74ed; - --color-fuchsia-700: #e055e2; - --color-fuchsia-800: #cd3ace; - --color-fuchsia-900: #b622b7; - --color-fuchsia-1000: #9d039e; - --color-fuchsia-1100: #800081; - --color-fuchsia-1200: #640664; - --color-fuchsia-1300: #470e46; - - --color-indigo-100: #edeeff; - --color-indigo-200: #e0e2ff; - --color-indigo-300: #d3d5ff; - --color-indigo-400: #c1c4ff; - --color-indigo-500: #acafff; - --color-indigo-600: #9599ff; - --color-indigo-700: #7e84fc; - --color-indigo-800: #686df4; - --color-indigo-900: #5258e4; - --color-indigo-1000: #4046ca; - --color-indigo-1100: #3236a8; - --color-indigo-1200: #262986; - --color-indigo-1300: #1b1e64; - - --color-magenta-100: #ffeaf1; - --color-magenta-200: #ffdce8; - --color-magenta-300: #ffcadd; - --color-magenta-400: #ffb2ce; - --color-magenta-500: #ff95bd; - --color-magenta-600: #fa77aa; - --color-magenta-700: #ef5a98; - --color-magenta-800: #de3d82; - --color-magenta-900: #c82269; - --color-magenta-1000: #ad0955; - --color-magenta-1100: #8e0045; - --color-magenta-1200: #700037; - --color-magenta-1300: #54032a; - - --color-purple-100: #f6ebff; - --color-purple-200: #eeddff; - --color-purple-300: #e6d0ff; - --color-purple-400: #dbbbfe; - --color-purple-500: #cca4fd; - --color-purple-600: #bd8bfc; - --color-purple-700: #ae72f9; - --color-purple-800: #9d57f4; - --color-purple-900: #893de7; - --color-purple-1000: #7326d3; - --color-purple-1100: #5d13b7; - --color-purple-1200: #470c94; - --color-purple-1300: #33106a; - - --color-seafoam-100: #cef7f3; - --color-seafoam-200: #aaf1ea; - --color-seafoam-300: #8ce9e2; - --color-seafoam-400: #65dad2; - --color-seafoam-500: #3fc9c1; - --color-seafoam-600: #0fb5ae; - --color-seafoam-700: #00a19a; - --color-seafoam-800: #008c87; - --color-seafoam-900: #007772; - --color-seafoam-1000: #00635f; - --color-seafoam-1100: #0c4f4c; - --color-seafoam-1200: #123c3a; - --color-seafoam-1300: #122c2b; - - --color-yellow-100: #fbf198; - --color-yellow-200: #f8e750; - --color-yellow-300: #f8d904; - --color-yellow-400: #e8c600; - --color-yellow-500: #d7b300; - --color-yellow-600: #c49f00; - --color-yellow-700: #b08c00; - --color-yellow-800: #9b7800; - --color-yellow-900: #856600; - --color-yellow-1000: #705300; - --color-yellow-1100: #5b4300; - --color-yellow-1200: #483300; - --color-yellow-1300: #362500; - } -} +:root { + /* Persisted colors variables (not changed on dark mode) */ + --color-persist-white: #ffffff; + --color-persist-gray-50: #fdfdfd; + --color-persist-gray-100: #f8f8f8; + --color-persist-gray-200: #e6e6e6; + --color-persist-gray-300: #d5d5d5; + --color-persist-gray-400: #b1b1b1; + --color-persist-gray-500: #909090; + --color-persist-gray-600: #6d6d6d; + --color-persist-gray-700: #464646; + --color-persist-gray-800: #222222; + --color-persist-gray-900: #151515; + --color-persist-black: #000000; + + --color-persist-blue-100: #e0f2ff; + --color-persist-blue-200: #cae8ff; + --color-persist-blue-300: #b5deff; + --color-persist-blue-400: #96cefd; + --color-persist-blue-500: #78bbfa; + --color-persist-blue-600: #59a7f6; + --color-persist-blue-700: #3892f3; + --color-persist-blue-800: #147af3; + --color-persist-blue-900: #0265dc; + --color-persist-blue-1000: #0054b6; + --color-persist-blue-1100: #004491; + --color-persist-blue-1200: #003571; + --color-persist-blue-1300: #002754; + + --color-persist-green-100: #cef8e0; + --color-persist-green-200: #adf4ce; + --color-persist-green-300: #89ecbc; + --color-persist-green-400: #67dea8; + --color-persist-green-500: #49cc93; + --color-persist-green-600: #2fb880; + --color-persist-green-700: #15a46e; + --color-persist-green-800: #008f5d; + --color-persist-green-900: #007a4d; + --color-persist-green-1000: #00653e; + --color-persist-green-1100: #005132; + --color-persist-green-1200: #053f27; + --color-persist-green-1300: #0a2e1d; + + --color-persist-orange-100: #ffeccc; + --color-persist-orange-200: #ffdfad; + --color-persist-orange-300: #fdd291; + --color-persist-orange-400: #ffbb63; + --color-persist-orange-500: #ffa037; + --color-persist-orange-600: #f68511; + --color-persist-orange-700: #e46f00; + --color-persist-orange-800: #cb5d00; + --color-persist-orange-900: #b14c00; + --color-persist-orange-1000: #953d00; + --color-persist-orange-1100: #7a2f00; + --color-persist-orange-1200: #612300; + --color-persist-orange-1300: #491901; + + --color-persist-red-100: #ffebe7; + --color-persist-red-200: #ffddd6; + --color-persist-red-300: #ffcdc3; + --color-persist-red-400: #ffb7a9; + --color-persist-red-500: #ff9b88; + --color-persist-red-600: #ff7c65; + --color-persist-red-700: #f75c46; + --color-persist-red-800: #ea3829; + --color-persist-red-900: #d31510; + --color-persist-red-1000: #b40000; + --color-persist-red-1100: #930000; + --color-persist-red-1200: #740000; + --color-persist-red-1300: #590000; + + --color-persist-celery-100: #cdfcbf; + --color-persist-celery-200: #aef69d; + --color-persist-celery-300: #96ee85; + --color-persist-celery-400: #72e06a; + --color-persist-celery-500: #4ecf50; + --color-persist-celery-600: #27bb36; + --color-persist-celery-700: #07a721; + --color-persist-celery-800: #009112; + --color-persist-celery-900: #007c0f; + --color-persist-celery-1000: #00670f; + --color-persist-celery-1100: #00530d; + --color-persist-celery-1200: #00400a; + --color-persist-celery-1300: #003007; + + --color-persist-chartreuse-100: #dbfc6e; + --color-persist-chartreuse-200: #cbf443; + --color-persist-chartreuse-300: #bce92a; + --color-persist-chartreuse-400: #aad816; + --color-persist-chartreuse-500: #98c50a; + --color-persist-chartreuse-600: #87b103; + --color-persist-chartreuse-700: #769c00; + --color-persist-chartreuse-800: #678800; + --color-persist-chartreuse-900: #577400; + --color-persist-chartreuse-1000: #486000; + --color-persist-chartreuse-1100: #3a4d00; + --color-persist-chartreuse-1200: #2c3b00; + --color-persist-chartreuse-1300: #212c00; + + --color-persist-cyan-100: #c5f8ff; + --color-persist-cyan-200: #a4f0ff; + --color-persist-cyan-300: #88e7fa; + --color-persist-cyan-400: #60d8f3; + --color-persist-cyan-500: #33c5e8; + --color-persist-cyan-600: #12b0da; + --color-persist-cyan-700: #019cc8; + --color-persist-cyan-800: #0086b4; + --color-persist-cyan-900: #00719f; + --color-persist-cyan-1000: #005d89; + --color-persist-cyan-1100: #004a73; + --color-persist-cyan-1200: #00395d; + --color-persist-cyan-1300: #002a46; + + --color-persist-fuchsia-100: #ffe9fc; + --color-persist-fuchsia-200: #ffdafa; + --color-persist-fuchsia-300: #fec7f8; + --color-persist-fuchsia-400: #fbaef6; + --color-persist-fuchsia-500: #f592f3; + --color-persist-fuchsia-600: #ed74ed; + --color-persist-fuchsia-700: #e055e2; + --color-persist-fuchsia-800: #cd3ace; + --color-persist-fuchsia-900: #b622b7; + --color-persist-fuchsia-1000: #9d039e; + --color-persist-fuchsia-1100: #800081; + --color-persist-fuchsia-1200: #640664; + --color-persist-fuchsia-1300: #470e46; + + --color-persist-indigo-100: #edeeff; + --color-persist-indigo-200: #e0e2ff; + --color-persist-indigo-300: #d3d5ff; + --color-persist-indigo-400: #c1c4ff; + --color-persist-indigo-500: #acafff; + --color-persist-indigo-600: #9599ff; + --color-persist-indigo-700: #7e84fc; + --color-persist-indigo-800: #686df4; + --color-persist-indigo-900: #5258e4; + --color-persist-indigo-1000: #4046ca; + --color-persist-indigo-1100: #3236a8; + --color-persist-indigo-1200: #262986; + --color-persist-indigo-1300: #1b1e64; + + --color-persist-magenta-100: #ffeaf1; + --color-persist-magenta-200: #ffdce8; + --color-persist-magenta-300: #ffcadd; + --color-persist-magenta-400: #ffb2ce; + --color-persist-magenta-500: #ff95bd; + --color-persist-magenta-600: #fa77aa; + --color-persist-magenta-700: #ef5a98; + --color-persist-magenta-800: #de3d82; + --color-persist-magenta-900: #c82269; + --color-persist-magenta-1000: #ad0955; + --color-persist-magenta-1100: #8e0045; + --color-persist-magenta-1200: #700037; + --color-persist-magenta-1300: #54032a; + + --color-persist-purple-100: #f6ebff; + --color-persist-purple-200: #eeddff; + --color-persist-purple-300: #e6d0ff; + --color-persist-purple-400: #dbbbfe; + --color-persist-purple-500: #cca4fd; + --color-persist-purple-600: #bd8bfc; + --color-persist-purple-700: #ae72f9; + --color-persist-purple-800: #9d57f4; + --color-persist-purple-900: #893de7; + --color-persist-purple-1000: #7326d3; + --color-persist-purple-1100: #5d13b7; + --color-persist-purple-1200: #470c94; + --color-persist-purple-1300: #33106a; + + --color-persist-seafoam-100: #cef7f3; + --color-persist-seafoam-200: #aaf1ea; + --color-persist-seafoam-300: #8ce9e2; + --color-persist-seafoam-400: #65dad2; + --color-persist-seafoam-500: #3fc9c1; + --color-persist-seafoam-600: #0fb5ae; + --color-persist-seafoam-700: #00a19a; + --color-persist-seafoam-800: #008c87; + --color-persist-seafoam-900: #007772; + --color-persist-seafoam-1000: #00635f; + --color-persist-seafoam-1100: #0c4f4c; + --color-persist-seafoam-1200: #123c3a; + --color-persist-seafoam-1300: #122c2b; + + --color-persist-yellow-100: #fbf198; + --color-persist-yellow-200: #f8e750; + --color-persist-yellow-300: #f8d904; + --color-persist-yellow-400: #e8c600; + --color-persist-yellow-500: #d7b300; + --color-persist-yellow-600: #c49f00; + --color-persist-yellow-700: #b08c00; + --color-persist-yellow-800: #9b7800; + --color-persist-yellow-900: #856600; + --color-persist-yellow-1000: #705300; + --color-persist-yellow-1100: #5b4300; + --color-persist-yellow-1200: #483300; + --color-persist-yellow-1300: #362500; +} + +@media (prefers-color-scheme: dark) { + :root { + --color-white: #000000; + + --color-gray-50: #151515; + --color-gray-100: #222222; + --color-gray-200: #464646; + --color-gray-300: #6d6d6d; + --color-gray-400: #909090; + --color-gray-500: #b1b1b1; + --color-gray-600: #d5d5d5; + --color-gray-700: #e6e6e6; + --color-gray-800: #f8f8f8; + --color-gray-900: #fdfdfd; + + --color-black: #ffffff; + + --color-blue-100: #003877; + --color-blue-200: #00418a; + --color-blue-300: #004da3; + --color-blue-400: #0059c2; + --color-blue-500: #0367e0; + --color-blue-600: #1379f3; + --color-blue-700: #348ff4; + --color-blue-800: #54a3f6; + --color-blue-900: #72b7f9; + --color-blue-1000: #8fcafc; + --color-blue-1100: #aedbfe; + --color-blue-1200: #cce9ff; + --color-blue-1300: #e8f6ff; + + --color-green-100: #044329; + --color-green-200: #004e2f; + --color-green-300: #005c38; + --color-green-400: #006c43; + --color-green-500: #007d4e; + --color-green-600: #008f5d; + --color-green-700: #12a26c; + --color-green-800: #2bb47d; + --color-green-900: #43c78f; + --color-green-1000: #5ed9a2; + --color-green-1100: #81e9b8; + --color-green-1200: #b1f4d1; + --color-green-1300: #dffaea; + + --color-orange-100: #662500; + --color-orange-200: #752d00; + --color-orange-300: #893700; + --color-orange-400: #9e4200; + --color-orange-500: #b44e00; + --color-orange-600: #ca5d00; + --color-orange-700: #e16d00; + --color-orange-800: #f4810c; + --color-orange-900: #fe9a2e; + --color-orange-1000: #ffb558; + --color-orange-1100: #fdce88; + --color-orange-1200: #ffe1b3; + --color-orange-1300: #fff2dd; + + --color-red-100: #7b0000; + --color-red-200: #8d0000; + --color-red-300: #a50000; + --color-red-400: #be0403; + --color-red-500: #d71913; + --color-red-600: #ea3829; + --color-red-700: #f65843; + --color-red-800: #ff755e; + --color-red-900: #ff9581; + --color-red-1000: #ffb0a1; + --color-red-1100: #ffc9bd; + --color-red-1200: #ffded8; + --color-red-1300: #fff1ee; + + --color-celery-100: #00450a; + --color-celery-200: #00500c; + --color-celery-300: #005e0e; + --color-celery-400: #006d0f; + --color-celery-500: #007f0f; + --color-celery-600: #009112; + --color-celery-700: #04a51e; + --color-celery-800: #22b833; + --color-celery-900: #44ca49; + --color-celery-1000: #69dc63; + --color-celery-1100: #8eeb7f; + --color-celery-1200: #b4f7a2; + --color-celery-1300: #ddfdd3; + + --color-chartreuse-100: #304000; + --color-chartreuse-200: #374a00; + --color-chartreuse-300: #415700; + --color-chartreuse-400: #4c6600; + --color-chartreuse-500: #597600; + --color-chartreuse-600: #668800; + --color-chartreuse-700: #759a00; + --color-chartreuse-800: #84ad01; + --color-chartreuse-900: #94c008; + --color-chartreuse-1000: #a6d312; + --color-chartreuse-1100: #b8e525; + --color-chartreuse-1200: #cdf547; + --color-chartreuse-1300: #e7fe9a; + + --color-cyan-100: #003d62; + --color-cyan-200: #00476f; + --color-cyan-300: #00557f; + --color-cyan-400: #006491; + --color-cyan-500: #0074a2; + --color-cyan-600: #0086b4; + --color-cyan-700: #0099c6; + --color-cyan-800: #0eadd7; + --color-cyan-900: #2cc1e6; + --color-cyan-1000: #54d3f1; + --color-cyan-1100: #7fe4f9; + --color-cyan-1200: #a7f1ff; + --color-cyan-1300: #d7faff; + + --color-fuchsia-100: #6b036a; + --color-fuchsia-200: #7b007b; + --color-fuchsia-300: #900091; + --color-fuchsia-400: #a50da6; + --color-fuchsia-500: #b925b9; + --color-fuchsia-600: #cd39ce; + --color-fuchsia-700: #df51e0; + --color-fuchsia-800: #eb6eec; + --color-fuchsia-900: #f48cf2; + --color-fuchsia-1000: #faa8f5; + --color-fuchsia-1100: #fec2f8; + --color-fuchsia-1200: #ffdbfa; + --color-fuchsia-1300: #ffeffc; + + --color-indigo-100: #282c8c; + --color-indigo-200: #2f34a3; + --color-indigo-300: #393fbb; + --color-indigo-400: #464bd3; + --color-indigo-500: #555be7; + --color-indigo-600: #686df4; + --color-indigo-700: #7c81fb; + --color-indigo-800: #9195ff; + --color-indigo-900: #a7aaff; + --color-indigo-1000: #bcbeff; + --color-indigo-1100: #d0d2ff; + --color-indigo-1200: #e2e4ff; + --color-indigo-1300: #f3f3fe; + + --color-magenta-100: #76003a; + --color-magenta-200: #890042; + --color-magenta-300: #a0004d; + --color-magenta-400: #b6125a; + --color-magenta-500: #cb266d; + --color-magenta-600: #de3d82; + --color-magenta-700: #ed5795; + --color-magenta-800: #f972a7; + --color-magenta-900: #ff8fb9; + --color-magenta-1000: #ffacca; + --color-magenta-1100: #ffc6da; + --color-magenta-1200: #ffdde9; + --color-magenta-1300: #fff0f5; + + --color-purple-100: #4c0d9d; + --color-purple-200: #5911b1; + --color-purple-300: #691cc8; + --color-purple-400: #7a2dda; + --color-purple-500: #8c41e9; + --color-purple-600: #9d57f3; + --color-purple-700: #ac6ff9; + --color-purple-800: #bb87fb; + --color-purple-900: #ca9ffc; + --color-purple-1000: #d7b6fe; + --color-purple-1100: #e4ccfe; + --color-purple-1200: #efdfff; + --color-purple-1300: #f9f0ff; + + --color-seafoam-100: #12413f; + --color-seafoam-200: #0e4c49; + --color-seafoam-300: #045a57; + --color-seafoam-400: #006965; + --color-seafoam-500: #007a75; + --color-seafoam-600: #008c87; + --color-seafoam-700: #009e98; + --color-seafoam-800: #03b2ab; + --color-seafoam-900: #36c5bd; + --color-seafoam-1000: #5dd6cf; + --color-seafoam-1100: #84e6df; + --color-seafoam-1200: #b0f2ec; + --color-seafoam-1300: #dff9f6; + + --color-yellow-100: #4c3600; + --color-yellow-200: #584000; + --color-yellow-300: #674c00; + --color-yellow-400: #775900; + --color-yellow-500: #886800; + --color-yellow-600: #9b7800; + --color-yellow-700: #ae8900; + --color-yellow-800: #c09c00; + --color-yellow-900: #d3ae00; + --color-yellow-1000: #e4c200; + --color-yellow-1100: #f4d500; + --color-yellow-1200: #f9e85c; + --color-yellow-1300: #fcf6bb; + } +} + +@media (prefers-color-scheme: light) { + :root { + --color-white: #ffffff; + + --color-gray-50: #fdfdfd; + --color-gray-100: #f8f8f8; + --color-gray-200: #e6e6e6; + --color-gray-300: #d5d5d5; + --color-gray-400: #b1b1b1; + --color-gray-500: #909090; + --color-gray-600: #6d6d6d; + --color-gray-700: #464646; + --color-gray-800: #222222; + --color-gray-900: #151515; + + --color-black: #000000; + + --color-blue-100: #e0f2ff; + --color-blue-200: #cae8ff; + --color-blue-300: #b5deff; + --color-blue-400: #96cefd; + --color-blue-500: #78bbfa; + --color-blue-600: #59a7f6; + --color-blue-700: #3892f3; + --color-blue-800: #147af3; + --color-blue-900: #0265dc; + --color-blue-1000: #0054b6; + --color-blue-1100: #004491; + --color-blue-1200: #003571; + --color-blue-1300: #002754; + + --color-green-100: #cef8e0; + --color-green-200: #adf4ce; + --color-green-300: #89ecbc; + --color-green-400: #67dea8; + --color-green-500: #49cc93; + --color-green-600: #2fb880; + --color-green-700: #15a46e; + --color-green-800: #008f5d; + --color-green-900: #007a4d; + --color-green-1000: #00653e; + --color-green-1100: #005132; + --color-green-1200: #053f27; + --color-green-1300: #0a2e1d; + + --color-orange-100: #ffeccc; + --color-orange-200: #ffdfad; + --color-orange-300: #fdd291; + --color-orange-400: #ffbb63; + --color-orange-500: #ffa037; + --color-orange-600: #f68511; + --color-orange-700: #e46f00; + --color-orange-800: #cb5d00; + --color-orange-900: #b14c00; + --color-orange-1000: #953d00; + --color-orange-1100: #7a2f00; + --color-orange-1200: #612300; + --color-orange-1300: #491901; + + --color-red-100: #ffebe7; + --color-red-200: #ffddd6; + --color-red-300: #ffcdc3; + --color-red-400: #ffb7a9; + --color-red-500: #ff9b88; + --color-red-600: #ff7c65; + --color-red-700: #f75c46; + --color-red-800: #ea3829; + --color-red-900: #d31510; + --color-red-1000: #b40000; + --color-red-1100: #930000; + --color-red-1200: #740000; + --color-red-1300: #590000; + + --color-celery-100: #cdfcbf; + --color-celery-200: #aef69d; + --color-celery-300: #96ee85; + --color-celery-400: #72e06a; + --color-celery-500: #4ecf50; + --color-celery-600: #27bb36; + --color-celery-700: #07a721; + --color-celery-800: #009112; + --color-celery-900: #007c0f; + --color-celery-1000: #00670f; + --color-celery-1100: #00530d; + --color-celery-1200: #00400a; + --color-celery-1300: #003007; + + --color-chartreuse-100: #dbfc6e; + --color-chartreuse-200: #cbf443; + --color-chartreuse-300: #bce92a; + --color-chartreuse-400: #aad816; + --color-chartreuse-500: #98c50a; + --color-chartreuse-600: #87b103; + --color-chartreuse-700: #769c00; + --color-chartreuse-800: #678800; + --color-chartreuse-900: #577400; + --color-chartreuse-1000: #486000; + --color-chartreuse-1100: #3a4d00; + --color-chartreuse-1200: #2c3b00; + --color-chartreuse-1300: #212c00; + + --color-cyan-100: #c5f8ff; + --color-cyan-200: #a4f0ff; + --color-cyan-300: #88e7fa; + --color-cyan-400: #60d8f3; + --color-cyan-500: #33c5e8; + --color-cyan-600: #12b0da; + --color-cyan-700: #019cc8; + --color-cyan-800: #0086b4; + --color-cyan-900: #00719f; + --color-cyan-1000: #005d89; + --color-cyan-1100: #004a73; + --color-cyan-1200: #00395d; + --color-cyan-1300: #002a46; + + --color-fuchsia-100: #ffe9fc; + --color-fuchsia-200: #ffdafa; + --color-fuchsia-300: #fec7f8; + --color-fuchsia-400: #fbaef6; + --color-fuchsia-500: #f592f3; + --color-fuchsia-600: #ed74ed; + --color-fuchsia-700: #e055e2; + --color-fuchsia-800: #cd3ace; + --color-fuchsia-900: #b622b7; + --color-fuchsia-1000: #9d039e; + --color-fuchsia-1100: #800081; + --color-fuchsia-1200: #640664; + --color-fuchsia-1300: #470e46; + + --color-indigo-100: #edeeff; + --color-indigo-200: #e0e2ff; + --color-indigo-300: #d3d5ff; + --color-indigo-400: #c1c4ff; + --color-indigo-500: #acafff; + --color-indigo-600: #9599ff; + --color-indigo-700: #7e84fc; + --color-indigo-800: #686df4; + --color-indigo-900: #5258e4; + --color-indigo-1000: #4046ca; + --color-indigo-1100: #3236a8; + --color-indigo-1200: #262986; + --color-indigo-1300: #1b1e64; + + --color-magenta-100: #ffeaf1; + --color-magenta-200: #ffdce8; + --color-magenta-300: #ffcadd; + --color-magenta-400: #ffb2ce; + --color-magenta-500: #ff95bd; + --color-magenta-600: #fa77aa; + --color-magenta-700: #ef5a98; + --color-magenta-800: #de3d82; + --color-magenta-900: #c82269; + --color-magenta-1000: #ad0955; + --color-magenta-1100: #8e0045; + --color-magenta-1200: #700037; + --color-magenta-1300: #54032a; + + --color-purple-100: #f6ebff; + --color-purple-200: #eeddff; + --color-purple-300: #e6d0ff; + --color-purple-400: #dbbbfe; + --color-purple-500: #cca4fd; + --color-purple-600: #bd8bfc; + --color-purple-700: #ae72f9; + --color-purple-800: #9d57f4; + --color-purple-900: #893de7; + --color-purple-1000: #7326d3; + --color-purple-1100: #5d13b7; + --color-purple-1200: #470c94; + --color-purple-1300: #33106a; + + --color-seafoam-100: #cef7f3; + --color-seafoam-200: #aaf1ea; + --color-seafoam-300: #8ce9e2; + --color-seafoam-400: #65dad2; + --color-seafoam-500: #3fc9c1; + --color-seafoam-600: #0fb5ae; + --color-seafoam-700: #00a19a; + --color-seafoam-800: #008c87; + --color-seafoam-900: #007772; + --color-seafoam-1000: #00635f; + --color-seafoam-1100: #0c4f4c; + --color-seafoam-1200: #123c3a; + --color-seafoam-1300: #122c2b; + + --color-yellow-100: #fbf198; + --color-yellow-200: #f8e750; + --color-yellow-300: #f8d904; + --color-yellow-400: #e8c600; + --color-yellow-500: #d7b300; + --color-yellow-600: #c49f00; + --color-yellow-700: #b08c00; + --color-yellow-800: #9b7800; + --color-yellow-900: #856600; + --color-yellow-1000: #705300; + --color-yellow-1100: #5b4300; + --color-yellow-1200: #483300; + --color-yellow-1300: #362500; + } +} diff --git a/src/apps/seelenweg/styles/global.css b/src/apps/seelenweg/styles/global.css index b7776c6e..3b509dab 100644 --- a/src/apps/seelenweg/styles/global.css +++ b/src/apps/seelenweg/styles/global.css @@ -1,239 +1,239 @@ -/** - * The styles in this file are only structurals for Seelenweg, - * all the design should be added to the default theme css. - */ -body { - overflow: hidden; - cursor: default; - background: transparent; - display: flex; - justify-content: var(--config-by-position-justify-content); - align-items: var(--config-by-position-align-items); - width: 100vw; - height: 100vh; -} - -/** Root Styles */ -.SeelenWeg { - height: min-content; - width: min-content; - margin: var(--config-margin); -} - -/** Taskbar Styles */ -.taskbar { - position: relative; - overflow: visible; - padding: var(--config-padding); - transition: transform 0.2s ease-in-out; - - display: flex; - justify-content: var(--config-by-position-justify-content); - align-items: var(--config-by-position-align-items); - flex-direction: var(--config-by-position-flex-direction); - gap: var(--config-space-between-items); - - &.hidden { - &.left { - transform: translateX(calc(-100% - var(--config-margin))); - } - - &.right { - transform: translateX(calc(100% + var(--config-margin))); - } - - &.top { - transform: translateY(calc(-100% - var(--config-margin))); - } - - &.bottom { - transform: translateY(calc(100% + var(--config-margin))); - } - } - - &.horizontal { - height: calc( - var(--config-item-size) + var(--config-additional-side-padding) + var(--config-padding) * 2 - ); - width: min-content; - - &.full-width { - width: calc(100vw - var(--config-margin) * 2); - } - - &.top { - padding-top: calc(var(--config-padding) + var(--config-additional-side-padding)); - } - - &.bottom { - padding-bottom: calc(var(--config-padding) + var(--config-additional-side-padding)); - } - } - - &.vertical { - width: calc( - var(--config-item-size) + var(--config-additional-side-padding) + var(--config-padding) * 2 - ); - height: min-content; - - &.full-width { - height: calc(100vh - var(--config-margin) * 2); - } - - &.left { - padding-left: calc(var(--config-padding) + var(--config-additional-side-padding)); - } - - &.right { - padding-right: calc(var(--config-padding) + var(--config-additional-side-padding)); - } - } - - .weg-separator { - z-index: 1 !important; /* Override inline style */ - - &:nth-child(2), - &:last-child, - &:not(.visible) { - opacity: 0; - } - - .vertical & { - width: 100%; - - /* first child always is the background */ - &:nth-child(2) { - margin-top: calc(var(--config-space-between-items) * -1); - } - - &:last-child { - margin-bottom: calc(var(--config-space-between-items) * -1); - } - } - - .horizontal & { - height: 100%; - - /* first child always is the background */ - &:nth-child(2) { - margin-left: calc(var(--config-space-between-items) * -1); - } - - &:last-child { - margin-right: calc(var(--config-space-between-items) * -1); - } - } - } - - .weg-item { - position: relative; - display: flex; - justify-content: center; - align-items: center; - - .weg-item-open-sign { - position: absolute; - width: 4px; - height: 4px; - background-color: var(--color-gray-600); - opacity: 0; - - &.weg-item-open-sign-active { - opacity: 1; - } - - &.weg-item-open-sign-focused { - background-color: var(--config-accent-color); - } - - .vertical & { - top: 50%; - transform: translateY(-50%); - } - - .horizontal & { - left: 50%; - transform: translateX(-50%); - } - - .top & { - bottom: calc(100% + var(--config-additional-side-padding)); - } - - .bottom & { - top: calc(100% + var(--config-additional-side-padding)); - } - - .left & { - right: calc(100% + var(--config-additional-side-padding)); - } - - .right & { - left: calc(100% + var(--config-additional-side-padding)); - } - } - } -} - -.weg-item-preview-container { - position: relative; - display: flex; - max-width: 100vw; - overflow-x: auto; - gap: var(--config-space-between-items); - - &::-webkit-scrollbar { - display: none; - } - - .weg-item-preview { - z-index: 1; - - &:hover { - filter: brightness(0.95); - backdrop-filter: brightness(0.95); - } - - .weg-item-preview-topbar { - display: flex; - width: 240px; - justify-content: space-between; - gap: 10px; - - .weg-item-preview-title { - overflow: hidden; - text-wrap: nowrap; - text-overflow: ellipsis; - flex: 1; - } - - .weg-item-preview-close { - border-radius: 6px; - width: 20px; - height: 20px; - display: flex; - align-items: center; - justify-content: center; - line-height: 5px; - - &:hover { - background-color: #0000005c; - } - } - } - - .weg-item-preview-image-container { - width: 240px; - height: calc(240px / 1.77); - display: flex; - justify-content: center; - align-items: center; - - .weg-item-preview-image { - max-height: 100%; - height: 100%; - object-fit: scale-down; - } - } - } -} +/** + * The styles in this file are only structurals for Seelenweg, + * all the design should be added to the default theme css. + */ +body { + overflow: hidden; + cursor: default; + background: transparent; + display: flex; + justify-content: var(--config-by-position-justify-content); + align-items: var(--config-by-position-align-items); + width: 100vw; + height: 100vh; +} + +/** Root Styles */ +.SeelenWeg { + height: min-content; + width: min-content; + margin: var(--config-margin); +} + +/** Taskbar Styles */ +.taskbar { + position: relative; + overflow: visible; + padding: var(--config-padding); + transition: transform 0.2s ease-in-out; + + display: flex; + justify-content: var(--config-by-position-justify-content); + align-items: var(--config-by-position-align-items); + flex-direction: var(--config-by-position-flex-direction); + gap: var(--config-space-between-items); + + &.hidden { + &.left { + transform: translateX(calc(-100% - var(--config-margin))); + } + + &.right { + transform: translateX(calc(100% + var(--config-margin))); + } + + &.top { + transform: translateY(calc(-100% - var(--config-margin))); + } + + &.bottom { + transform: translateY(calc(100% + var(--config-margin))); + } + } + + &.horizontal { + height: calc( + var(--config-item-size) + var(--config-additional-side-padding) + var(--config-padding) * 2 + ); + width: min-content; + + &.full-width { + width: calc(100vw - var(--config-margin) * 2); + } + + &.top { + padding-top: calc(var(--config-padding) + var(--config-additional-side-padding)); + } + + &.bottom { + padding-bottom: calc(var(--config-padding) + var(--config-additional-side-padding)); + } + } + + &.vertical { + width: calc( + var(--config-item-size) + var(--config-additional-side-padding) + var(--config-padding) * 2 + ); + height: min-content; + + &.full-width { + height: calc(100vh - var(--config-margin) * 2); + } + + &.left { + padding-left: calc(var(--config-padding) + var(--config-additional-side-padding)); + } + + &.right { + padding-right: calc(var(--config-padding) + var(--config-additional-side-padding)); + } + } + + .weg-separator { + z-index: 1 !important; /* Override inline style */ + + &:nth-child(2), + &:last-child, + &:not(.visible) { + opacity: 0; + } + + .vertical & { + width: 100%; + + /* first child always is the background */ + &:nth-child(2) { + margin-top: calc(var(--config-space-between-items) * -1); + } + + &:last-child { + margin-bottom: calc(var(--config-space-between-items) * -1); + } + } + + .horizontal & { + height: 100%; + + /* first child always is the background */ + &:nth-child(2) { + margin-left: calc(var(--config-space-between-items) * -1); + } + + &:last-child { + margin-right: calc(var(--config-space-between-items) * -1); + } + } + } + + .weg-item { + position: relative; + display: flex; + justify-content: center; + align-items: center; + + .weg-item-open-sign { + position: absolute; + width: 4px; + height: 4px; + background-color: var(--color-gray-600); + opacity: 0; + + &.weg-item-open-sign-active { + opacity: 1; + } + + &.weg-item-open-sign-focused { + background-color: var(--config-accent-color); + } + + .vertical & { + top: 50%; + transform: translateY(-50%); + } + + .horizontal & { + left: 50%; + transform: translateX(-50%); + } + + .top & { + bottom: calc(100% + var(--config-additional-side-padding)); + } + + .bottom & { + top: calc(100% + var(--config-additional-side-padding)); + } + + .left & { + right: calc(100% + var(--config-additional-side-padding)); + } + + .right & { + left: calc(100% + var(--config-additional-side-padding)); + } + } + } +} + +.weg-item-preview-container { + position: relative; + display: flex; + max-width: 100vw; + overflow-x: auto; + gap: var(--config-space-between-items); + + &::-webkit-scrollbar { + display: none; + } + + .weg-item-preview { + z-index: 1; + + &:hover { + filter: brightness(0.95); + backdrop-filter: brightness(0.95); + } + + .weg-item-preview-topbar { + display: flex; + width: 240px; + justify-content: space-between; + gap: 10px; + + .weg-item-preview-title { + overflow: hidden; + text-wrap: nowrap; + text-overflow: ellipsis; + flex: 1; + } + + .weg-item-preview-close { + border-radius: 6px; + width: 20px; + height: 20px; + display: flex; + align-items: center; + justify-content: center; + line-height: 5px; + + &:hover { + background-color: #0000005c; + } + } + } + + .weg-item-preview-image-container { + width: 240px; + height: calc(240px / 1.77); + display: flex; + justify-content: center; + align-items: center; + + .weg-item-preview-image { + max-height: 100%; + height: 100%; + object-fit: scale-down; + } + } + } +} diff --git a/src/apps/seelenweg/styles/reset.css b/src/apps/seelenweg/styles/reset.css index a360b0f2..dbfaf364 100644 --- a/src/apps/seelenweg/styles/reset.css +++ b/src/apps/seelenweg/styles/reset.css @@ -1,136 +1,136 @@ -:root { - font-size: 100%; - --main-typo: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; - --primary-color: var(--color-gray-900); - --secondary-color: var(--color-gray-50); -} - -*, *:after, *:before { - margin: 0; - padding: 0; - border: 0; - outline: none; - box-sizing: border-box; - vertical-align: baseline; - -webkit-user-select: none; - user-select: none; -} - -img, image, picture, video, iframe, figure { - max-width: 100%; - width: 100%; - display: block; -} - -a { - display: block; -} - -p a { - display: inline; -} - -li { - list-style-type: none; -} - -html { - scroll-behavior: smooth; -} - -h1, h2, h3, h4, h5, h6, p, span, a, strong, blockquote, i, b, em, pre { - font-size: 1em; - font-weight: inherit; - font-style: inherit; - text-decoration: none; - color: inherit; -} - -form, input, textarea, select, button, label { - font-family: inherit; - font-size: inherit; - hyphens: auto; - background-color: transparent; - display: block; - color: inherit; -} - -table, tr, td { - border-collapse: collapse; - border-spacing: 0; -} - -svg { - width: 100%; - display: block; - fill: currentColor; -} - -body { - font-size: 1em; - line-height: 1.4em; - font-family: var(--main-typo); - color: var(--primary-color); - background-color: var(--secondary-color); - hyphens: auto; - font-smooth: always; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -hr { - border: 1px solid; - margin: 1em 0; - opacity: 0.8; - color: var(--color-gray-200); -} - -/* Antd reset */ -#root { - .ant-popover { - .ant-popover-inner { - background: transparent; - border-radius: 0; - box-shadow: none; - padding: 0; - } - } - - .ant-dropdown-menu-submenu, - .ant-dropdown-menu, - .ant-menu { - background: transparent; - box-shadow: none; - display: flex; - flex-direction: column; - gap: 4px; - - .ant-menu-item, - .ant-dropdown-menu-item { - padding: 10px; - height: min-content; - width: 100%; - line-height: 12px; - margin: 0; - border-radius: 8px; - } - - .ant-menu-item:not(.ant-menu-item-danger), - .ant-dropdown-menu-item:not(.ant-dropdown-menu-item-danger) { - color: inherit; - - &:hover { - backdrop-filter: brightness(0.6); - } - } - - .ant-menu-item-divider, - .ant-dropdown-menu-item-divider { - backdrop-filter: brightness(0.85); - } - - .ant-dropdown-menu-submenu-title { - color: inherit; - } - } +:root { + font-size: 100%; + --main-typo: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + --primary-color: var(--color-gray-900); + --secondary-color: var(--color-gray-50); +} + +*, *:after, *:before { + margin: 0; + padding: 0; + border: 0; + outline: none; + box-sizing: border-box; + vertical-align: baseline; + -webkit-user-select: none; + user-select: none; +} + +img, image, picture, video, iframe, figure { + max-width: 100%; + width: 100%; + display: block; +} + +a { + display: block; +} + +p a { + display: inline; +} + +li { + list-style-type: none; +} + +html { + scroll-behavior: smooth; +} + +h1, h2, h3, h4, h5, h6, p, span, a, strong, blockquote, i, b, em, pre { + font-size: 1em; + font-weight: inherit; + font-style: inherit; + text-decoration: none; + color: inherit; +} + +form, input, textarea, select, button, label { + font-family: inherit; + font-size: inherit; + hyphens: auto; + background-color: transparent; + display: block; + color: inherit; +} + +table, tr, td { + border-collapse: collapse; + border-spacing: 0; +} + +svg { + width: 100%; + display: block; + fill: currentColor; +} + +body { + font-size: 1em; + line-height: 1.4em; + font-family: var(--main-typo); + color: var(--primary-color); + background-color: var(--secondary-color); + hyphens: auto; + font-smooth: always; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +hr { + border: 1px solid; + margin: 1em 0; + opacity: 0.8; + color: var(--color-gray-200); +} + +/* Antd reset */ +#root { + .ant-popover { + .ant-popover-inner { + background: transparent; + border-radius: 0; + box-shadow: none; + padding: 0; + } + } + + .ant-dropdown-menu-submenu, + .ant-dropdown-menu, + .ant-menu { + background: transparent; + box-shadow: none; + display: flex; + flex-direction: column; + gap: 4px; + + .ant-menu-item, + .ant-dropdown-menu-item { + padding: 10px; + height: min-content; + width: 100%; + line-height: 12px; + margin: 0; + border-radius: 8px; + } + + .ant-menu-item:not(.ant-menu-item-danger), + .ant-dropdown-menu-item:not(.ant-dropdown-menu-item-danger) { + color: inherit; + + &:hover { + backdrop-filter: brightness(0.6); + } + } + + .ant-menu-item-divider, + .ant-dropdown-menu-item-divider { + backdrop-filter: brightness(0.85); + } + + .ant-dropdown-menu-submenu-title { + color: inherit; + } + } } \ No newline at end of file diff --git a/src/apps/seelenweg/styles/variables.css b/src/apps/seelenweg/styles/variables.css index 24f1ef07..d0edd22b 100644 --- a/src/apps/seelenweg/styles/variables.css +++ b/src/apps/seelenweg/styles/variables.css @@ -1,16 +1,16 @@ -:root { - --config-padding: 0px; - --config-margin: 0px; - --config-additional-side-padding: 4px; - - --config-item-size: 0px; - --config-item-zoom-size: 0px; - --config-space-between-items: 0px; - - --config-accent-color: #ff0000; - --config-accent-color-rgb: 255, 0, 0; - - --config-by-position-justify-content: center; - --config-by-position-align-items: flex-end; - --config-by-position-flex-direction: row; -} +:root { + --config-padding: 0px; + --config-margin: 0px; + --config-additional-side-padding: 4px; + + --config-item-size: 0px; + --config-item-zoom-size: 0px; + --config-space-between-items: 0px; + + --config-accent-color: #ff0000; + --config-accent-color-rgb: 255, 0, 0; + + --config-by-position-justify-content: center; + --config-by-position-align-items: flex-end; + --config-by-position-flex-direction: row; +} diff --git a/src/apps/settings/app.tsx b/src/apps/settings/app.tsx index b1d4f927..d9707b0f 100644 --- a/src/apps/settings/app.tsx +++ b/src/apps/settings/app.tsx @@ -1,68 +1,68 @@ -import { useDarkMode } from '../shared/styles'; -import { Header } from './components/header'; -import { Navigation } from './components/navigation'; -import { Route } from './components/navigation/routes'; -import { ConfigProvider, theme } from 'antd'; -import { Suspense, useEffect } from 'react'; -import { useSelector } from 'react-redux'; - -import { AppsConfiguration } from './modules/appsConfigurations/infra/infra'; -import { DeveloperTools } from './modules/developer/infra'; -import { FancyToolbarSettings } from './modules/fancyToolbar/infra'; -import { General } from './modules/general/main/infra'; -import { Information } from './modules/information/infrastructure'; -import { Monitors } from './modules/monitors/main/infra'; -import { SeelenWegSettings } from './modules/seelenweg/infra'; -import { Shortcuts } from './modules/shortcuts/infrastructure'; -import { WindowManagerSettings } from './modules/WindowManager/main/infra'; - -import { newSelectors } from './modules/shared/store/app/reducer'; -import { RootSelectors } from './modules/shared/store/app/selectors'; - -const ComponentByRout: Record> = { - [Route.GENERAL]: General, - [Route.MONITORS]: Monitors, - [Route.SHORTCUTS]: Shortcuts, - [Route.SPECIFIC_APPS]: AppsConfiguration, - [Route.INFO]: Information, - [Route.SEELEN_WEG]: SeelenWegSettings, - [Route.SEELEN_WM]: WindowManagerSettings, - [Route.SEELEN_BAR]: FancyToolbarSettings, - [Route.DEVELOPER]: DeveloperTools, -}; - -export function App() { - const isDarkMode = useDarkMode(); - const colors = useSelector(newSelectors.colors); - let route = useSelector(RootSelectors.route); - - useEffect(() => { - setTimeout(() => { - let splashscreen = document.getElementById('splashscreen'); - splashscreen?.classList.add('vanish'); - setTimeout(() => splashscreen?.classList.add('hidden'), 300); - }, 300); - }, []); - - let Component = ComponentByRout[route]; - - return ( - - -
-
- Loading...
}> - - -
- - ); -} +import { useDarkMode } from '../shared/styles'; +import { Header } from './components/header'; +import { Navigation } from './components/navigation'; +import { Route } from './components/navigation/routes'; +import { ConfigProvider, theme } from 'antd'; +import { Suspense, useEffect } from 'react'; +import { useSelector } from 'react-redux'; + +import { AppsConfiguration } from './modules/appsConfigurations/infra/infra'; +import { DeveloperTools } from './modules/developer/infra'; +import { FancyToolbarSettings } from './modules/fancyToolbar/infra'; +import { General } from './modules/general/main/infra'; +import { Information } from './modules/information/infrastructure'; +import { Monitors } from './modules/monitors/main/infra'; +import { SeelenWegSettings } from './modules/seelenweg/infra'; +import { Shortcuts } from './modules/shortcuts/infrastructure'; +import { WindowManagerSettings } from './modules/WindowManager/main/infra'; + +import { newSelectors } from './modules/shared/store/app/reducer'; +import { RootSelectors } from './modules/shared/store/app/selectors'; + +const ComponentByRout: Record> = { + [Route.GENERAL]: General, + [Route.MONITORS]: Monitors, + [Route.SHORTCUTS]: Shortcuts, + [Route.SPECIFIC_APPS]: AppsConfiguration, + [Route.INFO]: Information, + [Route.SEELEN_WEG]: SeelenWegSettings, + [Route.SEELEN_WM]: WindowManagerSettings, + [Route.SEELEN_BAR]: FancyToolbarSettings, + [Route.DEVELOPER]: DeveloperTools, +}; + +export function App() { + const isDarkMode = useDarkMode(); + const colors = useSelector(newSelectors.colors); + let route = useSelector(RootSelectors.route); + + useEffect(() => { + setTimeout(() => { + let splashscreen = document.getElementById('splashscreen'); + splashscreen?.classList.add('vanish'); + setTimeout(() => splashscreen?.classList.add('hidden'), 300); + }, 300); + }, []); + + let Component = ComponentByRout[route]; + + return ( + + +
+
+ Loading...
}> + + +
+ + ); +} diff --git a/src/apps/settings/components/SettingsBox/index.module.css b/src/apps/settings/components/SettingsBox/index.module.css index ef928702..85ec017f 100644 --- a/src/apps/settings/components/SettingsBox/index.module.css +++ b/src/apps/settings/components/SettingsBox/index.module.css @@ -1,72 +1,72 @@ -.group { - padding: 10px 20px; - font-size: 0.9rem; - border-radius: var(--config-border-radius); - overflow: hidden; - position: relative; - - &:last-child { - margin-bottom: 10px; - } - - > div { - position: absolute; /* for noise and blur */ - top: 0; - right: 0; - bottom: 0; - left: 0; - } - - &:not(:last-child) { - margin-bottom: 20px; - } - - .noise { - opacity: 0.2; - background-color: var(--color-gray-300); - background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 250 250' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='4' numOctaves='3' stitchTiles='stitch '/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E"); - background-size: cover; - } - - .blur { - backdrop-filter: blur(20px); - } - - .content { - position: relative; - z-index: 1; - - > .box, - > .subgroup { - &:not(:last-child) { - padding-bottom: 6px; - margin-bottom: 6px; - } - } - - .box { - padding: 5px 0; - display: flex; - justify-content: space-between; - align-items: center; - - :global(.ant-input) { - max-width: 150px; - } - } - - .subtitle { - font-weight: 600; - } - - .subgroup { - padding-left: 10px; - - .box { - > span:first-child::before { - content: "- "; - } - } - } - } -} +.group { + padding: 10px 20px; + font-size: 0.9rem; + border-radius: var(--config-border-radius); + overflow: hidden; + position: relative; + + &:last-child { + margin-bottom: 10px; + } + + > div { + position: absolute; /* for noise and blur */ + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + &:not(:last-child) { + margin-bottom: 20px; + } + + .noise { + opacity: 0.2; + background-color: var(--color-gray-300); + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 250 250' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='4' numOctaves='3' stitchTiles='stitch '/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E"); + background-size: cover; + } + + .blur { + backdrop-filter: blur(20px); + } + + .content { + position: relative; + z-index: 1; + + > .box, + > .subgroup { + &:not(:last-child) { + padding-bottom: 6px; + margin-bottom: 6px; + } + } + + .box { + padding: 5px 0; + display: flex; + justify-content: space-between; + align-items: center; + + :global(.ant-input) { + max-width: 150px; + } + } + + .subtitle { + font-weight: 600; + } + + .subgroup { + padding-left: 10px; + + .box { + > span:first-child::before { + content: "- "; + } + } + } + } +} diff --git a/src/apps/settings/components/SettingsBox/index.tsx b/src/apps/settings/components/SettingsBox/index.tsx index f6c6a2cc..be84adc2 100644 --- a/src/apps/settings/components/SettingsBox/index.tsx +++ b/src/apps/settings/components/SettingsBox/index.tsx @@ -1,56 +1,56 @@ -import { ConfigProvider } from 'antd'; - -import cs from './index.module.css'; - -interface Props { - children: React.ReactNode; -} - -export const SettingsGroup = ({ children }: Props) => { - return
-
-
-
{children}
-
; -}; - -interface SubGroupProps { - children: React.ReactNode; - label: React.ReactNode; - disableOptions?: boolean; -} - -export const SettingsSubGroup = ({ children, label, disableOptions }: SubGroupProps) => { - return ( -
-
{label}
- -
{children}
-
-
- ); -}; - -type OptionProps = - | { - children: React.ReactNode; - } - | { - label: React.ReactNode; - trigger: React.ReactNode; - }; - -export const SettingsOption = (props: OptionProps) => { - return ( -
- {'children' in props ? ( - props.children - ) : ( - <> - {props.label} - {props.trigger} - - )} -
- ); -}; +import { ConfigProvider } from 'antd'; + +import cs from './index.module.css'; + +interface Props { + children: React.ReactNode; +} + +export const SettingsGroup = ({ children }: Props) => { + return
+
+
+
{children}
+
; +}; + +interface SubGroupProps { + children: React.ReactNode; + label: React.ReactNode; + disableOptions?: boolean; +} + +export const SettingsSubGroup = ({ children, label, disableOptions }: SubGroupProps) => { + return ( +
+
{label}
+ +
{children}
+
+
+ ); +}; + +type OptionProps = + | { + children: React.ReactNode; + } + | { + label: React.ReactNode; + trigger: React.ReactNode; + }; + +export const SettingsOption = (props: OptionProps) => { + return ( +
+ {'children' in props ? ( + props.children + ) : ( + <> + {props.label} + {props.trigger} + + )} +
+ ); +}; diff --git a/src/apps/settings/components/header/index.module.css b/src/apps/settings/components/header/index.module.css index 09c9bc89..8cc3952b 100644 --- a/src/apps/settings/components/header/index.module.css +++ b/src/apps/settings/components/header/index.module.css @@ -1,14 +1,14 @@ -.Header { - height: 100%; - border-bottom: 1px solid var(--color-gray-200); - font-weight: 600; - padding: 0 14px; - display: flex; - align-items: center; - display: flex; - justify-content: space-between; - - button { - width: 60px; - } +.Header { + height: 100%; + border-bottom: 1px solid var(--color-gray-200); + font-weight: 600; + padding: 0 14px; + display: flex; + align-items: center; + display: flex; + justify-content: space-between; + + button { + width: 60px; + } } \ No newline at end of file diff --git a/src/apps/settings/components/header/index.tsx b/src/apps/settings/components/header/index.tsx index ba3406df..7ab9a6d4 100644 --- a/src/apps/settings/components/header/index.tsx +++ b/src/apps/settings/components/header/index.tsx @@ -1,63 +1,63 @@ -import { RouteExtraInfo } from '../navigation/routes'; -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; -import { Button, Tooltip } from 'antd'; -import { useTranslation } from 'react-i18next'; -import { useDispatch } from 'react-redux'; - -import { SaveStore } from '../../modules/shared/store/infra'; -import { useAppSelector } from '../../modules/shared/utils/infra'; - -import { RootActions } from '../../modules/shared/store/app/reducer'; -import { RootSelectors } from '../../modules/shared/store/app/selectors'; - -import cs from './index.module.css'; - -export const Header = () => { - let route = useAppSelector(RootSelectors.route); - let hasChanges = useAppSelector(RootSelectors.toBeSaved); - - const { t } = useTranslation(); - - const dispatch = useDispatch(); - - const cancelChanges = () => { - dispatch(RootActions.restoreToLastLoaded()); - }; - - const SaveOrQuit = () => { - if (hasChanges) { - SaveStore(); - } else { - getCurrentWebviewWindow().close(); - } - }; - - return ( -
-
- {t(`header.labels.${route}`)} - {RouteExtraInfo[route] && ( - - 🛈 - - )} -
-
-
-
- ); -}; +import { RouteExtraInfo } from '../navigation/routes'; +import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; +import { Button, Tooltip } from 'antd'; +import { useTranslation } from 'react-i18next'; +import { useDispatch } from 'react-redux'; + +import { SaveStore } from '../../modules/shared/store/infra'; +import { useAppSelector } from '../../modules/shared/utils/infra'; + +import { RootActions } from '../../modules/shared/store/app/reducer'; +import { RootSelectors } from '../../modules/shared/store/app/selectors'; + +import cs from './index.module.css'; + +export const Header = () => { + let route = useAppSelector(RootSelectors.route); + let hasChanges = useAppSelector(RootSelectors.toBeSaved); + + const { t } = useTranslation(); + + const dispatch = useDispatch(); + + const cancelChanges = () => { + dispatch(RootActions.restoreToLastLoaded()); + }; + + const SaveOrQuit = () => { + if (hasChanges) { + SaveStore(); + } else { + getCurrentWebviewWindow().close(); + } + }; + + return ( +
+
+ {t(`header.labels.${route}`)} + {RouteExtraInfo[route] && ( + + 🛈 + + )} +
+
+
+
+ ); +}; diff --git a/src/apps/settings/components/monitor/index.module.css b/src/apps/settings/components/monitor/index.module.css index c22ddd05..f33733cb 100644 --- a/src/apps/settings/components/monitor/index.module.css +++ b/src/apps/settings/components/monitor/index.module.css @@ -1,28 +1,28 @@ -.monitor { - height: 144px; - width: 256px; - border-radius: 12px; - background-color: var(--color-persist-gray-800); - padding: 8px; - - .screen { - position: relative; - border-radius: 8px; - background: linear-gradient( - 40deg, - var(--color-blue-500) 2%, - var(--color-blue-300) 60%, - var(--color-blue-100) 100% - ); - width: 100%; - height: 100%; - overflow: hidden; - - .wallpaper { - width: 100%; - height: 100%; - object-fit: cover; - position: absolute; - } - } -} +.monitor { + height: 144px; + width: 256px; + border-radius: 12px; + background-color: var(--color-persist-gray-800); + padding: 8px; + + .screen { + position: relative; + border-radius: 8px; + background: linear-gradient( + 40deg, + var(--color-blue-500) 2%, + var(--color-blue-300) 60%, + var(--color-blue-100) 100% + ); + width: 100%; + height: 100%; + overflow: hidden; + + .wallpaper { + width: 100%; + height: 100%; + object-fit: cover; + position: absolute; + } + } +} diff --git a/src/apps/settings/components/monitor/index.tsx b/src/apps/settings/components/monitor/index.tsx index a40ea314..96e5f958 100644 --- a/src/apps/settings/components/monitor/index.tsx +++ b/src/apps/settings/components/monitor/index.tsx @@ -1,34 +1,34 @@ -import { cx } from '../../../shared/styles'; -import { motion, useAnimationControls } from 'framer-motion'; -import { PropsWithChildren } from 'react'; -import { useSelector } from 'react-redux'; - -import { newSelectors } from '../../modules/shared/store/app/reducer'; - -import cs from './index.module.css'; - -interface Props extends PropsWithChildren, React.HTMLAttributes {} - -export function Monitor({ children, className, ...props }: Props) { - const wallpaper = useSelector(newSelectors.wallpaper); - const controls = useAnimationControls(); - - return ( -
-
- {wallpaper && ( - { - controls.start({ opacity: 1, transition: { duration: 0.3, ease: 'linear' } }); - }} - /> - )} - {children} -
-
- ); -} +import { cx } from '../../../shared/styles'; +import { motion, useAnimationControls } from 'framer-motion'; +import { PropsWithChildren } from 'react'; +import { useSelector } from 'react-redux'; + +import { newSelectors } from '../../modules/shared/store/app/reducer'; + +import cs from './index.module.css'; + +interface Props extends PropsWithChildren, React.HTMLAttributes {} + +export function Monitor({ children, className, ...props }: Props) { + const wallpaper = useSelector(newSelectors.wallpaper); + const controls = useAnimationControls(); + + return ( +
+
+ {wallpaper && ( + { + controls.start({ opacity: 1, transition: { duration: 0.3, ease: 'linear' } }); + }} + /> + )} + {children} +
+
+ ); +} diff --git a/src/apps/settings/components/navigation/index.module.css b/src/apps/settings/components/navigation/index.module.css index 59e35d21..e797370e 100644 --- a/src/apps/settings/components/navigation/index.module.css +++ b/src/apps/settings/components/navigation/index.module.css @@ -1,71 +1,71 @@ -.navigation { - background-color: var(--primary-color); - color: var(--secondary-color); - display: flex; - flex-direction: column; - justify-content: space-between; - padding: 10px; - grid-row: 1/3; - width: 180px; - transition: width 300ms ease, padding 300ms ease; - - &.tableView { - padding: 10px 6px; - width: 40px; - - .item { - .label { - opacity: 0; - } - } - } - - .group { - display: flex; - flex-direction: column; - gap: 6px; - } - - .item { - padding: 3px 5px; - display: flex; - align-items: center; - justify-content: flex-start; - overflow: hidden; - font-size: 0.8rem; - font-weight: 600; - border-radius: var(--config-border-radius); - transition: background-color 300ms ease; - - &:hover { - background-color: var(--config-accent-light-color); - } - - &.active { - background-color: var(--config-accent-color); - } - - .icon { - width: 18px; - min-width: 18px; - display: flex; - justify-content: center; - align-items: center; - } - - .label { - margin-left: 5px; - opacity: 1; - text-wrap: nowrap; - transition: opacity 300ms ease; - } - } -} - -/* Maintains colors on dark mode */ -@media (prefers-color-scheme: dark) { - .navigation { - background-color: var(--secondary-color); - color: var(--primary-color); - } +.navigation { + background-color: var(--primary-color); + color: var(--secondary-color); + display: flex; + flex-direction: column; + justify-content: space-between; + padding: 10px; + grid-row: 1/3; + width: 180px; + transition: width 300ms ease, padding 300ms ease; + + &.tableView { + padding: 10px 6px; + width: 40px; + + .item { + .label { + opacity: 0; + } + } + } + + .group { + display: flex; + flex-direction: column; + gap: 6px; + } + + .item { + padding: 3px 5px; + display: flex; + align-items: center; + justify-content: flex-start; + overflow: hidden; + font-size: 0.8rem; + font-weight: 600; + border-radius: var(--config-border-radius); + transition: background-color 300ms ease; + + &:hover { + background-color: var(--config-accent-light-color); + } + + &.active { + background-color: var(--config-accent-color); + } + + .icon { + width: 18px; + min-width: 18px; + display: flex; + justify-content: center; + align-items: center; + } + + .label { + margin-left: 5px; + opacity: 1; + text-wrap: nowrap; + transition: opacity 300ms ease; + } + } +} + +/* Maintains colors on dark mode */ +@media (prefers-color-scheme: dark) { + .navigation { + background-color: var(--secondary-color); + color: var(--primary-color); + } } \ No newline at end of file diff --git a/src/apps/settings/components/navigation/index.tsx b/src/apps/settings/components/navigation/index.tsx index ef1a1f86..a0508767 100644 --- a/src/apps/settings/components/navigation/index.tsx +++ b/src/apps/settings/components/navigation/index.tsx @@ -1,68 +1,68 @@ -import { Route, RouteIcons, WorkingInProgressRoutes } from './routes'; -import { Tooltip } from 'antd'; -import { memo, useCallback } from 'react'; -import { useTranslation } from 'react-i18next'; - -import { useAppDispatch, useAppSelector } from '../../modules/shared/utils/infra'; - -import { RootActions } from '../../modules/shared/store/app/reducer'; -import { RootSelectors } from '../../modules/shared/store/app/selectors'; -import { cx } from '../../modules/shared/utils/app'; - -import cs from './index.module.css'; - -interface ItemProps { - route: Route; - isActive: boolean; -} - -const Item = ({ route, isActive }: ItemProps) => { - const { t } = useTranslation(); - - let dispatch = useAppDispatch(); - let onclick = useCallback(() => { - if (WorkingInProgressRoutes.includes(route)) { - return; - } - dispatch(RootActions.setRoute(route)); - }, []); - - return ( - -
- {RouteIcons[route]} - {t(`header.labels.${route}`)} -
-
- - ); -}; - -export const Navigation = memo(() => { - let current = useAppSelector(RootSelectors.route); - let devTools = useAppSelector(RootSelectors.devTools); - - let routes = Object.values(Route).filter( - (r) => (r !== Route.DEVELOPER || devTools) && r !== Route.INFO, - ); - - return ( -
-
- {routes.map((route) => ( - - ))} -
- -
- ); -}); +import { Route, RouteIcons, WorkingInProgressRoutes } from './routes'; +import { Tooltip } from 'antd'; +import { memo, useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; + +import { useAppDispatch, useAppSelector } from '../../modules/shared/utils/infra'; + +import { RootActions } from '../../modules/shared/store/app/reducer'; +import { RootSelectors } from '../../modules/shared/store/app/selectors'; +import { cx } from '../../modules/shared/utils/app'; + +import cs from './index.module.css'; + +interface ItemProps { + route: Route; + isActive: boolean; +} + +const Item = ({ route, isActive }: ItemProps) => { + const { t } = useTranslation(); + + let dispatch = useAppDispatch(); + let onclick = useCallback(() => { + if (WorkingInProgressRoutes.includes(route)) { + return; + } + dispatch(RootActions.setRoute(route)); + }, []); + + return ( + +
+ {RouteIcons[route]} + {t(`header.labels.${route}`)} +
+
+ + ); +}; + +export const Navigation = memo(() => { + let current = useAppSelector(RootSelectors.route); + let devTools = useAppSelector(RootSelectors.devTools); + + let routes = Object.values(Route).filter( + (r) => (r !== Route.DEVELOPER || devTools) && r !== Route.INFO, + ); + + return ( +
+
+ {routes.map((route) => ( + + ))} +
+ +
+ ); +}); diff --git a/src/apps/settings/components/navigation/routes.tsx b/src/apps/settings/components/navigation/routes.tsx index f908d8fc..6b00c4ba 100644 --- a/src/apps/settings/components/navigation/routes.tsx +++ b/src/apps/settings/components/navigation/routes.tsx @@ -1,35 +1,35 @@ -import { Icon } from '../../../shared/components/Icon'; -import React from 'react'; - -export enum Route { - GENERAL = 'general', - SEELEN_BAR = 'seelen_bar', - SEELEN_WM = 'seelen_wm', - SEELEN_WEG = 'seelen_weg', - MONITORS = 'monitors', - SPECIFIC_APPS = 'specific_apps', - SHORTCUTS = 'shortcuts', - DEVELOPER = 'developer', - INFO = 'info', -} - -export const WorkingInProgressRoutes = [Route.MONITORS]; - -export const RouteExtraInfo: { [key in Route]?: string } = { - [Route.SPECIFIC_APPS]: ` - Seelen UI use only one identifier per app (first match found) so the order in how are specificated is important, - the latest added will be priorized, as note the table is sorted by default from latest to old. - `, -}; - -export const RouteIcons: Record = { - [Route.GENERAL]: , - [Route.MONITORS]: , - [Route.SEELEN_BAR]: , - [Route.SEELEN_WM]: , - [Route.SEELEN_WEG]: , - [Route.SPECIFIC_APPS]: , - [Route.SHORTCUTS]: '🔡', - [Route.INFO]: , - [Route.DEVELOPER]: , +import { Icon } from '../../../shared/components/Icon'; +import React from 'react'; + +export enum Route { + GENERAL = 'general', + SEELEN_BAR = 'seelen_bar', + SEELEN_WM = 'seelen_wm', + SEELEN_WEG = 'seelen_weg', + MONITORS = 'monitors', + SPECIFIC_APPS = 'specific_apps', + SHORTCUTS = 'shortcuts', + DEVELOPER = 'developer', + INFO = 'info', +} + +export const WorkingInProgressRoutes = [Route.MONITORS]; + +export const RouteExtraInfo: { [key in Route]?: string } = { + [Route.SPECIFIC_APPS]: ` + Seelen UI use only one identifier per app (first match found) so the order in how are specificated is important, + the latest added will be priorized, as note the table is sorted by default from latest to old. + `, +}; + +export const RouteIcons: Record = { + [Route.GENERAL]: , + [Route.MONITORS]: , + [Route.SEELEN_BAR]: , + [Route.SEELEN_WM]: , + [Route.SEELEN_WEG]: , + [Route.SPECIFIC_APPS]: , + [Route.SHORTCUTS]: '🔡', + [Route.INFO]: , + [Route.DEVELOPER]: , }; \ No newline at end of file diff --git a/src/apps/settings/i18n/index.ts b/src/apps/settings/i18n/index.ts index 5779f454..36e91f97 100644 --- a/src/apps/settings/i18n/index.ts +++ b/src/apps/settings/i18n/index.ts @@ -1,98 +1,98 @@ -import { Lang } from '../../shared/lang'; -import i18n from 'i18next'; -import yaml from 'js-yaml'; -import { initReactI18next } from 'react-i18next'; - -i18n.use(initReactI18next).init( - { - lng: 'en', - fallbackLng: 'en', - interpolation: { - escapeValue: false, - }, - debug: true, - resources: {}, - }, - undefined, -); - -export async function loadTranslations() { - const translations: Record = { - en: await import('./translations/en.yml'), - es: await import('./translations/es.yml'), - de: await import('./translations/de.yml'), - zh: await import('./translations/zh.yml'), - ko: await import('./translations/ko.yml'), - fr: await import('./translations/fr.yml'), - ar: await import('./translations/ar.yml'), - ru: await import('./translations/ru.yml'), - hi: await import('./translations/hi.yml'), - ja: await import('./translations/ja.yml'), - pt: await import('./translations/pt.yml'), - it: await import('./translations/it.yml'), - nl: await import('./translations/nl.yml'), - tr: await import('./translations/tr.yml'), - pl: await import('./translations/pl.yml'), - uk: await import('./translations/uk.yml'), - id: await import('./translations/id.yml'), - cs: await import('./translations/cs.yml'), - th: await import('./translations/th.yml'), - vi: await import('./translations/vi.yml'), - ms: await import('./translations/ms.yml'), - he: await import('./translations/he.yml'), - ro: await import('./translations/ro.yml'), - el: await import('./translations/el.yml'), - sv: await import('./translations/sv.yml'), - no: await import('./translations/no.yml'), - fi: await import('./translations/fi.yml'), - da: await import('./translations/da.yml'), - hu: await import('./translations/hu.yml'), - lt: await import('./translations/lt.yml'), - bg: await import('./translations/bg.yml'), - sk: await import('./translations/sk.yml'), - hr: await import('./translations/hr.yml'), - lv: await import('./translations/lv.yml'), - et: await import('./translations/et.yml'), - tl: await import('./translations/tl.yml'), - ca: await import('./translations/ca.yml'), - af: await import('./translations/af.yml'), - bn: await import('./translations/bn.yml'), - fa: await import('./translations/fa.yml'), - pa: await import('./translations/pa.yml'), - sw: await import('./translations/sw.yml'), - ta: await import('./translations/ta.yml'), - ur: await import('./translations/ur.yml'), - cy: await import('./translations/cy.yml'), - am: await import('./translations/am.yml'), - hy: await import('./translations/hy.yml'), - az: await import('./translations/az.yml'), - eu: await import('./translations/eu.yml'), - bs: await import('./translations/bs.yml'), - ka: await import('./translations/ka.yml'), - gu: await import('./translations/gu.yml'), - is: await import('./translations/is.yml'), - km: await import('./translations/km.yml'), - ku: await import('./translations/ku.yml'), - lo: await import('./translations/lo.yml'), - lb: await import('./translations/lb.yml'), - mk: await import('./translations/mk.yml'), - mt: await import('./translations/mt.yml'), - mn: await import('./translations/mn.yml'), - ne: await import('./translations/ne.yml'), - ps: await import('./translations/ps.yml'), - sr: await import('./translations/sr.yml'), - si: await import('./translations/si.yml'), - so: await import('./translations/so.yml'), - tg: await import('./translations/tg.yml'), - te: await import('./translations/te.yml'), - uz: await import('./translations/uz.yml'), - yo: await import('./translations/yo.yml'), - zu: await import('./translations/zu.yml'), - }; - - for (const [key, value] of Object.entries(translations)) { - i18n.addResourceBundle(key, 'translation', yaml.load(value.default)); - } -} - -export default i18n; +import { Lang } from '../../shared/lang'; +import i18n from 'i18next'; +import yaml from 'js-yaml'; +import { initReactI18next } from 'react-i18next'; + +i18n.use(initReactI18next).init( + { + lng: 'en', + fallbackLng: 'en', + interpolation: { + escapeValue: false, + }, + debug: true, + resources: {}, + }, + undefined, +); + +export async function loadTranslations() { + const translations: Record = { + en: await import('./translations/en.yml'), + es: await import('./translations/es.yml'), + de: await import('./translations/de.yml'), + zh: await import('./translations/zh.yml'), + ko: await import('./translations/ko.yml'), + fr: await import('./translations/fr.yml'), + ar: await import('./translations/ar.yml'), + ru: await import('./translations/ru.yml'), + hi: await import('./translations/hi.yml'), + ja: await import('./translations/ja.yml'), + pt: await import('./translations/pt.yml'), + it: await import('./translations/it.yml'), + nl: await import('./translations/nl.yml'), + tr: await import('./translations/tr.yml'), + pl: await import('./translations/pl.yml'), + uk: await import('./translations/uk.yml'), + id: await import('./translations/id.yml'), + cs: await import('./translations/cs.yml'), + th: await import('./translations/th.yml'), + vi: await import('./translations/vi.yml'), + ms: await import('./translations/ms.yml'), + he: await import('./translations/he.yml'), + ro: await import('./translations/ro.yml'), + el: await import('./translations/el.yml'), + sv: await import('./translations/sv.yml'), + no: await import('./translations/no.yml'), + fi: await import('./translations/fi.yml'), + da: await import('./translations/da.yml'), + hu: await import('./translations/hu.yml'), + lt: await import('./translations/lt.yml'), + bg: await import('./translations/bg.yml'), + sk: await import('./translations/sk.yml'), + hr: await import('./translations/hr.yml'), + lv: await import('./translations/lv.yml'), + et: await import('./translations/et.yml'), + tl: await import('./translations/tl.yml'), + ca: await import('./translations/ca.yml'), + af: await import('./translations/af.yml'), + bn: await import('./translations/bn.yml'), + fa: await import('./translations/fa.yml'), + pa: await import('./translations/pa.yml'), + sw: await import('./translations/sw.yml'), + ta: await import('./translations/ta.yml'), + ur: await import('./translations/ur.yml'), + cy: await import('./translations/cy.yml'), + am: await import('./translations/am.yml'), + hy: await import('./translations/hy.yml'), + az: await import('./translations/az.yml'), + eu: await import('./translations/eu.yml'), + bs: await import('./translations/bs.yml'), + ka: await import('./translations/ka.yml'), + gu: await import('./translations/gu.yml'), + is: await import('./translations/is.yml'), + km: await import('./translations/km.yml'), + ku: await import('./translations/ku.yml'), + lo: await import('./translations/lo.yml'), + lb: await import('./translations/lb.yml'), + mk: await import('./translations/mk.yml'), + mt: await import('./translations/mt.yml'), + mn: await import('./translations/mn.yml'), + ne: await import('./translations/ne.yml'), + ps: await import('./translations/ps.yml'), + sr: await import('./translations/sr.yml'), + si: await import('./translations/si.yml'), + so: await import('./translations/so.yml'), + tg: await import('./translations/tg.yml'), + te: await import('./translations/te.yml'), + uz: await import('./translations/uz.yml'), + yo: await import('./translations/yo.yml'), + zu: await import('./translations/zu.yml'), + }; + + for (const [key, value] of Object.entries(translations)) { + i18n.addResourceBundle(key, 'translation', yaml.load(value.default)); + } +} + +export default i18n; diff --git a/src/apps/settings/i18n/translations/af.yml b/src/apps/settings/i18n/translations/af.yml index 0be5962a..b0eeb003 100644 --- a/src/apps/settings/i18n/translations/af.yml +++ b/src/apps/settings/i18n/translations/af.yml @@ -1,195 +1,195 @@ -sides: - top: Top - bottom: Bodem - left: Links - right: Regs -header: - labels: - developer: Ontwikkelaar - shortcuts: Kortpaaie - monitors: Monitors - general: Generaal - seelen_bar: Fancy -werkbalk - seelen_wm: Vensterbestuurder - seelen_weg: Dock/Taakbalk - info: Informasie - specific_apps: Spesifieke programme -start: - title: Welkom! - message: >- - Welkom by Seelen UI, die uiteindelike tafelrekenaaromgewing met 'n ingelyfde - teëlbestuurder om u Windows 11 -ervaring te verbeter! Ontdek 'n nuwe era van - doeltreffendheid en multitasking met ons intuïtiewe koppelvlak en gevorderde - funksies. - message_accent: Optimaliseer u produktiwiteit met styl! -general: - theme: - add: Voeg tema by - label: Tema -inligting - author: Outeur - description: Beskrywing - added: Tema reeds bygevoeg - tags: Tags - placeholder: Kies tema - enabled: Ingeskakelde temas - selected: Gekies - available: Beskikbaar - language: Taal - startup: Hardloop met opstart? - icon_pack: - label: Ikoonpakkies - accent_color: Aksentkleur -toolbar: - placeholder: - author: Outeur - description: Beskrywing - select: Werkbalkstruktuur - height: Hoogte - enable: Aktiveer Fancy Toolbar -wm: - border: - width: Grenswydte - enable: Aktiveer venster se grens - offset: Grens offset - author: Outeur - description: Beskrywing - disabled_windows10: Die vensterbestuurder is nie beskikbaar vir Windows 10 nie. - space_between_containers: Ruimte tussen houers - resize_delta: Verander die grootte delta (%) - layout: Uitleg - workspace_offset: Werkruimtes offset (marges) - workspace_padding: Werkruimtes opvulling - enable: Aktiveer vensterbestuurder -weg: - items: - visible_separators: Sigbare skeiers - label: Voorwerpe - gap: Ruimte tussen items - zoom_size: Ingezoomde grootte (gebruik vir temas) - size: Itemgrootte - dock_side: Dokkant - label: Dock/Taakbalk - margin: Marge - enable: Aktiveer dok/taakbalk - width: Wydte - auto_hide: Outo -vel - padding: Opvulling - gap: Gat -devtools: - app_folders: APP -vouers - load: Vrag - install_folder: Installasie -lêergids - data_folder: Datapap - settings_file: Instellingslêer - enable: Aktiveer ontwikkelaarsgereedskap - custom_config_file: Laai Custom Config -lêer -apps_configurations: - app: - options: - float: Dryf - force: Kragbestuur - pinned: Vasgaan - unmanage: Onhandiging - ok_create: Skep - name: Naam - ok_readonly: Wysig as nuut - monitor_placeholder: Geen - category_placeholder: Geen - monitor: Monitor - title_create: Skep {{name}} - title_readonly: Besigtig {{name}} - options_label: Ekstra opsies - ok_edit: Opdateer - workspace_placeholder: Geen - bindings: Binding (let op albei opsies is nodig) - workspace: Werkruimte - category: Kategorie - title_edit: Ingebou {{name}} - identifier: - remove: Vee blok uit - add_block: Voeg blok by - kind: Identifiseer deur - matching_strategy: Bypassende strategie - and: En - id: Identifiseerder - negation: Ontken ooreenstemming - or: Of - import: Invoerproduk - delete: Verwyder - export: Uitvoer - bundled_msg: >- - Hierdie saamgevoegde konfigurasies is nie bewerkbaar nie en is ontwerp om u - die beste ervaring sonder aanpassing te bied. Hulle stel outomaties die - algemeenste toepassings vir u op. - new: Nuut - bundled_title: App -konfigurasie saam met Seelen - confirm_delete_title: Bevestig delete - confirm_delete: Is u seker dat u hierdie konfigurasie/s wil uitvee? - swap: Ruil - search: Soek -extras: - relaunch: Herlaai - links: Amptelike skakels - discord: Teenstrydigheid - version: Weergawe - github: Github - exit: Hou op/uitgang -shortcuts: - labels: - increase_width: Verhoog die breedte - reserve_top: Reserve Top - switch_workspace_6: Skakel oor na Workspace 6 - focus_left: Fokus links - send_to_workspace_7: Stuur na Workspace 7 - reserve_right: Reserveer reg - move_to_workspace_0: Beweeg na werkruimte 0 - reserve_float: Reservaat vlot - switch_workspace_0: Skakel oor na werkruimte 0 - focus_right: Fokus reg - switch_workspace_7: Skakel oor na Workspace 7 - move_to_workspace_4: Beweeg na Workspace 4 - move_to_workspace_1: Beweeg na werkruimte 1 - switch_workspace_5: Skakel oor na Workspace 5 - switch_workspace_3: Skakel oor na Workspace 3 - focus_bottom: Fokus onder - reserve_left: Reservaat links - send_to_workspace_6: Stuur na Workspace 6 - send_to_workspace_3: Stuur na Workspace 3 - send_to_workspace_8: Stuur na Workspace 8 - switch_workspace_1: Skakel oor na werkruimte 1 - move_to_workspace_7: Beweeg na Workspace 7 - move_to_workspace_6: Beweeg na Workspace 6 - send_to_workspace_5: Stuur na Workspace 5 - send_to_workspace_1: Stuur na Workspace 1 - switch_workspace_9: Skakel oor na Workspace 9 - send_to_workspace_2: Stuur na Workspace 2 - switch_workspace_2: Skakel oor na Workspace 2 - move_to_workspace_3: Beweeg na Workspace 3 - switch_workspace_8: Skakel oor na Workspace 8 - reserve_stack: Reservaatstapel - focus_top: Fokus top - send_to_workspace_0: Stuur na werkruimte 0 - move_to_workspace_9: Beweeg na Workspace 9 - send_to_workspace_4: Stuur na Workspace 4 - move_to_workspace_8: Beweeg na Workspace 8 - send_to_workspace_9: Stuur na Workspace 9 - move_to_workspace_2: Beweeg na Workspace 2 - move_to_workspace_5: Beweeg na Workspace 5 - increase_height: Verhoog die hoogte - restore_sizes: Herstel groottes - switch_workspace_4: Skakel oor na Workspace 4 - decrease_width: Verminder breedte - decrease_height: Verminder hoogte - reserve_bottom: Reservaat onder - focus_latest: Fokus nuut - enable: Aktiveer geïntegreerde kortpaaie (AHK) - enable_tooltip: >- - Deaktiveer as u u eie kortpaaie sal implementeer met behulp van die Seelen - Core API -open: Oopmaak -loading: Laai ... -save: Red -cancel: Kanselleer -inProgress: Aan die gang ... -quit: Laat vaar -delete: Verwyder +sides: + top: Top + bottom: Bodem + left: Links + right: Regs +header: + labels: + developer: Ontwikkelaar + shortcuts: Kortpaaie + monitors: Monitors + general: Generaal + seelen_bar: Fancy -werkbalk + seelen_wm: Vensterbestuurder + seelen_weg: Dock/Taakbalk + info: Informasie + specific_apps: Spesifieke programme +start: + title: Welkom! + message: >- + Welkom by Seelen UI, die uiteindelike tafelrekenaaromgewing met 'n ingelyfde + teëlbestuurder om u Windows 11 -ervaring te verbeter! Ontdek 'n nuwe era van + doeltreffendheid en multitasking met ons intuïtiewe koppelvlak en gevorderde + funksies. + message_accent: Optimaliseer u produktiwiteit met styl! +general: + theme: + add: Voeg tema by + label: Tema -inligting + author: Outeur + description: Beskrywing + added: Tema reeds bygevoeg + tags: Tags + placeholder: Kies tema + enabled: Ingeskakelde temas + selected: Gekies + available: Beskikbaar + language: Taal + startup: Hardloop met opstart? + icon_pack: + label: Ikoonpakkies + accent_color: Aksentkleur +toolbar: + placeholder: + author: Outeur + description: Beskrywing + select: Werkbalkstruktuur + height: Hoogte + enable: Aktiveer Fancy Toolbar +wm: + border: + width: Grenswydte + enable: Aktiveer venster se grens + offset: Grens offset + author: Outeur + description: Beskrywing + disabled_windows10: Die vensterbestuurder is nie beskikbaar vir Windows 10 nie. + space_between_containers: Ruimte tussen houers + resize_delta: Verander die grootte delta (%) + layout: Uitleg + workspace_offset: Werkruimtes offset (marges) + workspace_padding: Werkruimtes opvulling + enable: Aktiveer vensterbestuurder +weg: + items: + visible_separators: Sigbare skeiers + label: Voorwerpe + gap: Ruimte tussen items + zoom_size: Ingezoomde grootte (gebruik vir temas) + size: Itemgrootte + dock_side: Dokkant + label: Dock/Taakbalk + margin: Marge + enable: Aktiveer dok/taakbalk + width: Wydte + auto_hide: Outo -vel + padding: Opvulling + gap: Gat +devtools: + app_folders: APP -vouers + load: Vrag + install_folder: Installasie -lêergids + data_folder: Datapap + settings_file: Instellingslêer + enable: Aktiveer ontwikkelaarsgereedskap + custom_config_file: Laai Custom Config -lêer +apps_configurations: + app: + options: + float: Dryf + force: Kragbestuur + pinned: Vasgaan + unmanage: Onhandiging + ok_create: Skep + name: Naam + ok_readonly: Wysig as nuut + monitor_placeholder: Geen + category_placeholder: Geen + monitor: Monitor + title_create: Skep {{name}} + title_readonly: Besigtig {{name}} + options_label: Ekstra opsies + ok_edit: Opdateer + workspace_placeholder: Geen + bindings: Binding (let op albei opsies is nodig) + workspace: Werkruimte + category: Kategorie + title_edit: Ingebou {{name}} + identifier: + remove: Vee blok uit + add_block: Voeg blok by + kind: Identifiseer deur + matching_strategy: Bypassende strategie + and: En + id: Identifiseerder + negation: Ontken ooreenstemming + or: Of + import: Invoerproduk + delete: Verwyder + export: Uitvoer + bundled_msg: >- + Hierdie saamgevoegde konfigurasies is nie bewerkbaar nie en is ontwerp om u + die beste ervaring sonder aanpassing te bied. Hulle stel outomaties die + algemeenste toepassings vir u op. + new: Nuut + bundled_title: App -konfigurasie saam met Seelen + confirm_delete_title: Bevestig delete + confirm_delete: Is u seker dat u hierdie konfigurasie/s wil uitvee? + swap: Ruil + search: Soek +extras: + relaunch: Herlaai + links: Amptelike skakels + discord: Teenstrydigheid + version: Weergawe + github: Github + exit: Hou op/uitgang +shortcuts: + labels: + increase_width: Verhoog die breedte + reserve_top: Reserve Top + switch_workspace_6: Skakel oor na Workspace 6 + focus_left: Fokus links + send_to_workspace_7: Stuur na Workspace 7 + reserve_right: Reserveer reg + move_to_workspace_0: Beweeg na werkruimte 0 + reserve_float: Reservaat vlot + switch_workspace_0: Skakel oor na werkruimte 0 + focus_right: Fokus reg + switch_workspace_7: Skakel oor na Workspace 7 + move_to_workspace_4: Beweeg na Workspace 4 + move_to_workspace_1: Beweeg na werkruimte 1 + switch_workspace_5: Skakel oor na Workspace 5 + switch_workspace_3: Skakel oor na Workspace 3 + focus_bottom: Fokus onder + reserve_left: Reservaat links + send_to_workspace_6: Stuur na Workspace 6 + send_to_workspace_3: Stuur na Workspace 3 + send_to_workspace_8: Stuur na Workspace 8 + switch_workspace_1: Skakel oor na werkruimte 1 + move_to_workspace_7: Beweeg na Workspace 7 + move_to_workspace_6: Beweeg na Workspace 6 + send_to_workspace_5: Stuur na Workspace 5 + send_to_workspace_1: Stuur na Workspace 1 + switch_workspace_9: Skakel oor na Workspace 9 + send_to_workspace_2: Stuur na Workspace 2 + switch_workspace_2: Skakel oor na Workspace 2 + move_to_workspace_3: Beweeg na Workspace 3 + switch_workspace_8: Skakel oor na Workspace 8 + reserve_stack: Reservaatstapel + focus_top: Fokus top + send_to_workspace_0: Stuur na werkruimte 0 + move_to_workspace_9: Beweeg na Workspace 9 + send_to_workspace_4: Stuur na Workspace 4 + move_to_workspace_8: Beweeg na Workspace 8 + send_to_workspace_9: Stuur na Workspace 9 + move_to_workspace_2: Beweeg na Workspace 2 + move_to_workspace_5: Beweeg na Workspace 5 + increase_height: Verhoog die hoogte + restore_sizes: Herstel groottes + switch_workspace_4: Skakel oor na Workspace 4 + decrease_width: Verminder breedte + decrease_height: Verminder hoogte + reserve_bottom: Reservaat onder + focus_latest: Fokus nuut + enable: Aktiveer geïntegreerde kortpaaie (AHK) + enable_tooltip: >- + Deaktiveer as u u eie kortpaaie sal implementeer met behulp van die Seelen + Core API +open: Oopmaak +loading: Laai ... +save: Red +cancel: Kanselleer +inProgress: Aan die gang ... +quit: Laat vaar +delete: Verwyder diff --git a/src/apps/settings/i18n/translations/am.yml b/src/apps/settings/i18n/translations/am.yml index 89fdf7f1..38a276af 100644 --- a/src/apps/settings/i18n/translations/am.yml +++ b/src/apps/settings/i18n/translations/am.yml @@ -1,190 +1,190 @@ -sides: - right: ቀኝ - left: ግራ - top: ከላይ - bottom: ታች -header: - labels: - developer: ገንቢ - general: አጠቃላይ - info: መረጃ - seelen_weg: Dock / Accorbar - shortcuts: አቋራጮች - specific_apps: የተወሰኑ መተግበሪያዎች - seelen_bar: Fancy የመሣሪያ አሞሌ - monitors: ተቆጣጣሪዎች - seelen_wm: የመስኮት አቀናባሪ -start: - title: እንኳን ደህና መጣህ! - message: >- - የእርስዎን ዊንዶውስ 11 ተሞክሮ ለማሳደግ ከተዋሃደ ድንገተኛ የዊንዶውስ ሥራ አስኪያጅ ጋር ወደ ደመወዝ የዴስክቶፕ ሥራ - አስኪያጅ እንኳን በደህና መጡ! አዲስ የብቃት እና የብዝበዛ ኢቫን እና ባለብዙ ፊደል እና የላቁ ባህሪያችን ጋር ይሳለቁ. - message_accent: ምርታማነትዎን በቅጥ ያሻሽሉ! -general: - theme: - description: መግለጫ - tags: መለያዎች - label: ጭብጥ መረጃ - add: ጭብጥ ያክሉ - author: ደራሲ ደራሲ - added: ጭብጥ ቀድሞውኑ ታክሏል - placeholder: ጭብጥ ይምረጡ - enabled: አስቁ - selected: ተመር selected ል - available: ይገኛል - startup: ጅምር ላይ ይሮጡ? - language: ቋንቋ - icon_pack: - label: አዶዎች ፓኬጆች - accent_color: የዝግጅት ቀለም -toolbar: - placeholder: - description: መግለጫ - select: የመሣሪያ አሞሌ መዋቅር - author: ደራሲ ደራሲ - height: ቁመት - enable: Fangance የመሳሪያ አሞሌን ያንቁ -wm: - border: - width: ድንበር ስፋት - offset: ድንበር ማካካሻ - enable: የመስኮት ድንበር አንቃ - description: መግለጫ - layout: አቀማመጥ - space_between_containers: በእቃ መጫዎቻዎች መካከል ያለው ቦታ - disabled_windows10: የመስክ ሥራ አስኪያጁ ለዊንዶውስ 10 አይገኝም. - enable: የመስኮት አቀናባሪን አንቃ - workspace_offset: የስራ ቦታዎች ማካካሻ (ማርጂኖች) - workspace_padding: የስራ ቦታዎች ፓድ - resize_delta: ዴልታ (%) - author: ደራሲ ደራሲ -weg: - items: - zoom_size: አራዊት መጠን (ለጭቦች ጥቅም ላይ የዋለው) - gap: በእቃዎች መካከል ቦታ - label: ዕቃዎች - size: የንጥል መጠን - visible_separators: የሚታዩ መለያዎች - margin: ህዳግ - auto_hide: ራስ-ሰር መደበቅ - padding: ፓድ - enable: መትከያ / ተግባር አሞሌን ያንቁ - width: ስፋት - gap: ክፍተት - label: Dock / Accorbar - dock_side: ጎን -devtools: - app_folders: የመተግበሪያ አቃፊዎች - data_folder: የውሂብ አቃፊ - load: ጭነት - custom_config_file: ብጁ ውቅያ ፋይልን ይጫኑ - install_folder: የመጫን አቃፊ - enable: የገንቢ መሳሪያዎችን ያንቁ - settings_file: የቅንብሮች ፋይል -apps_configurations: - app: - options: - float: ተንሳፋፊ - pinned: ተያይ ated ል - unmanage: አለመግባባት - force: ኃይል ማስተዳደር - monitor_placeholder: የለም - monitor: ተቆጣጠር - category_placeholder: የለም - name: ስም - ok_create: ፍጠር - workspace_placeholder: የለም - ok_edit: ዝመና - workspace: የስራ ቦታ - title_edit: አርትዕ {{{N}}} - bindings: ማሰሪያ (ሁለቱንም አማራጮች ልብ ይበሉ) - title_readonly: '{{{}}}}' - title_create: '{{{ስም} መፍጠር}}' - category: ምድብ - ok_readonly: እንደ አዲስ ያርትዑ - options_label: ተጨማሪ አማራጮች - identifier: - remove: ብሎክ ሰርዝ - and: እና - or: ወይም - id: መለያ - kind: መለየት በ - add_block: ብሎክ ያክሉ - negation: ማዛመድን - matching_strategy: ተዛማጅ ስትራቴጂ - new: አዲስ - search: ፍለጋ - confirm_delete: እርግጠኛ ነዎት ይህንን ውቅር / ቶች መሰረዝ ይፈልጋሉ? - confirm_delete_title: መሰረዝ ያረጋግጡ - bundled_title: የመተግበሪያ ውቅረት በጥይት የተደመሰሰ - bundled_msg: >- - እነዚህ የታሸጉ ውቅሮች አርት edity ት አይደሉም እናም ያለ ማበጀት ምርጥ ተሞክሮዎን ለማቅረብ የተቀየሱ ናቸው. በጣም - የተለመዱ ትግበራዎችን በራስ-ሰር ያዋቅሩታል. - delete: ሰርዝ - export: ወደ ውጭ ይላኩ - swap: መቀያየር - import: ማስመጣት -extras: - links: ኦፊሴላዊ አገናኞች - github: Github - discord: አለመግባባት - version: ስሪት - exit: ማቆም / መውጣት - relaunch: እንደገና መነገር -shortcuts: - labels: - send_to_workspace_2: ወደ የስራ ቦታ 2 ይላኩ 2 - reserve_left: የተቆራረጠ - increase_height: ቁመት ይጨምሩ - send_to_workspace_1: ወደ የስራ ቦታ 1 ይላኩ 1 - reserve_bottom: የተጠባበቅ ክፍል - switch_workspace_1: ወደ የሥራ ቦታ 1 ቀይር - switch_workspace_0: ወደ የሥራ ቦታ 0 ይቀይሩ - move_to_workspace_0: ወደ የሥራ ቦታ 0 ይሂዱ - send_to_workspace_5: ወደ የሥራ ቦታ 5 ይላኩ - switch_workspace_9: ወደ የሥራ ቦታ 9 ቀይር - switch_workspace_7: ወደ የሥራ ቦታ 7 ቀይር - decrease_height: ቁመት ቀንሷል - increase_width: ስፋት መጨመር - switch_workspace_6: ወደ የሥራ ቦታ 6 ይቀይሩ - move_to_workspace_3: ወደ የሥራ ቦታ 3 ይሂዱ - move_to_workspace_1: ወደ የሥራ ቦታ 1 ይሂዱ - focus_right: በትክክል ትኩረት ያድርጉ - focus_bottom: ወደ ታች ትኩረት - send_to_workspace_0: ወደ የስራ ቦታ 0 ይላኩ 0 - switch_workspace_8: ወደ የሥራ ቦታ 8 ቀይር - move_to_workspace_9: ወደ የሥራ ቦታ 9 ይሂዱ - move_to_workspace_4: ወደ የሥራ ቦታ 4 ይሂዱ - send_to_workspace_3: ወደ የስራ ቦታ 3 ይላኩ - reserve_stack: የተጠባባቂ ቁልል - move_to_workspace_5: ወደ የሥራ ቦታ 5 ይሂዱ - move_to_workspace_8: ወደ የሥራ ቦታ 8 ይሂዱ - move_to_workspace_7: ወደ የሥራ ቦታ 7 ይሂዱ - send_to_workspace_7: ወደ የሥራ ቦታ 7 ይላኩ 7 - focus_top: ትኩረት - focus_left: ትኩረት ቀርቷል - move_to_workspace_2: ወደ የሥራ ቦታ 2 ይሂዱ - switch_workspace_4: ወደ የሥራ ቦታ 4 ይቀይሩ - switch_workspace_3: ወደ የስራ ቦታ 3 ቀይር - send_to_workspace_9: ወደ የሥራ ቦታ 9 ይላኩ - send_to_workspace_6: ወደ የሥራ ቦታ 6 ይላኩ - switch_workspace_5: ወደ የሥራ ቦታ 5 ቀይር - reserve_top: የላይኛው ክፍል - focus_latest: የቅርብ ጊዜዎችን ያተኩሩ - reserve_float: የተጠባባቂ ተንሳፋፊ - send_to_workspace_4: ወደ የሥራ ቦታ 4 ይላኩ - switch_workspace_2: ወደ የሥራ ቦታ 2 ቀይር - move_to_workspace_6: ወደ የሥራ ቦታ 1 ይሂዱ - send_to_workspace_8: ወደ የሥራ ቦታ 8 ይላኩ 8 - restore_sizes: መጠኖች ወደነበሩበት ይመልሱ - reserve_right: መብት - decrease_width: ስፋት መቀነስ - enable: የተቀናጁ አቋራጮችን (AHK) - enable_tooltip: የእራስዎን አቋራጮዎች ​​የሚተገበሩትን የእራስዎን አቋራጮች የሚተገበሩ ከሆነ ያሰናክሉ -inProgress: በሂደት ላይ... -open: ክፈት -cancel: ይቅር -delete: ሰርዝ -quit: አቁም -loading: በመጫን ላይ ... -save: አስቀምጥ +sides: + right: ቀኝ + left: ግራ + top: ከላይ + bottom: ታች +header: + labels: + developer: ገንቢ + general: አጠቃላይ + info: መረጃ + seelen_weg: Dock / Accorbar + shortcuts: አቋራጮች + specific_apps: የተወሰኑ መተግበሪያዎች + seelen_bar: Fancy የመሣሪያ አሞሌ + monitors: ተቆጣጣሪዎች + seelen_wm: የመስኮት አቀናባሪ +start: + title: እንኳን ደህና መጣህ! + message: >- + የእርስዎን ዊንዶውስ 11 ተሞክሮ ለማሳደግ ከተዋሃደ ድንገተኛ የዊንዶውስ ሥራ አስኪያጅ ጋር ወደ ደመወዝ የዴስክቶፕ ሥራ + አስኪያጅ እንኳን በደህና መጡ! አዲስ የብቃት እና የብዝበዛ ኢቫን እና ባለብዙ ፊደል እና የላቁ ባህሪያችን ጋር ይሳለቁ. + message_accent: ምርታማነትዎን በቅጥ ያሻሽሉ! +general: + theme: + description: መግለጫ + tags: መለያዎች + label: ጭብጥ መረጃ + add: ጭብጥ ያክሉ + author: ደራሲ ደራሲ + added: ጭብጥ ቀድሞውኑ ታክሏል + placeholder: ጭብጥ ይምረጡ + enabled: አስቁ + selected: ተመር selected ል + available: ይገኛል + startup: ጅምር ላይ ይሮጡ? + language: ቋንቋ + icon_pack: + label: አዶዎች ፓኬጆች + accent_color: የዝግጅት ቀለም +toolbar: + placeholder: + description: መግለጫ + select: የመሣሪያ አሞሌ መዋቅር + author: ደራሲ ደራሲ + height: ቁመት + enable: Fangance የመሳሪያ አሞሌን ያንቁ +wm: + border: + width: ድንበር ስፋት + offset: ድንበር ማካካሻ + enable: የመስኮት ድንበር አንቃ + description: መግለጫ + layout: አቀማመጥ + space_between_containers: በእቃ መጫዎቻዎች መካከል ያለው ቦታ + disabled_windows10: የመስክ ሥራ አስኪያጁ ለዊንዶውስ 10 አይገኝም. + enable: የመስኮት አቀናባሪን አንቃ + workspace_offset: የስራ ቦታዎች ማካካሻ (ማርጂኖች) + workspace_padding: የስራ ቦታዎች ፓድ + resize_delta: ዴልታ (%) + author: ደራሲ ደራሲ +weg: + items: + zoom_size: አራዊት መጠን (ለጭቦች ጥቅም ላይ የዋለው) + gap: በእቃዎች መካከል ቦታ + label: ዕቃዎች + size: የንጥል መጠን + visible_separators: የሚታዩ መለያዎች + margin: ህዳግ + auto_hide: ራስ-ሰር መደበቅ + padding: ፓድ + enable: መትከያ / ተግባር አሞሌን ያንቁ + width: ስፋት + gap: ክፍተት + label: Dock / Accorbar + dock_side: ጎን +devtools: + app_folders: የመተግበሪያ አቃፊዎች + data_folder: የውሂብ አቃፊ + load: ጭነት + custom_config_file: ብጁ ውቅያ ፋይልን ይጫኑ + install_folder: የመጫን አቃፊ + enable: የገንቢ መሳሪያዎችን ያንቁ + settings_file: የቅንብሮች ፋይል +apps_configurations: + app: + options: + float: ተንሳፋፊ + pinned: ተያይ ated ል + unmanage: አለመግባባት + force: ኃይል ማስተዳደር + monitor_placeholder: የለም + monitor: ተቆጣጠር + category_placeholder: የለም + name: ስም + ok_create: ፍጠር + workspace_placeholder: የለም + ok_edit: ዝመና + workspace: የስራ ቦታ + title_edit: አርትዕ {{{N}}} + bindings: ማሰሪያ (ሁለቱንም አማራጮች ልብ ይበሉ) + title_readonly: '{{{}}}}' + title_create: '{{{ስም} መፍጠር}}' + category: ምድብ + ok_readonly: እንደ አዲስ ያርትዑ + options_label: ተጨማሪ አማራጮች + identifier: + remove: ብሎክ ሰርዝ + and: እና + or: ወይም + id: መለያ + kind: መለየት በ + add_block: ብሎክ ያክሉ + negation: ማዛመድን + matching_strategy: ተዛማጅ ስትራቴጂ + new: አዲስ + search: ፍለጋ + confirm_delete: እርግጠኛ ነዎት ይህንን ውቅር / ቶች መሰረዝ ይፈልጋሉ? + confirm_delete_title: መሰረዝ ያረጋግጡ + bundled_title: የመተግበሪያ ውቅረት በጥይት የተደመሰሰ + bundled_msg: >- + እነዚህ የታሸጉ ውቅሮች አርት edity ት አይደሉም እናም ያለ ማበጀት ምርጥ ተሞክሮዎን ለማቅረብ የተቀየሱ ናቸው. በጣም + የተለመዱ ትግበራዎችን በራስ-ሰር ያዋቅሩታል. + delete: ሰርዝ + export: ወደ ውጭ ይላኩ + swap: መቀያየር + import: ማስመጣት +extras: + links: ኦፊሴላዊ አገናኞች + github: Github + discord: አለመግባባት + version: ስሪት + exit: ማቆም / መውጣት + relaunch: እንደገና መነገር +shortcuts: + labels: + send_to_workspace_2: ወደ የስራ ቦታ 2 ይላኩ 2 + reserve_left: የተቆራረጠ + increase_height: ቁመት ይጨምሩ + send_to_workspace_1: ወደ የስራ ቦታ 1 ይላኩ 1 + reserve_bottom: የተጠባበቅ ክፍል + switch_workspace_1: ወደ የሥራ ቦታ 1 ቀይር + switch_workspace_0: ወደ የሥራ ቦታ 0 ይቀይሩ + move_to_workspace_0: ወደ የሥራ ቦታ 0 ይሂዱ + send_to_workspace_5: ወደ የሥራ ቦታ 5 ይላኩ + switch_workspace_9: ወደ የሥራ ቦታ 9 ቀይር + switch_workspace_7: ወደ የሥራ ቦታ 7 ቀይር + decrease_height: ቁመት ቀንሷል + increase_width: ስፋት መጨመር + switch_workspace_6: ወደ የሥራ ቦታ 6 ይቀይሩ + move_to_workspace_3: ወደ የሥራ ቦታ 3 ይሂዱ + move_to_workspace_1: ወደ የሥራ ቦታ 1 ይሂዱ + focus_right: በትክክል ትኩረት ያድርጉ + focus_bottom: ወደ ታች ትኩረት + send_to_workspace_0: ወደ የስራ ቦታ 0 ይላኩ 0 + switch_workspace_8: ወደ የሥራ ቦታ 8 ቀይር + move_to_workspace_9: ወደ የሥራ ቦታ 9 ይሂዱ + move_to_workspace_4: ወደ የሥራ ቦታ 4 ይሂዱ + send_to_workspace_3: ወደ የስራ ቦታ 3 ይላኩ + reserve_stack: የተጠባባቂ ቁልል + move_to_workspace_5: ወደ የሥራ ቦታ 5 ይሂዱ + move_to_workspace_8: ወደ የሥራ ቦታ 8 ይሂዱ + move_to_workspace_7: ወደ የሥራ ቦታ 7 ይሂዱ + send_to_workspace_7: ወደ የሥራ ቦታ 7 ይላኩ 7 + focus_top: ትኩረት + focus_left: ትኩረት ቀርቷል + move_to_workspace_2: ወደ የሥራ ቦታ 2 ይሂዱ + switch_workspace_4: ወደ የሥራ ቦታ 4 ይቀይሩ + switch_workspace_3: ወደ የስራ ቦታ 3 ቀይር + send_to_workspace_9: ወደ የሥራ ቦታ 9 ይላኩ + send_to_workspace_6: ወደ የሥራ ቦታ 6 ይላኩ + switch_workspace_5: ወደ የሥራ ቦታ 5 ቀይር + reserve_top: የላይኛው ክፍል + focus_latest: የቅርብ ጊዜዎችን ያተኩሩ + reserve_float: የተጠባባቂ ተንሳፋፊ + send_to_workspace_4: ወደ የሥራ ቦታ 4 ይላኩ + switch_workspace_2: ወደ የሥራ ቦታ 2 ቀይር + move_to_workspace_6: ወደ የሥራ ቦታ 1 ይሂዱ + send_to_workspace_8: ወደ የሥራ ቦታ 8 ይላኩ 8 + restore_sizes: መጠኖች ወደነበሩበት ይመልሱ + reserve_right: መብት + decrease_width: ስፋት መቀነስ + enable: የተቀናጁ አቋራጮችን (AHK) + enable_tooltip: የእራስዎን አቋራጮዎች ​​የሚተገበሩትን የእራስዎን አቋራጮች የሚተገበሩ ከሆነ ያሰናክሉ +inProgress: በሂደት ላይ... +open: ክፈት +cancel: ይቅር +delete: ሰርዝ +quit: አቁም +loading: በመጫን ላይ ... +save: አስቀምጥ diff --git a/src/apps/settings/i18n/translations/ar.yml b/src/apps/settings/i18n/translations/ar.yml index ad12350a..258712b0 100644 --- a/src/apps/settings/i18n/translations/ar.yml +++ b/src/apps/settings/i18n/translations/ar.yml @@ -1,191 +1,191 @@ -loading: تحميل... -inProgress: في تَقَدم... -cancel: يلغي -save: يحفظ -quit: يترك -open: يفتح -delete: يمسح -sides: - left: غادر - right: يمين - top: قمة - bottom: قاع -header: - labels: - general: عام - seelen_bar: شريط الأدوات الهوى - seelen_wm: مدير النافذة - seelen_weg: قفص الاتهام / شريط المهام - monitors: الشاشات - specific_apps: تطبيقات محددة - shortcuts: الاختصارات - developer: مطور - info: معلومة -start: - title: مرحباً! - message: >- - مرحبًا بك في Seelen UI، بيئة سطح المكتب المثالية مع مدير النوافذ المدمج - لتحسين تجربة Windows 11 الخاصة بك! اكتشف عصرًا جديدًا من الكفاءة وتعدد - المهام من خلال الواجهة البديهية والميزات المتقدمة. - message_accent: قم بتحسين إنتاجيتك بأناقة! -general: - startup: تشغيل عند بدء التشغيل؟ - language: لغة - theme: - label: معلومات الموضوع - placeholder: اختر نمطا - author: مؤلف - description: وصف - add: إضافة موضوع - added: تمت إضافة الموضوع بالفعل - enabled: السمات الممكّنة - tags: العلامات - available: متاح - selected: المحدد - icon_pack: - label: حزم أيقونة - accent_color: لون لهجة -toolbar: - enable: تمكين شريط الأدوات الفاخر - placeholder: - select: هيكل شريط الأدوات - author: مؤلف - description: وصف - height: ارتفاع -wm: - enable: تمكين مدير النوافذ - disabled_windows10: مدير النوافذ غير متوفر لنظام التشغيل Windows 10. - layout: تَخطِيط - author: مؤلف - description: وصف - space_between_containers: الفضاء بين الحاويات - workspace_padding: حشو مساحات العمل - workspace_offset: إزاحة مساحات العمل (الهوامش) - resize_delta: تغيير حجم دلتا (%) - border: - enable: تمكين حدود النافذة - width: عرض الحدود - offset: إزاحة الحدود -weg: - label: قفص الاتهام / شريط المهام - enable: تمكين قفص الاتهام/شريط المهام - width: عرض - auto_hide: اخفاء تلقائي - dock_side: جانب الرصيف - padding: حشوة - margin: هامِش - gap: فجوة - items: - label: أغراض - size: حجم الصنف - zoom_size: الحجم المكبر (يستخدم للموضوعات) - gap: المسافة بين العناصر - visible_separators: فواصل مرئية -devtools: - enable: تمكين أدوات المطور - app_folders: مجلدات التطبيق - install_folder: مجلد التثبيت - data_folder: مجلد البيانات - settings_file: ملف الإعدادات - custom_config_file: تحميل ملف التكوين المخصص - load: حمولة -apps_configurations: - import: يستورد - export: يصدّر - delete: يمسح - swap: تبديل - new: جديد - bundled_title: تكوين التطبيق المجمعة مع Seelen - bundled_msg: >- - هذه التكوينات المجمعة غير قابلة للتحرير وهي مصممة لتوفر لك أفضل تجربة دون - تخصيص. يقومون تلقائيًا بتكوين التطبيقات الأكثر شيوعًا لك. - confirm_delete_title: تأكيد الحذف - confirm_delete: هل أنت متأكد أنك تريد حذف هذا التكوين/التكوينات؟ - search: يبحث - app: - name: اسم - category: فئة - category_placeholder: لا أحد - bindings: ملزم (لاحظ أن كلا الخيارين مطلوبان) - monitor: شاشة - monitor_placeholder: لا أحد - workspace: مساحة العمل - workspace_placeholder: لا أحد - title_edit: تعديل {{اسم}} - title_create: إنشاء {{اسم}} - title_readonly: عرض {{اسم}} - ok_edit: تحديث - ok_create: يخلق - ok_readonly: تحرير كجديد - options_label: خيارات إضافية - options: - float: يطفو - unmanage: غير إدارة - force: إدارة القوة - pinned: مثبت - identifier: - remove: حذف الحظر - id: المعرف - kind: تحديد بواسطة - matching_strategy: استراتيجية المطابقة - negation: نفي المطابقة - and: و - or: أو - add_block: أضف بلوك -extras: - version: إصدار - links: الروابط الرسمية - github: جيثب - discord: الفتنة - relaunch: إعادة التشغيل - exit: إنهاء/خروج -shortcuts: - enable: تمكين الاختصارات المتكاملة (ahk) - enable_tooltip: قم بالتعطيل إذا كنت ستنفذ الاختصارات الخاصة بك باستخدام Seelen Core Api - labels: - reserve_top: احتياطي الأعلى - reserve_bottom: احتياطي القاع - reserve_left: احتياطي اليسار - reserve_right: حق الاحتياط - reserve_float: تعويم الاحتياطي - reserve_stack: المكدس الاحتياطي - focus_top: التركيز الأعلى - focus_bottom: التركيز على القاع - focus_left: التركيز على اليسار - focus_right: التركيز الصحيح - focus_latest: التركيز على الأحدث - increase_width: زيادة العرض - decrease_width: تقليل العرض - increase_height: زيادة الارتفاع - decrease_height: تقليل الارتفاع - restore_sizes: استعادة الأحجام - switch_workspace_0: قم بالتبديل إلى مساحة العمل 0 - switch_workspace_1: قم بالتبديل إلى مساحة العمل 1 - switch_workspace_2: قم بالتبديل إلى مساحة العمل 2 - switch_workspace_3: قم بالتبديل إلى مساحة العمل 3 - switch_workspace_4: قم بالتبديل إلى مساحة العمل 4 - switch_workspace_5: قم بالتبديل إلى مساحة العمل 5 - switch_workspace_6: قم بالتبديل إلى مساحة العمل 6 - switch_workspace_7: قم بالتبديل إلى مساحة العمل 7 - switch_workspace_8: قم بالتبديل إلى مساحة العمل 8 - switch_workspace_9: قم بالتبديل إلى مساحة العمل 9 - move_to_workspace_0: انتقل إلى مساحة العمل 0 - move_to_workspace_1: انتقل إلى مساحة العمل 1 - move_to_workspace_2: انتقل إلى مساحة العمل 2 - move_to_workspace_3: انتقل إلى مساحة العمل 3 - move_to_workspace_4: انتقل إلى مساحة العمل 4 - move_to_workspace_5: انتقل إلى مساحة العمل 5 - move_to_workspace_6: انتقل إلى مساحة العمل 6 - move_to_workspace_7: انتقل إلى مساحة العمل 7 - move_to_workspace_8: انتقل إلى مساحة العمل 8 - move_to_workspace_9: انتقل إلى مساحة العمل 9 - send_to_workspace_0: أرسل إلى مساحة العمل 0 - send_to_workspace_1: أرسل إلى مساحة العمل 1 - send_to_workspace_2: أرسل إلى مساحة العمل 2 - send_to_workspace_3: أرسل إلى مساحة العمل 3 - send_to_workspace_4: أرسل إلى مساحة العمل 4 - send_to_workspace_5: أرسل إلى مساحة العمل 5 - send_to_workspace_6: أرسل إلى مساحة العمل 6 - send_to_workspace_7: أرسل إلى مساحة العمل 7 - send_to_workspace_8: أرسل إلى مساحة العمل 8 - send_to_workspace_9: أرسل إلى مساحة العمل 9 +loading: تحميل... +inProgress: في تَقَدم... +cancel: يلغي +save: يحفظ +quit: يترك +open: يفتح +delete: يمسح +sides: + left: غادر + right: يمين + top: قمة + bottom: قاع +header: + labels: + general: عام + seelen_bar: شريط الأدوات الهوى + seelen_wm: مدير النافذة + seelen_weg: قفص الاتهام / شريط المهام + monitors: الشاشات + specific_apps: تطبيقات محددة + shortcuts: الاختصارات + developer: مطور + info: معلومة +start: + title: مرحباً! + message: >- + مرحبًا بك في Seelen UI، بيئة سطح المكتب المثالية مع مدير النوافذ المدمج + لتحسين تجربة Windows 11 الخاصة بك! اكتشف عصرًا جديدًا من الكفاءة وتعدد + المهام من خلال الواجهة البديهية والميزات المتقدمة. + message_accent: قم بتحسين إنتاجيتك بأناقة! +general: + startup: تشغيل عند بدء التشغيل؟ + language: لغة + theme: + label: معلومات الموضوع + placeholder: اختر نمطا + author: مؤلف + description: وصف + add: إضافة موضوع + added: تمت إضافة الموضوع بالفعل + enabled: السمات الممكّنة + tags: العلامات + available: متاح + selected: المحدد + icon_pack: + label: حزم أيقونة + accent_color: لون لهجة +toolbar: + enable: تمكين شريط الأدوات الفاخر + placeholder: + select: هيكل شريط الأدوات + author: مؤلف + description: وصف + height: ارتفاع +wm: + enable: تمكين مدير النوافذ + disabled_windows10: مدير النوافذ غير متوفر لنظام التشغيل Windows 10. + layout: تَخطِيط + author: مؤلف + description: وصف + space_between_containers: الفضاء بين الحاويات + workspace_padding: حشو مساحات العمل + workspace_offset: إزاحة مساحات العمل (الهوامش) + resize_delta: تغيير حجم دلتا (%) + border: + enable: تمكين حدود النافذة + width: عرض الحدود + offset: إزاحة الحدود +weg: + label: قفص الاتهام / شريط المهام + enable: تمكين قفص الاتهام/شريط المهام + width: عرض + auto_hide: اخفاء تلقائي + dock_side: جانب الرصيف + padding: حشوة + margin: هامِش + gap: فجوة + items: + label: أغراض + size: حجم الصنف + zoom_size: الحجم المكبر (يستخدم للموضوعات) + gap: المسافة بين العناصر + visible_separators: فواصل مرئية +devtools: + enable: تمكين أدوات المطور + app_folders: مجلدات التطبيق + install_folder: مجلد التثبيت + data_folder: مجلد البيانات + settings_file: ملف الإعدادات + custom_config_file: تحميل ملف التكوين المخصص + load: حمولة +apps_configurations: + import: يستورد + export: يصدّر + delete: يمسح + swap: تبديل + new: جديد + bundled_title: تكوين التطبيق المجمعة مع Seelen + bundled_msg: >- + هذه التكوينات المجمعة غير قابلة للتحرير وهي مصممة لتوفر لك أفضل تجربة دون + تخصيص. يقومون تلقائيًا بتكوين التطبيقات الأكثر شيوعًا لك. + confirm_delete_title: تأكيد الحذف + confirm_delete: هل أنت متأكد أنك تريد حذف هذا التكوين/التكوينات؟ + search: يبحث + app: + name: اسم + category: فئة + category_placeholder: لا أحد + bindings: ملزم (لاحظ أن كلا الخيارين مطلوبان) + monitor: شاشة + monitor_placeholder: لا أحد + workspace: مساحة العمل + workspace_placeholder: لا أحد + title_edit: تعديل {{اسم}} + title_create: إنشاء {{اسم}} + title_readonly: عرض {{اسم}} + ok_edit: تحديث + ok_create: يخلق + ok_readonly: تحرير كجديد + options_label: خيارات إضافية + options: + float: يطفو + unmanage: غير إدارة + force: إدارة القوة + pinned: مثبت + identifier: + remove: حذف الحظر + id: المعرف + kind: تحديد بواسطة + matching_strategy: استراتيجية المطابقة + negation: نفي المطابقة + and: و + or: أو + add_block: أضف بلوك +extras: + version: إصدار + links: الروابط الرسمية + github: جيثب + discord: الفتنة + relaunch: إعادة التشغيل + exit: إنهاء/خروج +shortcuts: + enable: تمكين الاختصارات المتكاملة (ahk) + enable_tooltip: قم بالتعطيل إذا كنت ستنفذ الاختصارات الخاصة بك باستخدام Seelen Core Api + labels: + reserve_top: احتياطي الأعلى + reserve_bottom: احتياطي القاع + reserve_left: احتياطي اليسار + reserve_right: حق الاحتياط + reserve_float: تعويم الاحتياطي + reserve_stack: المكدس الاحتياطي + focus_top: التركيز الأعلى + focus_bottom: التركيز على القاع + focus_left: التركيز على اليسار + focus_right: التركيز الصحيح + focus_latest: التركيز على الأحدث + increase_width: زيادة العرض + decrease_width: تقليل العرض + increase_height: زيادة الارتفاع + decrease_height: تقليل الارتفاع + restore_sizes: استعادة الأحجام + switch_workspace_0: قم بالتبديل إلى مساحة العمل 0 + switch_workspace_1: قم بالتبديل إلى مساحة العمل 1 + switch_workspace_2: قم بالتبديل إلى مساحة العمل 2 + switch_workspace_3: قم بالتبديل إلى مساحة العمل 3 + switch_workspace_4: قم بالتبديل إلى مساحة العمل 4 + switch_workspace_5: قم بالتبديل إلى مساحة العمل 5 + switch_workspace_6: قم بالتبديل إلى مساحة العمل 6 + switch_workspace_7: قم بالتبديل إلى مساحة العمل 7 + switch_workspace_8: قم بالتبديل إلى مساحة العمل 8 + switch_workspace_9: قم بالتبديل إلى مساحة العمل 9 + move_to_workspace_0: انتقل إلى مساحة العمل 0 + move_to_workspace_1: انتقل إلى مساحة العمل 1 + move_to_workspace_2: انتقل إلى مساحة العمل 2 + move_to_workspace_3: انتقل إلى مساحة العمل 3 + move_to_workspace_4: انتقل إلى مساحة العمل 4 + move_to_workspace_5: انتقل إلى مساحة العمل 5 + move_to_workspace_6: انتقل إلى مساحة العمل 6 + move_to_workspace_7: انتقل إلى مساحة العمل 7 + move_to_workspace_8: انتقل إلى مساحة العمل 8 + move_to_workspace_9: انتقل إلى مساحة العمل 9 + send_to_workspace_0: أرسل إلى مساحة العمل 0 + send_to_workspace_1: أرسل إلى مساحة العمل 1 + send_to_workspace_2: أرسل إلى مساحة العمل 2 + send_to_workspace_3: أرسل إلى مساحة العمل 3 + send_to_workspace_4: أرسل إلى مساحة العمل 4 + send_to_workspace_5: أرسل إلى مساحة العمل 5 + send_to_workspace_6: أرسل إلى مساحة العمل 6 + send_to_workspace_7: أرسل إلى مساحة العمل 7 + send_to_workspace_8: أرسل إلى مساحة العمل 8 + send_to_workspace_9: أرسل إلى مساحة العمل 9 diff --git a/src/apps/settings/i18n/translations/az.yml b/src/apps/settings/i18n/translations/az.yml index 8e0cc22f..36b25355 100644 --- a/src/apps/settings/i18n/translations/az.yml +++ b/src/apps/settings/i18n/translations/az.yml @@ -1,195 +1,195 @@ -sides: - bottom: Dibli - right: Haqlı - left: Sol - top: Üst -header: - labels: - developer: İnkişaf etdirici - seelen_wm: Pəncərə meneceri - info: Məlumat - specific_apps: Xüsusi tətbiqlər - seelen_weg: Dock / tapşırıq çubuğu - monitors: Monitorlar - shortcuts: Qısaylıq - seelen_bar: Xülya alətlər paneli - general: General -start: - title: Xoş gəliş edin! - message_accent: Üslubla məhsuldarlığınızı optimallaşdırın! - message: >- - Windows 11 təcrübənizi artırmaq üçün birləşdirilmiş bir kirəmit windows - meneceri olan son masa üstü mühiti Seelen Ui-yə xoş gəlmisiniz! İntuitiv - interfeysimiz və inkişaf etmiş xüsusiyyətlərimizlə yeni bir səmərəlilik və - çoklu bir dövrü araşdırın. -general: - theme: - placeholder: Mövzunu seçin - enabled: Effektiv mövzular - add: Mövzu əlavə edin - added: Mövzu artıq əlavə edildi - description: Təsvir - author: Müəllif - label: Tema haqqında məlumat - tags: Tags - selected: Seçilmiş - available: Mövcud - language: Dil - startup: Başlanğıcda qaçırsınız? - icon_pack: - label: Icon paketləri - accent_color: Vurğu -toolbar: - placeholder: - author: Müəllif - description: Təsvir - select: Alətlər paneli quruluşu - height: Hündürlük - enable: Zərif alət çubuğunu aktivləşdirin -wm: - border: - width: Sərhəd eni - offset: Sərhəd əvəzinə - enable: Pəncərənin sərhədini aktivləşdirin - description: Təsvir - resize_delta: Delta'nın ölçüsünü (%) - layout: Sxem - enable: Pəncərə menecerini aktivləşdirin - space_between_containers: Konteynerlər arasındakı boşluq - author: Müəllif - workspace_offset: İş yerləri ofset (kənarları) - disabled_windows10: Pəncərə meneceri Windows 10 üçün mövcud deyil. - workspace_padding: İş sahələri padding -weg: - items: - zoom_size: Böyüdülmüş ölçü (mövzular üçün istifadə olunur) - visible_separators: Görünən ayırıcılar - label: Maddələr - gap: Əşyalar arasındakı boşluq - size: Maddə ölçüsü - dock_side: Dok tərəfi - margin: Kənarə - auto_hide: Avtomatik gizlətmək - padding: Paddend - width: Geniştəhər - gap: Gap - label: Dock / tapşırıq çubuğu - enable: Dock / tapşırıq çubuğunu aktivləşdirin -devtools: - app_folders: Tətbiq qovluqları - data_folder: Məlumat qovluğu - load: Yükləmək - custom_config_file: Xüsusi konfiqurasiya faylını yükləyin - settings_file: Parametrlər faylı - enable: Developer alətlərini aktivləşdirin - install_folder: Quraşdırma qovluğu -apps_configurations: - app: - options: - float: Sal - pinned: Sancaq - unmanage: Qüsursuz - force: İdarə etmək - monitor: Ekran - ok_readonly: Yeni kimi redaktə edin - workspace_placeholder: Heç kim - title_create: Yaratmaq {{ad}} - monitor_placeholder: Heç kim - bindings: Bağlama (hər iki variant tələb olunur) - category_placeholder: Heç kim - name: Ad - category: Kateqoriya - ok_edit: Aktuallaşdırmaq - title_readonly: Bax {{ad}} - ok_create: Yaratmaq - workspace: İş sahəsi - title_edit: '{{Ad}} redaktəsi' - options_label: Əlavə seçimlər - identifier: - add_block: Blok əlavə edin - negation: Uyğunlaşmanı rədd edin - kind: Tərəfindən müəyyənləşdirmək - or: Və ya - and: Və - remove: Bloku silmək - matching_strategy: Uyğun strategiya - id: Eyniləşdirici - confirm_delete_title: Silmək təsdiqləyin - bundled_title: App Config Seelen ilə birləşdirilmişdir - export: İxrac etmək - confirm_delete: Bu konfiqurasiya / s silmək istədiyinizə əminsiniz? - new: Yeni - delete: Silmək - search: Axtarış - bundled_msg: >- - Bu paketlənmiş konfiqurasiya düzəliş deyil və özelleştirme olmadan ən yaxşı - təcrübəni təmin etmək üçün hazırlanmışdır. Avtomatik olaraq sizin üçün ən - çox yayılmış tətbiqləri konfiqurasiya edirlər. - import: İdxal etmək - swap: Dəyişdirmək -extras: - version: Versiya - relaunch: Başsız - discord: Nifaq - github: Gitub - exit: Çıxmaq / çıxmaq - links: Rəsmi bağlantılar -shortcuts: - labels: - reserve_right: Ehtiyat ehtiyat - focus_left: Fokus sol - focus_right: Fokuslanmaq - move_to_workspace_5: İş sahəsinə 5-ə keçin - focus_latest: Ən son fokus - send_to_workspace_5: 5 iş sahəsinə göndərin - decrease_width: Enini azaltmaq - decrease_height: Hündürlük azalmaq - move_to_workspace_3: İş sahəsinə 3-ə keçin - reserve_bottom: Ehtiyat - switch_workspace_3: İş sahəsinə 3 keçin - send_to_workspace_1: İş sahəsinə göndərin 1 - increase_height: Boylanmaq - switch_workspace_5: İş sahəsinə 5-ə keçin - reserve_left: Qoruğu - switch_workspace_9: İş sahəsinə 9-a keçin - focus_top: Fokuslanmaq - switch_workspace_7: İş sahəsinə 7-ə keçin - restore_sizes: Ölçüləri bərpa etmək - move_to_workspace_4: İş sahəsinə 4-ə keçin - move_to_workspace_2: İş sahəsinə 2-ə keçin - move_to_workspace_8: 8 iş sahəsinə keçin 8 - move_to_workspace_6: İş sahəsinə 6 hərəkət edin - switch_workspace_8: İş sahəsinə 8-ə keçin - focus_bottom: Fokuslanmaq - send_to_workspace_9: İş sahəsinə göndərin 9 - move_to_workspace_1: İş sahəsinə 1-ə keçin - send_to_workspace_6: İş sahəsinə göndərin 6 - reserve_stack: Ehtiyat yığını - move_to_workspace_7: 7 iş sahəsinə keçin - switch_workspace_6: İş sahəsinə 6-a keçin - increase_width: Enini artırmaq - reserve_top: Bronlamaq - switch_workspace_4: İş sahəsinə 4-ə keçin - send_to_workspace_7: 7 iş sahəsinə göndərin - send_to_workspace_8: İş sahəsinə göndərin 8 - move_to_workspace_9: İş sahəsinə 9-a keçin - move_to_workspace_0: İş sahəsinə 0 hərəkət edin - send_to_workspace_4: İş sahəsinə 4 göndərin - switch_workspace_0: İş sahəsinə 0 keçin - switch_workspace_2: İş sahəsinə 2 keçin - switch_workspace_1: İş sahəsinə 1 keçin - send_to_workspace_2: İş sahəsinə 2 göndərin - send_to_workspace_0: 0 iş sahəsinə göndərin - send_to_workspace_3: İş sahəsinə göndərin 3 - reserve_float: Ehtiyat float - enable: İnteqrasiya edilmiş qısa yolları (AHK) aktivləşdirin - enable_tooltip: >- - Seelen Core API istifadə edərək öz qısa yollarınızı həyata keçirə bilsəniz - deaktiv edin -save: Yadda saxla -loading: Yükləmə ... -delete: Silmək -cancel: Ləğv etmək -quit: Çıxmaq -open: Açıq-saçıq -inProgress: Davam edir ... +sides: + bottom: Dibli + right: Haqlı + left: Sol + top: Üst +header: + labels: + developer: İnkişaf etdirici + seelen_wm: Pəncərə meneceri + info: Məlumat + specific_apps: Xüsusi tətbiqlər + seelen_weg: Dock / tapşırıq çubuğu + monitors: Monitorlar + shortcuts: Qısaylıq + seelen_bar: Xülya alətlər paneli + general: General +start: + title: Xoş gəliş edin! + message_accent: Üslubla məhsuldarlığınızı optimallaşdırın! + message: >- + Windows 11 təcrübənizi artırmaq üçün birləşdirilmiş bir kirəmit windows + meneceri olan son masa üstü mühiti Seelen Ui-yə xoş gəlmisiniz! İntuitiv + interfeysimiz və inkişaf etmiş xüsusiyyətlərimizlə yeni bir səmərəlilik və + çoklu bir dövrü araşdırın. +general: + theme: + placeholder: Mövzunu seçin + enabled: Effektiv mövzular + add: Mövzu əlavə edin + added: Mövzu artıq əlavə edildi + description: Təsvir + author: Müəllif + label: Tema haqqında məlumat + tags: Tags + selected: Seçilmiş + available: Mövcud + language: Dil + startup: Başlanğıcda qaçırsınız? + icon_pack: + label: Icon paketləri + accent_color: Vurğu +toolbar: + placeholder: + author: Müəllif + description: Təsvir + select: Alətlər paneli quruluşu + height: Hündürlük + enable: Zərif alət çubuğunu aktivləşdirin +wm: + border: + width: Sərhəd eni + offset: Sərhəd əvəzinə + enable: Pəncərənin sərhədini aktivləşdirin + description: Təsvir + resize_delta: Delta'nın ölçüsünü (%) + layout: Sxem + enable: Pəncərə menecerini aktivləşdirin + space_between_containers: Konteynerlər arasındakı boşluq + author: Müəllif + workspace_offset: İş yerləri ofset (kənarları) + disabled_windows10: Pəncərə meneceri Windows 10 üçün mövcud deyil. + workspace_padding: İş sahələri padding +weg: + items: + zoom_size: Böyüdülmüş ölçü (mövzular üçün istifadə olunur) + visible_separators: Görünən ayırıcılar + label: Maddələr + gap: Əşyalar arasındakı boşluq + size: Maddə ölçüsü + dock_side: Dok tərəfi + margin: Kənarə + auto_hide: Avtomatik gizlətmək + padding: Paddend + width: Geniştəhər + gap: Gap + label: Dock / tapşırıq çubuğu + enable: Dock / tapşırıq çubuğunu aktivləşdirin +devtools: + app_folders: Tətbiq qovluqları + data_folder: Məlumat qovluğu + load: Yükləmək + custom_config_file: Xüsusi konfiqurasiya faylını yükləyin + settings_file: Parametrlər faylı + enable: Developer alətlərini aktivləşdirin + install_folder: Quraşdırma qovluğu +apps_configurations: + app: + options: + float: Sal + pinned: Sancaq + unmanage: Qüsursuz + force: İdarə etmək + monitor: Ekran + ok_readonly: Yeni kimi redaktə edin + workspace_placeholder: Heç kim + title_create: Yaratmaq {{ad}} + monitor_placeholder: Heç kim + bindings: Bağlama (hər iki variant tələb olunur) + category_placeholder: Heç kim + name: Ad + category: Kateqoriya + ok_edit: Aktuallaşdırmaq + title_readonly: Bax {{ad}} + ok_create: Yaratmaq + workspace: İş sahəsi + title_edit: '{{Ad}} redaktəsi' + options_label: Əlavə seçimlər + identifier: + add_block: Blok əlavə edin + negation: Uyğunlaşmanı rədd edin + kind: Tərəfindən müəyyənləşdirmək + or: Və ya + and: Və + remove: Bloku silmək + matching_strategy: Uyğun strategiya + id: Eyniləşdirici + confirm_delete_title: Silmək təsdiqləyin + bundled_title: App Config Seelen ilə birləşdirilmişdir + export: İxrac etmək + confirm_delete: Bu konfiqurasiya / s silmək istədiyinizə əminsiniz? + new: Yeni + delete: Silmək + search: Axtarış + bundled_msg: >- + Bu paketlənmiş konfiqurasiya düzəliş deyil və özelleştirme olmadan ən yaxşı + təcrübəni təmin etmək üçün hazırlanmışdır. Avtomatik olaraq sizin üçün ən + çox yayılmış tətbiqləri konfiqurasiya edirlər. + import: İdxal etmək + swap: Dəyişdirmək +extras: + version: Versiya + relaunch: Başsız + discord: Nifaq + github: Gitub + exit: Çıxmaq / çıxmaq + links: Rəsmi bağlantılar +shortcuts: + labels: + reserve_right: Ehtiyat ehtiyat + focus_left: Fokus sol + focus_right: Fokuslanmaq + move_to_workspace_5: İş sahəsinə 5-ə keçin + focus_latest: Ən son fokus + send_to_workspace_5: 5 iş sahəsinə göndərin + decrease_width: Enini azaltmaq + decrease_height: Hündürlük azalmaq + move_to_workspace_3: İş sahəsinə 3-ə keçin + reserve_bottom: Ehtiyat + switch_workspace_3: İş sahəsinə 3 keçin + send_to_workspace_1: İş sahəsinə göndərin 1 + increase_height: Boylanmaq + switch_workspace_5: İş sahəsinə 5-ə keçin + reserve_left: Qoruğu + switch_workspace_9: İş sahəsinə 9-a keçin + focus_top: Fokuslanmaq + switch_workspace_7: İş sahəsinə 7-ə keçin + restore_sizes: Ölçüləri bərpa etmək + move_to_workspace_4: İş sahəsinə 4-ə keçin + move_to_workspace_2: İş sahəsinə 2-ə keçin + move_to_workspace_8: 8 iş sahəsinə keçin 8 + move_to_workspace_6: İş sahəsinə 6 hərəkət edin + switch_workspace_8: İş sahəsinə 8-ə keçin + focus_bottom: Fokuslanmaq + send_to_workspace_9: İş sahəsinə göndərin 9 + move_to_workspace_1: İş sahəsinə 1-ə keçin + send_to_workspace_6: İş sahəsinə göndərin 6 + reserve_stack: Ehtiyat yığını + move_to_workspace_7: 7 iş sahəsinə keçin + switch_workspace_6: İş sahəsinə 6-a keçin + increase_width: Enini artırmaq + reserve_top: Bronlamaq + switch_workspace_4: İş sahəsinə 4-ə keçin + send_to_workspace_7: 7 iş sahəsinə göndərin + send_to_workspace_8: İş sahəsinə göndərin 8 + move_to_workspace_9: İş sahəsinə 9-a keçin + move_to_workspace_0: İş sahəsinə 0 hərəkət edin + send_to_workspace_4: İş sahəsinə 4 göndərin + switch_workspace_0: İş sahəsinə 0 keçin + switch_workspace_2: İş sahəsinə 2 keçin + switch_workspace_1: İş sahəsinə 1 keçin + send_to_workspace_2: İş sahəsinə 2 göndərin + send_to_workspace_0: 0 iş sahəsinə göndərin + send_to_workspace_3: İş sahəsinə göndərin 3 + reserve_float: Ehtiyat float + enable: İnteqrasiya edilmiş qısa yolları (AHK) aktivləşdirin + enable_tooltip: >- + Seelen Core API istifadə edərək öz qısa yollarınızı həyata keçirə bilsəniz + deaktiv edin +save: Yadda saxla +loading: Yükləmə ... +delete: Silmək +cancel: Ləğv etmək +quit: Çıxmaq +open: Açıq-saçıq +inProgress: Davam edir ... diff --git a/src/apps/settings/i18n/translations/bg.yml b/src/apps/settings/i18n/translations/bg.yml index bd35dc95..0907acec 100644 --- a/src/apps/settings/i18n/translations/bg.yml +++ b/src/apps/settings/i18n/translations/bg.yml @@ -1,195 +1,195 @@ -sides: - top: Връх - left: Наляво - bottom: Отдолу - right: Точно -header: - labels: - seelen_wm: Мениджър на прозорци - developer: Разработчик - specific_apps: Конкретни приложения - info: Информация - monitors: Монитори - seelen_weg: Док/лента на задачите - general: Общ - seelen_bar: Фантастична лента с инструменти - shortcuts: Преки пътища -start: - title: Добре дошли! - message: >- - Добре дошли в Seelen UI, най -добрата среда на работния плот с включена - облицовка на Windows Manager, за да подобри вашето изживяване на Windows 11! - Разгледайте нова ера на ефективност и многозадачност с нашия интуитивен - интерфейс и разширени функции. - message_accent: Оптимизирайте производителността си със стил! -general: - theme: - add: Добавете тема - added: Темата вече е добавена - author: Автор - tags: Етикети - description: Описание - label: Информация за темата - enabled: Активирани теми - placeholder: Изберете тема - selected: Избран - available: На разположение - startup: Да се ​​стартирате при стартиране? - language: Език - icon_pack: - label: Икони пакети - accent_color: Цвят на акцент -toolbar: - placeholder: - description: Описание - select: Структура на лентата с инструменти - author: Автор - enable: Активирайте фантастичната лента с инструменти - height: Височина -wm: - border: - enable: Активирайте границата на Windows - offset: Гранично изместване - width: Гранична ширина - description: Описание - disabled_windows10: Мениджърът на прозореца не е достъпен за Windows 10. - resize_delta: Оразмерете делтата (%) - enable: Активирайте мениджъра на прозорци - workspace_padding: Работни пространства подплънки - space_between_containers: Пространство между контейнерите - layout: Оформление - author: Автор - workspace_offset: Изместване на работните пространства (маржове) -weg: - items: - zoom_size: Размерът на мащабиране (използван за теми) - gap: Пространство между артикулите - visible_separators: Видими разделители - label: Елементи - size: Размер на артикула - padding: Подплънки - enable: Активирайте док/лента на задачите - auto_hide: Автоматично скриване - margin: Марж - width: Ширина - label: Док/лента на задачите - gap: Пропаст - dock_side: Док -devtools: - app_folders: Папки на приложения - custom_config_file: Заредете персонализиран конфигурационен файл - load: Зареждане - data_folder: Папка с данни - install_folder: Инсталационна папка - enable: Активирайте инструментите за разработчици - settings_file: Файл за настройки -apps_configurations: - app: - options: - force: Управление на силата - float: Float - unmanage: Несъгласен - pinned: Прикован - title_edit: Редактиране {{name}} - title_create: Създаване {{name}} - workspace: Работно пространство - category: Категория - ok_readonly: Редактиране като ново - ok_edit: Актуализация - monitor_placeholder: Нито един - name: Име - workspace_placeholder: Нито един - bindings: Обвързване (Забележете, че и двете опции са необходими) - options_label: Допълнителни опции - title_readonly: Преглед {{name}} - monitor: Монитор - category_placeholder: Нито един - ok_create: Създаване - identifier: - add_block: Добавете блок - remove: Изтриване на блок - id: Идентификатор - negation: Отрицание за съвпадение - and: И - matching_strategy: Съответстваща стратегия - kind: Определете от - or: ИЛИ - new: Ново - confirm_delete_title: Потвърдете изтриването - bundled_title: App Config, вградено със Seelen - search: Търсене - confirm_delete: Сигурни ли сте, че искате да изтриете тази конфигурация/и? - export: Експорт - bundled_msg: >- - Тези пакетни конфигурации не са редактируеми и са предназначени да ви - осигурят най -доброто изживяване без персонализиране. Те автоматично - конфигурират най -често срещаните приложения за вас. - delete: Изтрий - swap: Размяна - import: Импортиране -extras: - relaunch: Рестартиране - links: Официални връзки - version: Версия - exit: QUIT/EXIT - discord: Раздор - github: Github -shortcuts: - labels: - reserve_float: Резервен поплавък - reserve_right: Резервирайте правилно - reserve_top: Резервен връх - focus_latest: Фокусирайте последното - focus_top: Фокус отгоре - focus_right: Фокусирайте се вдясно - reserve_bottom: Резервно дъно - focus_bottom: Фокусирайте дъното - reserve_stack: Резервен стек - reserve_left: Резервирайте вляво - focus_left: Фокусирайте вляво - increase_width: Увеличете ширината - send_to_workspace_0: Изпратете в работното пространство 0 - send_to_workspace_4: Изпратете в работното пространство 4 - send_to_workspace_1: Изпратете в работното пространство 1 - switch_workspace_1: Превключете в работното пространство 1 - move_to_workspace_6: Преместете се в работно пространство 6 - send_to_workspace_8: Изпратете в работното пространство 8 - send_to_workspace_6: Изпратете в Workspace 6 - switch_workspace_9: Превключете в работното пространство 9 - switch_workspace_4: Превключете в работното пространство 4 - switch_workspace_7: Превключете в работното пространство 7 - move_to_workspace_0: Преместете се в работно пространство 0 - decrease_width: Намалете ширината - switch_workspace_2: Превключете в работното пространство 2 - decrease_height: Намаляване на височината - switch_workspace_0: Превключете в работното пространство 0 - move_to_workspace_5: Преместете се в работното пространство 5 - move_to_workspace_2: Преместете се в работното пространство 2 - send_to_workspace_2: Изпратете в работното пространство 2 - move_to_workspace_4: Преместете се в работно пространство 4 - send_to_workspace_7: Изпратете в работното пространство 7 - move_to_workspace_1: Преместете се в работно пространство 1 - move_to_workspace_9: Преместете се в работно пространство 9 - switch_workspace_5: Превключете в работното пространство 5 - move_to_workspace_8: Преместете се в работно пространство 8 - move_to_workspace_7: Преместете се в работно пространство 7 - switch_workspace_3: Превключете в работното пространство 3 - send_to_workspace_3: Изпратете в Workspace 3 - switch_workspace_8: Превключете в работното пространство 8 - restore_sizes: Възстановяване на размерите - send_to_workspace_9: Изпратете в работно пространство 9 - switch_workspace_6: Превключете в работното пространство 6 - send_to_workspace_5: Изпратете в работното пространство 5 - increase_height: Увеличете височината - move_to_workspace_3: Преместете се в работното пространство 3 - enable_tooltip: >- - Деактивирайте, ако ще внедрите свои собствени преки пътища с помощта на API - на Core Seelen - enable: Активиране на интегрирани преки пътища (AHK) -loading: Зареждане... -quit: Напусна -delete: Изтрий -save: Запазете -inProgress: В ход ... -open: Отворен -cancel: Отказ +sides: + top: Връх + left: Наляво + bottom: Отдолу + right: Точно +header: + labels: + seelen_wm: Мениджър на прозорци + developer: Разработчик + specific_apps: Конкретни приложения + info: Информация + monitors: Монитори + seelen_weg: Док/лента на задачите + general: Общ + seelen_bar: Фантастична лента с инструменти + shortcuts: Преки пътища +start: + title: Добре дошли! + message: >- + Добре дошли в Seelen UI, най -добрата среда на работния плот с включена + облицовка на Windows Manager, за да подобри вашето изживяване на Windows 11! + Разгледайте нова ера на ефективност и многозадачност с нашия интуитивен + интерфейс и разширени функции. + message_accent: Оптимизирайте производителността си със стил! +general: + theme: + add: Добавете тема + added: Темата вече е добавена + author: Автор + tags: Етикети + description: Описание + label: Информация за темата + enabled: Активирани теми + placeholder: Изберете тема + selected: Избран + available: На разположение + startup: Да се ​​стартирате при стартиране? + language: Език + icon_pack: + label: Икони пакети + accent_color: Цвят на акцент +toolbar: + placeholder: + description: Описание + select: Структура на лентата с инструменти + author: Автор + enable: Активирайте фантастичната лента с инструменти + height: Височина +wm: + border: + enable: Активирайте границата на Windows + offset: Гранично изместване + width: Гранична ширина + description: Описание + disabled_windows10: Мениджърът на прозореца не е достъпен за Windows 10. + resize_delta: Оразмерете делтата (%) + enable: Активирайте мениджъра на прозорци + workspace_padding: Работни пространства подплънки + space_between_containers: Пространство между контейнерите + layout: Оформление + author: Автор + workspace_offset: Изместване на работните пространства (маржове) +weg: + items: + zoom_size: Размерът на мащабиране (използван за теми) + gap: Пространство между артикулите + visible_separators: Видими разделители + label: Елементи + size: Размер на артикула + padding: Подплънки + enable: Активирайте док/лента на задачите + auto_hide: Автоматично скриване + margin: Марж + width: Ширина + label: Док/лента на задачите + gap: Пропаст + dock_side: Док +devtools: + app_folders: Папки на приложения + custom_config_file: Заредете персонализиран конфигурационен файл + load: Зареждане + data_folder: Папка с данни + install_folder: Инсталационна папка + enable: Активирайте инструментите за разработчици + settings_file: Файл за настройки +apps_configurations: + app: + options: + force: Управление на силата + float: Float + unmanage: Несъгласен + pinned: Прикован + title_edit: Редактиране {{name}} + title_create: Създаване {{name}} + workspace: Работно пространство + category: Категория + ok_readonly: Редактиране като ново + ok_edit: Актуализация + monitor_placeholder: Нито един + name: Име + workspace_placeholder: Нито един + bindings: Обвързване (Забележете, че и двете опции са необходими) + options_label: Допълнителни опции + title_readonly: Преглед {{name}} + monitor: Монитор + category_placeholder: Нито един + ok_create: Създаване + identifier: + add_block: Добавете блок + remove: Изтриване на блок + id: Идентификатор + negation: Отрицание за съвпадение + and: И + matching_strategy: Съответстваща стратегия + kind: Определете от + or: ИЛИ + new: Ново + confirm_delete_title: Потвърдете изтриването + bundled_title: App Config, вградено със Seelen + search: Търсене + confirm_delete: Сигурни ли сте, че искате да изтриете тази конфигурация/и? + export: Експорт + bundled_msg: >- + Тези пакетни конфигурации не са редактируеми и са предназначени да ви + осигурят най -доброто изживяване без персонализиране. Те автоматично + конфигурират най -често срещаните приложения за вас. + delete: Изтрий + swap: Размяна + import: Импортиране +extras: + relaunch: Рестартиране + links: Официални връзки + version: Версия + exit: QUIT/EXIT + discord: Раздор + github: Github +shortcuts: + labels: + reserve_float: Резервен поплавък + reserve_right: Резервирайте правилно + reserve_top: Резервен връх + focus_latest: Фокусирайте последното + focus_top: Фокус отгоре + focus_right: Фокусирайте се вдясно + reserve_bottom: Резервно дъно + focus_bottom: Фокусирайте дъното + reserve_stack: Резервен стек + reserve_left: Резервирайте вляво + focus_left: Фокусирайте вляво + increase_width: Увеличете ширината + send_to_workspace_0: Изпратете в работното пространство 0 + send_to_workspace_4: Изпратете в работното пространство 4 + send_to_workspace_1: Изпратете в работното пространство 1 + switch_workspace_1: Превключете в работното пространство 1 + move_to_workspace_6: Преместете се в работно пространство 6 + send_to_workspace_8: Изпратете в работното пространство 8 + send_to_workspace_6: Изпратете в Workspace 6 + switch_workspace_9: Превключете в работното пространство 9 + switch_workspace_4: Превключете в работното пространство 4 + switch_workspace_7: Превключете в работното пространство 7 + move_to_workspace_0: Преместете се в работно пространство 0 + decrease_width: Намалете ширината + switch_workspace_2: Превключете в работното пространство 2 + decrease_height: Намаляване на височината + switch_workspace_0: Превключете в работното пространство 0 + move_to_workspace_5: Преместете се в работното пространство 5 + move_to_workspace_2: Преместете се в работното пространство 2 + send_to_workspace_2: Изпратете в работното пространство 2 + move_to_workspace_4: Преместете се в работно пространство 4 + send_to_workspace_7: Изпратете в работното пространство 7 + move_to_workspace_1: Преместете се в работно пространство 1 + move_to_workspace_9: Преместете се в работно пространство 9 + switch_workspace_5: Превключете в работното пространство 5 + move_to_workspace_8: Преместете се в работно пространство 8 + move_to_workspace_7: Преместете се в работно пространство 7 + switch_workspace_3: Превключете в работното пространство 3 + send_to_workspace_3: Изпратете в Workspace 3 + switch_workspace_8: Превключете в работното пространство 8 + restore_sizes: Възстановяване на размерите + send_to_workspace_9: Изпратете в работно пространство 9 + switch_workspace_6: Превключете в работното пространство 6 + send_to_workspace_5: Изпратете в работното пространство 5 + increase_height: Увеличете височината + move_to_workspace_3: Преместете се в работното пространство 3 + enable_tooltip: >- + Деактивирайте, ако ще внедрите свои собствени преки пътища с помощта на API + на Core Seelen + enable: Активиране на интегрирани преки пътища (AHK) +loading: Зареждане... +quit: Напусна +delete: Изтрий +save: Запазете +inProgress: В ход ... +open: Отворен +cancel: Отказ diff --git a/src/apps/settings/i18n/translations/bn.yml b/src/apps/settings/i18n/translations/bn.yml index e23dc54f..9e19b714 100644 --- a/src/apps/settings/i18n/translations/bn.yml +++ b/src/apps/settings/i18n/translations/bn.yml @@ -1,195 +1,195 @@ -sides: - bottom: নীচে - top: শীর্ষ - right: ঠিক আছে - left: বাম -header: - labels: - info: তথ্য - developer: বিকাশকারী - seelen_weg: ডক/টাস্কবার - general: সাধারণ - monitors: মনিটর - seelen_bar: অভিনব সরঞ্জামদণ্ড - shortcuts: শর্টকাটস - specific_apps: নির্দিষ্ট অ্যাপ্লিকেশন - seelen_wm: উইন্ডো ম্যানেজার -start: - title: স্বাগত! - message: >- - আপনার উইন্ডোজ 11 অভিজ্ঞতা বাড়ানোর জন্য একটি অন্তর্ভুক্ত টাইলিং উইন্ডোজ - ম্যানেজারের সাথে চূড়ান্ত ডেস্কটপ পরিবেশ সিলেন ইউআই -তে আপনাকে স্বাগতম! - আমাদের স্বজ্ঞাত ইন্টারফেস এবং উন্নত বৈশিষ্ট্যগুলির সাথে দক্ষতা এবং - মাল্টিটাস্কিংয়ের একটি নতুন যুগের সন্ধান করুন। - message_accent: স্টাইল দিয়ে আপনার উত্পাদনশীলতা অনুকূলিত করুন! -general: - theme: - description: বর্ণনা - placeholder: থিম নির্বাচন কর - tags: ট্যাগ - author: লেখক - enabled: সক্ষম থিম - label: থিম তথ্য - added: থিম ইতিমধ্যে যুক্ত - add: থিম যুক্ত করুন - selected: নির্বাচিত - available: উপলব্ধ - startup: প্রারম্ভকালে চালানো? - language: ভাষা - icon_pack: - label: আইকন প্যাকস - accent_color: সুরের ধাপের রঙ -toolbar: - placeholder: - author: লেখক - description: বর্ণনা - select: সরঞ্জামদণ্ড কাঠামো - enable: অভিনব সরঞ্জামদণ্ড সক্ষম করুন - height: উচ্চতা -wm: - border: - width: সীমানার প্রশস্থতা - enable: উইন্ডোর সীমানা সক্ষম করুন - offset: সীমান্ত অফসেট - author: লেখক - layout: বিন্যাস - description: বর্ণনা - resize_delta: পুনরায় আকার ডেল্টা (%) - workspace_offset: ওয়ার্কস্পেস অফসেট (মার্জিন) - disabled_windows10: উইন্ডো ম্যানেজার উইন্ডোজ 10 এর জন্য উপলভ্য নয়। - space_between_containers: পাত্রে স্থান - workspace_padding: ওয়ার্কস্পেস প্যাডিং - enable: উইন্ডো ম্যানেজার সক্ষম করুন -weg: - items: - size: আইটেমের আকার - gap: আইটেম মধ্যে স্থান - visible_separators: দৃশ্যমান বিভাজক - label: আইটেম - zoom_size: জুমযুক্ত আকার (থিমের জন্য ব্যবহৃত) - auto_hide: স্বয়ং চামড়া - dock_side: ডক সাইড - width: প্রস্থ - gap: ফাঁক - margin: মার্জিন - enable: ডক/টাস্কবার সক্ষম করুন - label: ডক/টাস্কবার - padding: প্যাডিং -devtools: - enable: বিকাশকারী সরঞ্জাম সক্ষম করুন - settings_file: সেটিংস ফাইল - install_folder: ইনস্টলেশন ফোল্ডার - custom_config_file: কাস্টম কনফিগার ফাইল লোড করুন - app_folders: অ্যাপ্লিকেশন ফোল্ডার - data_folder: ডেটা ফোল্ডার - load: বোঝা -apps_configurations: - app: - options: - float: ভাসা - unmanage: আনম্যানেজ - force: জোর পরিচালনা - pinned: পিনড - ok_create: সৃষ্টি - name: নাম - workspace_placeholder: কিছুই না - monitor_placeholder: কিছুই না - category_placeholder: কিছুই না - ok_edit: হালনাগাদ - title_readonly: '{{নাম}} দেখুন' - category: বিভাগ - ok_readonly: নতুন হিসাবে সম্পাদনা - monitor: মনিটর - title_edit: সম্পাদনা {{নাম}} - options_label: অতিরিক্ত বিকল্প - title_create: '{{নাম}} তৈরি করা' - workspace: কর্মক্ষেত্র - bindings: বাইন্ডিং (নোট উভয় বিকল্পের প্রয়োজন) - identifier: - or: বা - and: এবং - id: সনাক্তকারী - negation: ম্যাচিং অবহেলা - remove: ব্লক মুছুন - kind: দ্বারা চিহ্নিত করুন - add_block: ব্লক যুক্ত করুন - matching_strategy: ম্যাচিং কৌশল - import: আমদানি - search: অনুসন্ধান - new: নতুন - confirm_delete_title: নিশ্চিত বাতিল - export: রফতানি - delete: মুছে ফেলা - confirm_delete: আপনি কি নিশ্চিত যে আপনি এই কনফিগারেশন/গুলি মুছতে চান? - bundled_title: অ্যাপ কনফিগারেশন সিলেনের সাথে বান্ডিল - swap: অদলবদল - bundled_msg: >- - এই বান্ডিলযুক্ত কনফিগারেশনগুলি সম্পাদনাযোগ্য নয় এবং আপনাকে কাস্টমাইজেশন - ছাড়াই সেরা অভিজ্ঞতা সরবরাহ করার জন্য ডিজাইন করা হয়েছে। তারা - স্বয়ংক্রিয়ভাবে আপনার জন্য সর্বাধিক সাধারণ অ্যাপ্লিকেশনগুলি কনফিগার করে। -extras: - version: সংস্করণ - relaunch: পুনরায় চালু - exit: প্রস্থান/প্রস্থান - links: অফিসিয়াল লিঙ্ক - github: গিথুব - discord: মতবিরোধ -shortcuts: - labels: - focus_latest: সর্বশেষ ফোকাস - send_to_workspace_2: ওয়ার্কস্পেস 2 এ প্রেরণ করুন - reserve_left: রিজার্ভ বাম - switch_workspace_6: ওয়ার্কস্পেস 6 এ স্যুইচ করুন - reserve_stack: রিজার্ভ স্ট্যাক - decrease_height: উচ্চতা হ্রাস - send_to_workspace_8: ওয়ার্কস্পেস 8 এ প্রেরণ করুন - send_to_workspace_4: ওয়ার্কস্পেস 4 এ প্রেরণ করুন - increase_width: প্রস্থ বৃদ্ধি - switch_workspace_9: ওয়ার্কস্পেস 9 এ স্যুইচ করুন - switch_workspace_8: ওয়ার্কস্পেস 8 এ স্যুইচ করুন - send_to_workspace_5: ওয়ার্কস্পেস 5 এ প্রেরণ করুন - move_to_workspace_5: ওয়ার্কস্পেস 5 এ যান - send_to_workspace_0: ওয়ার্কস্পেস 0 এ প্রেরণ করুন - move_to_workspace_3: ওয়ার্কস্পেস 3 এ যান - switch_workspace_5: ওয়ার্কস্পেস 5 এ স্যুইচ করুন - focus_top: ফোকাস শীর্ষ - focus_right: ডান ফোকাস - send_to_workspace_9: ওয়ার্কস্পেস 9 এ প্রেরণ করুন - switch_workspace_3: ওয়ার্কস্পেস 3 এ স্যুইচ করুন - switch_workspace_4: ওয়ার্কস্পেস 4 এ স্যুইচ করুন - move_to_workspace_6: ওয়ার্কস্পেস 6 এ যান - increase_height: উচ্চতা বৃদ্ধি - reserve_bottom: রিজার্ভ নীচে - send_to_workspace_1: ওয়ার্কস্পেস 1 এ প্রেরণ করুন - switch_workspace_2: ওয়ার্কস্পেস 2 এ স্যুইচ করুন - send_to_workspace_6: ওয়ার্কস্পেস 6 এ প্রেরণ করুন - move_to_workspace_9: ওয়ার্কস্পেস 9 এ যান - reserve_float: রিজার্ভ ফ্লোট - send_to_workspace_3: ওয়ার্কস্পেস 3 এ প্রেরণ করুন - switch_workspace_1: ওয়ার্কস্পেস 1 এ স্যুইচ করুন - switch_workspace_7: ওয়ার্কস্পেস 7 এ স্যুইচ করুন - focus_bottom: ফোকাস নীচে - move_to_workspace_1: ওয়ার্কস্পেস 1 এ যান - switch_workspace_0: ওয়ার্কস্পেস 0 এ স্যুইচ করুন - move_to_workspace_0: ওয়ার্কস্পেস 0 এ যান - decrease_width: প্রস্থ হ্রাস - restore_sizes: আকার পুনরুদ্ধার - send_to_workspace_7: ওয়ার্কস্পেস 7 এ প্রেরণ করুন - move_to_workspace_4: ওয়ার্কস্পেস 4 এ যান - move_to_workspace_7: ওয়ার্কস্পেস 7 এ যান - reserve_right: রিজার্ভ রিজার - move_to_workspace_2: ওয়ার্কস্পেস 2 এ যান - focus_left: ফোকাস বাম - move_to_workspace_8: ওয়ার্কস্পেস 8 এ যান - reserve_top: রিজার্ভ শীর্ষ - enable_tooltip: >- - আপনি যদি সিলেন কোর এপিআই ব্যবহার করে নিজের শর্টকাটগুলি প্রয়োগ করেন তবে - অক্ষম করুন - enable: ইন্টিগ্রেটেড শর্টকাটগুলি সক্ষম করুন (এএইচকে) -inProgress: চলমান... -cancel: বাতিল -delete: মুছে ফেলা -save: সংরক্ষণ -open: খোলা -quit: প্রস্থান -loading: লোড হচ্ছে ... +sides: + bottom: নীচে + top: শীর্ষ + right: ঠিক আছে + left: বাম +header: + labels: + info: তথ্য + developer: বিকাশকারী + seelen_weg: ডক/টাস্কবার + general: সাধারণ + monitors: মনিটর + seelen_bar: অভিনব সরঞ্জামদণ্ড + shortcuts: শর্টকাটস + specific_apps: নির্দিষ্ট অ্যাপ্লিকেশন + seelen_wm: উইন্ডো ম্যানেজার +start: + title: স্বাগত! + message: >- + আপনার উইন্ডোজ 11 অভিজ্ঞতা বাড়ানোর জন্য একটি অন্তর্ভুক্ত টাইলিং উইন্ডোজ + ম্যানেজারের সাথে চূড়ান্ত ডেস্কটপ পরিবেশ সিলেন ইউআই -তে আপনাকে স্বাগতম! + আমাদের স্বজ্ঞাত ইন্টারফেস এবং উন্নত বৈশিষ্ট্যগুলির সাথে দক্ষতা এবং + মাল্টিটাস্কিংয়ের একটি নতুন যুগের সন্ধান করুন। + message_accent: স্টাইল দিয়ে আপনার উত্পাদনশীলতা অনুকূলিত করুন! +general: + theme: + description: বর্ণনা + placeholder: থিম নির্বাচন কর + tags: ট্যাগ + author: লেখক + enabled: সক্ষম থিম + label: থিম তথ্য + added: থিম ইতিমধ্যে যুক্ত + add: থিম যুক্ত করুন + selected: নির্বাচিত + available: উপলব্ধ + startup: প্রারম্ভকালে চালানো? + language: ভাষা + icon_pack: + label: আইকন প্যাকস + accent_color: সুরের ধাপের রঙ +toolbar: + placeholder: + author: লেখক + description: বর্ণনা + select: সরঞ্জামদণ্ড কাঠামো + enable: অভিনব সরঞ্জামদণ্ড সক্ষম করুন + height: উচ্চতা +wm: + border: + width: সীমানার প্রশস্থতা + enable: উইন্ডোর সীমানা সক্ষম করুন + offset: সীমান্ত অফসেট + author: লেখক + layout: বিন্যাস + description: বর্ণনা + resize_delta: পুনরায় আকার ডেল্টা (%) + workspace_offset: ওয়ার্কস্পেস অফসেট (মার্জিন) + disabled_windows10: উইন্ডো ম্যানেজার উইন্ডোজ 10 এর জন্য উপলভ্য নয়। + space_between_containers: পাত্রে স্থান + workspace_padding: ওয়ার্কস্পেস প্যাডিং + enable: উইন্ডো ম্যানেজার সক্ষম করুন +weg: + items: + size: আইটেমের আকার + gap: আইটেম মধ্যে স্থান + visible_separators: দৃশ্যমান বিভাজক + label: আইটেম + zoom_size: জুমযুক্ত আকার (থিমের জন্য ব্যবহৃত) + auto_hide: স্বয়ং চামড়া + dock_side: ডক সাইড + width: প্রস্থ + gap: ফাঁক + margin: মার্জিন + enable: ডক/টাস্কবার সক্ষম করুন + label: ডক/টাস্কবার + padding: প্যাডিং +devtools: + enable: বিকাশকারী সরঞ্জাম সক্ষম করুন + settings_file: সেটিংস ফাইল + install_folder: ইনস্টলেশন ফোল্ডার + custom_config_file: কাস্টম কনফিগার ফাইল লোড করুন + app_folders: অ্যাপ্লিকেশন ফোল্ডার + data_folder: ডেটা ফোল্ডার + load: বোঝা +apps_configurations: + app: + options: + float: ভাসা + unmanage: আনম্যানেজ + force: জোর পরিচালনা + pinned: পিনড + ok_create: সৃষ্টি + name: নাম + workspace_placeholder: কিছুই না + monitor_placeholder: কিছুই না + category_placeholder: কিছুই না + ok_edit: হালনাগাদ + title_readonly: '{{নাম}} দেখুন' + category: বিভাগ + ok_readonly: নতুন হিসাবে সম্পাদনা + monitor: মনিটর + title_edit: সম্পাদনা {{নাম}} + options_label: অতিরিক্ত বিকল্প + title_create: '{{নাম}} তৈরি করা' + workspace: কর্মক্ষেত্র + bindings: বাইন্ডিং (নোট উভয় বিকল্পের প্রয়োজন) + identifier: + or: বা + and: এবং + id: সনাক্তকারী + negation: ম্যাচিং অবহেলা + remove: ব্লক মুছুন + kind: দ্বারা চিহ্নিত করুন + add_block: ব্লক যুক্ত করুন + matching_strategy: ম্যাচিং কৌশল + import: আমদানি + search: অনুসন্ধান + new: নতুন + confirm_delete_title: নিশ্চিত বাতিল + export: রফতানি + delete: মুছে ফেলা + confirm_delete: আপনি কি নিশ্চিত যে আপনি এই কনফিগারেশন/গুলি মুছতে চান? + bundled_title: অ্যাপ কনফিগারেশন সিলেনের সাথে বান্ডিল + swap: অদলবদল + bundled_msg: >- + এই বান্ডিলযুক্ত কনফিগারেশনগুলি সম্পাদনাযোগ্য নয় এবং আপনাকে কাস্টমাইজেশন + ছাড়াই সেরা অভিজ্ঞতা সরবরাহ করার জন্য ডিজাইন করা হয়েছে। তারা + স্বয়ংক্রিয়ভাবে আপনার জন্য সর্বাধিক সাধারণ অ্যাপ্লিকেশনগুলি কনফিগার করে। +extras: + version: সংস্করণ + relaunch: পুনরায় চালু + exit: প্রস্থান/প্রস্থান + links: অফিসিয়াল লিঙ্ক + github: গিথুব + discord: মতবিরোধ +shortcuts: + labels: + focus_latest: সর্বশেষ ফোকাস + send_to_workspace_2: ওয়ার্কস্পেস 2 এ প্রেরণ করুন + reserve_left: রিজার্ভ বাম + switch_workspace_6: ওয়ার্কস্পেস 6 এ স্যুইচ করুন + reserve_stack: রিজার্ভ স্ট্যাক + decrease_height: উচ্চতা হ্রাস + send_to_workspace_8: ওয়ার্কস্পেস 8 এ প্রেরণ করুন + send_to_workspace_4: ওয়ার্কস্পেস 4 এ প্রেরণ করুন + increase_width: প্রস্থ বৃদ্ধি + switch_workspace_9: ওয়ার্কস্পেস 9 এ স্যুইচ করুন + switch_workspace_8: ওয়ার্কস্পেস 8 এ স্যুইচ করুন + send_to_workspace_5: ওয়ার্কস্পেস 5 এ প্রেরণ করুন + move_to_workspace_5: ওয়ার্কস্পেস 5 এ যান + send_to_workspace_0: ওয়ার্কস্পেস 0 এ প্রেরণ করুন + move_to_workspace_3: ওয়ার্কস্পেস 3 এ যান + switch_workspace_5: ওয়ার্কস্পেস 5 এ স্যুইচ করুন + focus_top: ফোকাস শীর্ষ + focus_right: ডান ফোকাস + send_to_workspace_9: ওয়ার্কস্পেস 9 এ প্রেরণ করুন + switch_workspace_3: ওয়ার্কস্পেস 3 এ স্যুইচ করুন + switch_workspace_4: ওয়ার্কস্পেস 4 এ স্যুইচ করুন + move_to_workspace_6: ওয়ার্কস্পেস 6 এ যান + increase_height: উচ্চতা বৃদ্ধি + reserve_bottom: রিজার্ভ নীচে + send_to_workspace_1: ওয়ার্কস্পেস 1 এ প্রেরণ করুন + switch_workspace_2: ওয়ার্কস্পেস 2 এ স্যুইচ করুন + send_to_workspace_6: ওয়ার্কস্পেস 6 এ প্রেরণ করুন + move_to_workspace_9: ওয়ার্কস্পেস 9 এ যান + reserve_float: রিজার্ভ ফ্লোট + send_to_workspace_3: ওয়ার্কস্পেস 3 এ প্রেরণ করুন + switch_workspace_1: ওয়ার্কস্পেস 1 এ স্যুইচ করুন + switch_workspace_7: ওয়ার্কস্পেস 7 এ স্যুইচ করুন + focus_bottom: ফোকাস নীচে + move_to_workspace_1: ওয়ার্কস্পেস 1 এ যান + switch_workspace_0: ওয়ার্কস্পেস 0 এ স্যুইচ করুন + move_to_workspace_0: ওয়ার্কস্পেস 0 এ যান + decrease_width: প্রস্থ হ্রাস + restore_sizes: আকার পুনরুদ্ধার + send_to_workspace_7: ওয়ার্কস্পেস 7 এ প্রেরণ করুন + move_to_workspace_4: ওয়ার্কস্পেস 4 এ যান + move_to_workspace_7: ওয়ার্কস্পেস 7 এ যান + reserve_right: রিজার্ভ রিজার + move_to_workspace_2: ওয়ার্কস্পেস 2 এ যান + focus_left: ফোকাস বাম + move_to_workspace_8: ওয়ার্কস্পেস 8 এ যান + reserve_top: রিজার্ভ শীর্ষ + enable_tooltip: >- + আপনি যদি সিলেন কোর এপিআই ব্যবহার করে নিজের শর্টকাটগুলি প্রয়োগ করেন তবে + অক্ষম করুন + enable: ইন্টিগ্রেটেড শর্টকাটগুলি সক্ষম করুন (এএইচকে) +inProgress: চলমান... +cancel: বাতিল +delete: মুছে ফেলা +save: সংরক্ষণ +open: খোলা +quit: প্রস্থান +loading: লোড হচ্ছে ... diff --git a/src/apps/settings/i18n/translations/bs.yml b/src/apps/settings/i18n/translations/bs.yml index cf7d84eb..2cb45c1d 100644 --- a/src/apps/settings/i18n/translations/bs.yml +++ b/src/apps/settings/i18n/translations/bs.yml @@ -1,195 +1,195 @@ -sides: - bottom: Dno - left: Lijevo - right: Pravo - top: Vrh -header: - labels: - seelen_weg: Dock / programska traka - developer: Programer - monitors: Monitori - specific_apps: Specifične aplikacije - general: Opći - seelen_bar: Fancy alatna traka - seelen_wm: Upravitelj prozora - info: Informacije - shortcuts: Prečice -start: - title: Dobrodošli! - message_accent: Optimizirajte svoju produktivnost sa stilom! - message: >- - Dobrodošli u Seelen UI, vrhunsko okruženje za radnu površinu sa ugrađenim - popločavanjem Windows Manager-a za poboljšanje vašeg Windows 11 iskustva! - Istražite novu eru efikasnosti i više zadataka sa našim intuitivnim - interfejsom i naprednim funkcijama. -general: - theme: - label: Informacije o temu - author: Autor - description: Opis - added: Tema je već dodana - add: Dodajte temu - tags: Oznake - placeholder: Odaberite temu - enabled: Omogućene teme - selected: Odabrano - available: Na raspolaganju - language: Jezik - startup: Trčite na pokretanju? - icon_pack: - label: Paketa ikona - accent_color: Akcentna boja -toolbar: - placeholder: - select: Struktura alatne trake - author: Autor - description: Opis - height: Visina - enable: Omogući fantastičnu alatnu traku -wm: - border: - width: Širina granice - enable: Omogući granicu prozora - offset: Offset granice - description: Opis - author: Autor - enable: Omogućite menadžeru prozora - layout: Izgled - workspace_offset: Offset radne prostore (margine) - disabled_windows10: Upravitelj prozora nije dostupan za Windows 10. - resize_delta: Promijenite veličinu Delta (%) - space_between_containers: Prostor između kontejnera - workspace_padding: Djelatna površina obloga -weg: - items: - gap: Prostor između predmeta - zoom_size: Povećana veličina (koristi se za teme) - size: Veličina predmeta - visible_separators: Vidljivi separatori - label: Predmeti - width: Širina - auto_hide: Auto se sakrio - gap: Jaz - dock_side: Priključak - margin: Marža - label: Dock / programska traka - padding: Obloga - enable: Omogući pristanište / traku zadataka -devtools: - app_folders: App Mape - settings_file: Datoteka postavki - enable: Omogućite alate za programere - data_folder: Mapa podataka - install_folder: Instalacijska mapa - custom_config_file: Učitajte prilagođenu datoteku config config - load: Opteretiti -apps_configurations: - app: - options: - pinned: Prikvačen - float: Lebdjeti - force: Sile upravljati - unmanage: Nevenjački - bindings: Vezanje (napominje su obavezne opcije) - monitor: Monitor - category_placeholder: Nijedan - name: Ime - workspace_placeholder: Nijedan - title_readonly: Gledanje {{ime}} - monitor_placeholder: Nijedan - options_label: Dodatne opcije - category: Kategorija - ok_create: Stvoriti - ok_readonly: Uredi kao novo - ok_edit: Ažurirati - workspace: Radni prostor - title_create: Stvarajući {{ime}} - title_edit: Uređivanje {{ime}} - identifier: - matching_strategy: Strategija podudaranja - and: I - or: Ili - id: Identifikator - negation: Negirati podudaranje - add_block: Dodajte blok - remove: Obriši blok - kind: Identificirati - new: Novo - confirm_delete: Jeste li sigurni da želite izbrisati ovu konfiguraciju / s? - import: Uvoz - bundled_title: Konfiguracija aplikacija paketa sa seelen - search: Pretražiti - export: Izvoz - confirm_delete_title: Potvrdite Izbriši - bundled_msg: >- - Ove uleteljene konfiguracije nisu uređivanje i dizajnirane su da vam pruže - najbolje iskustvo bez prilagodbe. Oni automatski konfiguriraju najčešće - aplikacije za vas. - delete: Izbrisati - swap: Swap -extras: - exit: Prestanite / izlaz - links: Službene veze - relaunch: Ponovno pokretanje - discord: Nesklad - github: Github - version: Verzija -shortcuts: - labels: - reserve_right: Rezervirajte pravo - switch_workspace_3: Prebacite se na radni prostor 3 - increase_height: Povećati visinu - restore_sizes: Vrati veličine - move_to_workspace_2: Premjestiti na radni prostor 2 - switch_workspace_2: Prebacite se na radni prostor 2 - move_to_workspace_5: Premjestiti na radni prostor 5 - move_to_workspace_0: Premjestiti na radni prostor 0 - focus_right: Fokusirajte se - switch_workspace_6: Prebacite se na radni prostor 6 - decrease_height: Smanjenje visine - focus_latest: Fokus najnovije - switch_workspace_0: Prebacite se na radni prostor 0 - reserve_left: Rezerva - reserve_bottom: Rezervno dno - move_to_workspace_3: Premjestiti na radni prostor 3 - switch_workspace_9: Prebacite se na radni prostor 9 - move_to_workspace_1: Premjestiti na radni prostor 1 - move_to_workspace_4: Premjestiti na radni prostor 4 - switch_workspace_5: Prebacite se na radni prostor 5 - reserve_stack: Rezervat - send_to_workspace_9: Pošalji u radni prostor 9 - reserve_top: Rezervat - focus_top: Focus Top - increase_width: Povećati širinu - focus_bottom: Fokus dno - switch_workspace_8: Prebacite se na radni prostor 8 - decrease_width: Smanjenje širine - focus_left: Fokus ostavljen - send_to_workspace_0: Pošaljite na Workspace 0 - switch_workspace_7: Prebacite se na radni prostor 7 - send_to_workspace_5: Pošalji u radni prostor 5 - switch_workspace_4: Prebacite se na radni prostor 4 - move_to_workspace_7: Premjestiti na radni prostor 7 - send_to_workspace_8: Pošalji u radni prostor 8 - move_to_workspace_9: Premjestiti na radni prostor 9 - reserve_float: Rezervni plutajući - send_to_workspace_6: Pošalji u radni prostor 6 - send_to_workspace_4: Pošaljite na Workspace 4 - move_to_workspace_6: Premjestiti na radni prostor 6 - send_to_workspace_3: Pošalji u radni prostor 3 - send_to_workspace_1: Pošaljite u radni prostor 1 - send_to_workspace_2: Pošalji u radni prostor 2 - switch_workspace_1: Prebacite se na radni prostor 1 - send_to_workspace_7: Pošalji u radni prostor 7 - move_to_workspace_8: Premjestiti na radni prostor 8 - enable: Omogući integrirane prečice (AHK) - enable_tooltip: >- - Onemogućite ako ćete implementirati vlastite prečice koristeći Seelen Core - API -loading: Učitavanje... -inProgress: U toku... -cancel: Otkazati -delete: Izbrisati -save: Sačuvati -quit: Prestati -open: Otvoren +sides: + bottom: Dno + left: Lijevo + right: Pravo + top: Vrh +header: + labels: + seelen_weg: Dock / programska traka + developer: Programer + monitors: Monitori + specific_apps: Specifične aplikacije + general: Opći + seelen_bar: Fancy alatna traka + seelen_wm: Upravitelj prozora + info: Informacije + shortcuts: Prečice +start: + title: Dobrodošli! + message_accent: Optimizirajte svoju produktivnost sa stilom! + message: >- + Dobrodošli u Seelen UI, vrhunsko okruženje za radnu površinu sa ugrađenim + popločavanjem Windows Manager-a za poboljšanje vašeg Windows 11 iskustva! + Istražite novu eru efikasnosti i više zadataka sa našim intuitivnim + interfejsom i naprednim funkcijama. +general: + theme: + label: Informacije o temu + author: Autor + description: Opis + added: Tema je već dodana + add: Dodajte temu + tags: Oznake + placeholder: Odaberite temu + enabled: Omogućene teme + selected: Odabrano + available: Na raspolaganju + language: Jezik + startup: Trčite na pokretanju? + icon_pack: + label: Paketa ikona + accent_color: Akcentna boja +toolbar: + placeholder: + select: Struktura alatne trake + author: Autor + description: Opis + height: Visina + enable: Omogući fantastičnu alatnu traku +wm: + border: + width: Širina granice + enable: Omogući granicu prozora + offset: Offset granice + description: Opis + author: Autor + enable: Omogućite menadžeru prozora + layout: Izgled + workspace_offset: Offset radne prostore (margine) + disabled_windows10: Upravitelj prozora nije dostupan za Windows 10. + resize_delta: Promijenite veličinu Delta (%) + space_between_containers: Prostor između kontejnera + workspace_padding: Djelatna površina obloga +weg: + items: + gap: Prostor između predmeta + zoom_size: Povećana veličina (koristi se za teme) + size: Veličina predmeta + visible_separators: Vidljivi separatori + label: Predmeti + width: Širina + auto_hide: Auto se sakrio + gap: Jaz + dock_side: Priključak + margin: Marža + label: Dock / programska traka + padding: Obloga + enable: Omogući pristanište / traku zadataka +devtools: + app_folders: App Mape + settings_file: Datoteka postavki + enable: Omogućite alate za programere + data_folder: Mapa podataka + install_folder: Instalacijska mapa + custom_config_file: Učitajte prilagođenu datoteku config config + load: Opteretiti +apps_configurations: + app: + options: + pinned: Prikvačen + float: Lebdjeti + force: Sile upravljati + unmanage: Nevenjački + bindings: Vezanje (napominje su obavezne opcije) + monitor: Monitor + category_placeholder: Nijedan + name: Ime + workspace_placeholder: Nijedan + title_readonly: Gledanje {{ime}} + monitor_placeholder: Nijedan + options_label: Dodatne opcije + category: Kategorija + ok_create: Stvoriti + ok_readonly: Uredi kao novo + ok_edit: Ažurirati + workspace: Radni prostor + title_create: Stvarajući {{ime}} + title_edit: Uređivanje {{ime}} + identifier: + matching_strategy: Strategija podudaranja + and: I + or: Ili + id: Identifikator + negation: Negirati podudaranje + add_block: Dodajte blok + remove: Obriši blok + kind: Identificirati + new: Novo + confirm_delete: Jeste li sigurni da želite izbrisati ovu konfiguraciju / s? + import: Uvoz + bundled_title: Konfiguracija aplikacija paketa sa seelen + search: Pretražiti + export: Izvoz + confirm_delete_title: Potvrdite Izbriši + bundled_msg: >- + Ove uleteljene konfiguracije nisu uređivanje i dizajnirane su da vam pruže + najbolje iskustvo bez prilagodbe. Oni automatski konfiguriraju najčešće + aplikacije za vas. + delete: Izbrisati + swap: Swap +extras: + exit: Prestanite / izlaz + links: Službene veze + relaunch: Ponovno pokretanje + discord: Nesklad + github: Github + version: Verzija +shortcuts: + labels: + reserve_right: Rezervirajte pravo + switch_workspace_3: Prebacite se na radni prostor 3 + increase_height: Povećati visinu + restore_sizes: Vrati veličine + move_to_workspace_2: Premjestiti na radni prostor 2 + switch_workspace_2: Prebacite se na radni prostor 2 + move_to_workspace_5: Premjestiti na radni prostor 5 + move_to_workspace_0: Premjestiti na radni prostor 0 + focus_right: Fokusirajte se + switch_workspace_6: Prebacite se na radni prostor 6 + decrease_height: Smanjenje visine + focus_latest: Fokus najnovije + switch_workspace_0: Prebacite se na radni prostor 0 + reserve_left: Rezerva + reserve_bottom: Rezervno dno + move_to_workspace_3: Premjestiti na radni prostor 3 + switch_workspace_9: Prebacite se na radni prostor 9 + move_to_workspace_1: Premjestiti na radni prostor 1 + move_to_workspace_4: Premjestiti na radni prostor 4 + switch_workspace_5: Prebacite se na radni prostor 5 + reserve_stack: Rezervat + send_to_workspace_9: Pošalji u radni prostor 9 + reserve_top: Rezervat + focus_top: Focus Top + increase_width: Povećati širinu + focus_bottom: Fokus dno + switch_workspace_8: Prebacite se na radni prostor 8 + decrease_width: Smanjenje širine + focus_left: Fokus ostavljen + send_to_workspace_0: Pošaljite na Workspace 0 + switch_workspace_7: Prebacite se na radni prostor 7 + send_to_workspace_5: Pošalji u radni prostor 5 + switch_workspace_4: Prebacite se na radni prostor 4 + move_to_workspace_7: Premjestiti na radni prostor 7 + send_to_workspace_8: Pošalji u radni prostor 8 + move_to_workspace_9: Premjestiti na radni prostor 9 + reserve_float: Rezervni plutajući + send_to_workspace_6: Pošalji u radni prostor 6 + send_to_workspace_4: Pošaljite na Workspace 4 + move_to_workspace_6: Premjestiti na radni prostor 6 + send_to_workspace_3: Pošalji u radni prostor 3 + send_to_workspace_1: Pošaljite u radni prostor 1 + send_to_workspace_2: Pošalji u radni prostor 2 + switch_workspace_1: Prebacite se na radni prostor 1 + send_to_workspace_7: Pošalji u radni prostor 7 + move_to_workspace_8: Premjestiti na radni prostor 8 + enable: Omogući integrirane prečice (AHK) + enable_tooltip: >- + Onemogućite ako ćete implementirati vlastite prečice koristeći Seelen Core + API +loading: Učitavanje... +inProgress: U toku... +cancel: Otkazati +delete: Izbrisati +save: Sačuvati +quit: Prestati +open: Otvoren diff --git a/src/apps/settings/i18n/translations/ca.yml b/src/apps/settings/i18n/translations/ca.yml index 3f398fdc..97f50336 100644 --- a/src/apps/settings/i18n/translations/ca.yml +++ b/src/apps/settings/i18n/translations/ca.yml @@ -1,195 +1,195 @@ -sides: - left: Esquerre - right: Dret - bottom: Fons - top: Superior -header: - labels: - info: Informació - seelen_wm: Gestor de finestres - seelen_bar: Barra d’eines de luxe - shortcuts: Dreceres - developer: Desenvolupador - seelen_weg: Moll/barra de tasques - monitors: Monitors - specific_apps: Aplicacions específiques - general: General -start: - title: Benvingut! - message_accent: Optimitzeu la vostra productivitat amb estil. - message: >- - Benvingut a la interfície d'usuari de Seelen, l'entorn d'escriptori - definitiu amb un gestor de Windows de rajoles incorporat per millorar la - vostra experiència de Windows 11. Exploreu una nova era d’eficiència i - multitasca amb la nostra interfície intuïtiva i les funcions avançades. -general: - theme: - added: Tema ja afegit - tags: Etiquetes - add: Afegiu el tema - description: Descripció - author: Autora - enabled: Temes habilitats - placeholder: Seleccioneu el tema - label: Informació del tema - available: Disponible - selected: Seleccionat - startup: Executeu la posada en marxa? - language: Llenguatge - icon_pack: - label: Paquets d’icones - accent_color: Color d’accent -toolbar: - placeholder: - description: Descripció - select: Estructura de la barra d’eines - author: Autora - height: Altura - enable: Activa la barra d’eines de luxe -wm: - border: - offset: Compensació fronterera - width: Amplada de la frontera - enable: Activa la vora de la finestra - layout: Pla - space_between_containers: Espai entre contenidors - disabled_windows10: El gestor de finestres no està disponible per a Windows 10. - workspace_offset: Offset d'espais de treball (marges) - resize_delta: Redimensiona el delta (%) - workspace_padding: Rado d’espais de treball - author: Autora - description: Descripció - enable: Activa el gestor de finestres -weg: - items: - visible_separators: Separadors visibles - label: Plantes - zoom_size: Mida zoom (usada per a temes) - size: Mida de l'article - gap: Espai entre articles - enable: Activa el moll/la barra de tasques - dock_side: Costat del moll - gap: Escletxa - margin: Marge - padding: Encoir - width: Amplada - label: Moll/barra de tasques - auto_hide: Amaga automàtic -devtools: - load: Carregar - data_folder: Carpeta de dades - settings_file: Arxiu de configuració - custom_config_file: Carregueu el fitxer de configuració personalitzada - app_folders: Carpetes d'aplicacions - enable: Activa les eines de desenvolupadors - install_folder: Carpeta d'instal·lació -apps_configurations: - app: - options: - force: Gestionar la força - float: Surar - unmanage: Implacable - pinned: Fixada - ok_edit: Actualitzar - workspace: Espai de treball - name: Nom - bindings: Enquadernació (nota les dues opcions són necessàries) - title_edit: Editing {{nom}} - category: Categoria - category_placeholder: Res - title_readonly: Visualització {{nom}} - workspace_placeholder: Res - ok_readonly: Edita com a nou - ok_create: Crear - monitor: Observar - title_create: Creació {{nom}} - monitor_placeholder: Res - options_label: Opcions addicionals - identifier: - add_block: Afegiu bloc - remove: Esborra el bloc - negation: Negar la concordança - and: I - matching_strategy: Estratègia de coincidència - id: Identificador - kind: Identificar -se per - or: O - confirm_delete_title: Confirmeu Suprimeix - search: Cerca - export: Exportar - new: Nou - bundled_title: Configuració de l'aplicació agrupada amb Seelen - import: Importar - confirm_delete: Esteu segur que voleu suprimir aquesta configuració/s? - bundled_msg: >- - Aquestes configuracions agrupades no són editables i estan dissenyades per - proporcionar -vos la millor experiència sense personalització. Configuen - automàticament les aplicacions més habituals per a vosaltres. - delete: Esborrar - swap: Canviar -extras: - github: Github - exit: Deixar/sortir - links: Enllaços oficials - discord: Discòrdia - relaunch: Rellançar - version: Versió -shortcuts: - labels: - reserve_top: Reserva superior - move_to_workspace_4: Traslladar -se a l'espai de treball 4 - move_to_workspace_7: Desplaceu -vos a l'espai de treball 7 - send_to_workspace_2: Enviar a l'espai de treball 2 - send_to_workspace_9: Enviar a l’espai de treball 9 - switch_workspace_2: Canvia a l'espai de treball 2 - move_to_workspace_1: Desplaceu -vos a l'espai de treball 1 - send_to_workspace_7: Enviar a l’espai de treball 7 - switch_workspace_9: Canvia a l'espai de treball 9 - reserve_right: Reserva a la dreta - reserve_left: Reserva a l'esquerra - switch_workspace_3: Canvia a l'espai de treball 3 - decrease_width: Disminuir l'amplada - move_to_workspace_3: Desplaceu -vos a l'espai de treball 3 - focus_right: Centra't a la dreta - switch_workspace_0: Canvia a l'espai de treball 0 - move_to_workspace_5: Desplaceu -vos a l'espai de treball 5 - focus_bottom: Focus Bottom - send_to_workspace_3: Envia a l’espai de treball 3 - switch_workspace_4: Canvia a l'espai de treball 4 - switch_workspace_6: Canvia a l'espai de treball 6 - focus_left: Focus deixat - move_to_workspace_0: Desplaceu -vos a l'espai de treball 0 - move_to_workspace_9: Traslladar -se a l'espai de treball 9 - reserve_float: Reserva flotant - reserve_stack: Pila de reserva - focus_latest: Focus més recent - move_to_workspace_6: Desplaceu -vos a l'espai de treball 6 - send_to_workspace_6: Enviar a l’espai de treball 6 - switch_workspace_7: Canvia a l'espai de treball 7 - switch_workspace_5: Canvia a l'espai de treball 5 - send_to_workspace_8: Enviar a l'espai de treball 8 - increase_width: Augment d'amplada - switch_workspace_8: Canvia a l'espai de treball 8 - send_to_workspace_5: Enviar a l’espai de treball 5 - move_to_workspace_2: Desplaceu -vos a l'espai de treball 2 - reserve_bottom: Reserva de fons - restore_sizes: Restaurar les mides - increase_height: Augmentar l'alçada - focus_top: Focus Top - decrease_height: Disminuir l'alçada - move_to_workspace_8: Traslladar -se a l'espai de treball 8 - send_to_workspace_0: Enviar a l’espai de treball 0 - send_to_workspace_4: Enviar a l’espai de treball 4 - switch_workspace_1: Canvieu a l'espai de treball 1 - send_to_workspace_1: Envia a l'espai de treball 1 - enable: Activa les dreceres integrades (AHK) - enable_tooltip: >- - Desactiveu si implementareu les vostres pròpies dreceres mitjançant l'API de - Seelen Core -loading: Carregant ... -open: Obrir -delete: Esborrar -inProgress: En progrés... -cancel: Cancel · lar -save: Estalviar -quit: Abandonar +sides: + left: Esquerre + right: Dret + bottom: Fons + top: Superior +header: + labels: + info: Informació + seelen_wm: Gestor de finestres + seelen_bar: Barra d’eines de luxe + shortcuts: Dreceres + developer: Desenvolupador + seelen_weg: Moll/barra de tasques + monitors: Monitors + specific_apps: Aplicacions específiques + general: General +start: + title: Benvingut! + message_accent: Optimitzeu la vostra productivitat amb estil. + message: >- + Benvingut a la interfície d'usuari de Seelen, l'entorn d'escriptori + definitiu amb un gestor de Windows de rajoles incorporat per millorar la + vostra experiència de Windows 11. Exploreu una nova era d’eficiència i + multitasca amb la nostra interfície intuïtiva i les funcions avançades. +general: + theme: + added: Tema ja afegit + tags: Etiquetes + add: Afegiu el tema + description: Descripció + author: Autora + enabled: Temes habilitats + placeholder: Seleccioneu el tema + label: Informació del tema + available: Disponible + selected: Seleccionat + startup: Executeu la posada en marxa? + language: Llenguatge + icon_pack: + label: Paquets d’icones + accent_color: Color d’accent +toolbar: + placeholder: + description: Descripció + select: Estructura de la barra d’eines + author: Autora + height: Altura + enable: Activa la barra d’eines de luxe +wm: + border: + offset: Compensació fronterera + width: Amplada de la frontera + enable: Activa la vora de la finestra + layout: Pla + space_between_containers: Espai entre contenidors + disabled_windows10: El gestor de finestres no està disponible per a Windows 10. + workspace_offset: Offset d'espais de treball (marges) + resize_delta: Redimensiona el delta (%) + workspace_padding: Rado d’espais de treball + author: Autora + description: Descripció + enable: Activa el gestor de finestres +weg: + items: + visible_separators: Separadors visibles + label: Plantes + zoom_size: Mida zoom (usada per a temes) + size: Mida de l'article + gap: Espai entre articles + enable: Activa el moll/la barra de tasques + dock_side: Costat del moll + gap: Escletxa + margin: Marge + padding: Encoir + width: Amplada + label: Moll/barra de tasques + auto_hide: Amaga automàtic +devtools: + load: Carregar + data_folder: Carpeta de dades + settings_file: Arxiu de configuració + custom_config_file: Carregueu el fitxer de configuració personalitzada + app_folders: Carpetes d'aplicacions + enable: Activa les eines de desenvolupadors + install_folder: Carpeta d'instal·lació +apps_configurations: + app: + options: + force: Gestionar la força + float: Surar + unmanage: Implacable + pinned: Fixada + ok_edit: Actualitzar + workspace: Espai de treball + name: Nom + bindings: Enquadernació (nota les dues opcions són necessàries) + title_edit: Editing {{nom}} + category: Categoria + category_placeholder: Res + title_readonly: Visualització {{nom}} + workspace_placeholder: Res + ok_readonly: Edita com a nou + ok_create: Crear + monitor: Observar + title_create: Creació {{nom}} + monitor_placeholder: Res + options_label: Opcions addicionals + identifier: + add_block: Afegiu bloc + remove: Esborra el bloc + negation: Negar la concordança + and: I + matching_strategy: Estratègia de coincidència + id: Identificador + kind: Identificar -se per + or: O + confirm_delete_title: Confirmeu Suprimeix + search: Cerca + export: Exportar + new: Nou + bundled_title: Configuració de l'aplicació agrupada amb Seelen + import: Importar + confirm_delete: Esteu segur que voleu suprimir aquesta configuració/s? + bundled_msg: >- + Aquestes configuracions agrupades no són editables i estan dissenyades per + proporcionar -vos la millor experiència sense personalització. Configuen + automàticament les aplicacions més habituals per a vosaltres. + delete: Esborrar + swap: Canviar +extras: + github: Github + exit: Deixar/sortir + links: Enllaços oficials + discord: Discòrdia + relaunch: Rellançar + version: Versió +shortcuts: + labels: + reserve_top: Reserva superior + move_to_workspace_4: Traslladar -se a l'espai de treball 4 + move_to_workspace_7: Desplaceu -vos a l'espai de treball 7 + send_to_workspace_2: Enviar a l'espai de treball 2 + send_to_workspace_9: Enviar a l’espai de treball 9 + switch_workspace_2: Canvia a l'espai de treball 2 + move_to_workspace_1: Desplaceu -vos a l'espai de treball 1 + send_to_workspace_7: Enviar a l’espai de treball 7 + switch_workspace_9: Canvia a l'espai de treball 9 + reserve_right: Reserva a la dreta + reserve_left: Reserva a l'esquerra + switch_workspace_3: Canvia a l'espai de treball 3 + decrease_width: Disminuir l'amplada + move_to_workspace_3: Desplaceu -vos a l'espai de treball 3 + focus_right: Centra't a la dreta + switch_workspace_0: Canvia a l'espai de treball 0 + move_to_workspace_5: Desplaceu -vos a l'espai de treball 5 + focus_bottom: Focus Bottom + send_to_workspace_3: Envia a l’espai de treball 3 + switch_workspace_4: Canvia a l'espai de treball 4 + switch_workspace_6: Canvia a l'espai de treball 6 + focus_left: Focus deixat + move_to_workspace_0: Desplaceu -vos a l'espai de treball 0 + move_to_workspace_9: Traslladar -se a l'espai de treball 9 + reserve_float: Reserva flotant + reserve_stack: Pila de reserva + focus_latest: Focus més recent + move_to_workspace_6: Desplaceu -vos a l'espai de treball 6 + send_to_workspace_6: Enviar a l’espai de treball 6 + switch_workspace_7: Canvia a l'espai de treball 7 + switch_workspace_5: Canvia a l'espai de treball 5 + send_to_workspace_8: Enviar a l'espai de treball 8 + increase_width: Augment d'amplada + switch_workspace_8: Canvia a l'espai de treball 8 + send_to_workspace_5: Enviar a l’espai de treball 5 + move_to_workspace_2: Desplaceu -vos a l'espai de treball 2 + reserve_bottom: Reserva de fons + restore_sizes: Restaurar les mides + increase_height: Augmentar l'alçada + focus_top: Focus Top + decrease_height: Disminuir l'alçada + move_to_workspace_8: Traslladar -se a l'espai de treball 8 + send_to_workspace_0: Enviar a l’espai de treball 0 + send_to_workspace_4: Enviar a l’espai de treball 4 + switch_workspace_1: Canvieu a l'espai de treball 1 + send_to_workspace_1: Envia a l'espai de treball 1 + enable: Activa les dreceres integrades (AHK) + enable_tooltip: >- + Desactiveu si implementareu les vostres pròpies dreceres mitjançant l'API de + Seelen Core +loading: Carregant ... +open: Obrir +delete: Esborrar +inProgress: En progrés... +cancel: Cancel · lar +save: Estalviar +quit: Abandonar diff --git a/src/apps/settings/i18n/translations/cs.yml b/src/apps/settings/i18n/translations/cs.yml index 9623c535..f02304c4 100644 --- a/src/apps/settings/i18n/translations/cs.yml +++ b/src/apps/settings/i18n/translations/cs.yml @@ -1,193 +1,193 @@ -sides: - left: Vlevo, odjet - top: Horní - right: Že jo - bottom: Dno -header: - labels: - info: Informace - developer: Vývojář - seelen_weg: Dock/TaskBar - general: Všeobecné - seelen_wm: Správce oken - seelen_bar: Ozdobný panel nástrojů - monitors: Monitory - specific_apps: Konkrétní aplikace - shortcuts: Zkratky -start: - title: Vítejte! - message: >- - Vítejte v SEELEN UI, Ultimate Desktop Environment s začleněným obkladovým - systémem Windows Manager, aby se zlepšil váš zážitek ze systému Windows 11! - Prozkoumejte novou éru účinnosti a multitaskingu s naším intuitivním - rozhraním a pokročilými funkcemi. - message_accent: Optimalizujte svou produktivitu stylem! -general: - theme: - description: Popis - author: Autor - enabled: Povolená témata - placeholder: Vyberte téma - added: Téma již bylo přidáno - add: Přidat téma - label: Informace o motivu - tags: Tagy - selected: Vybraný - available: Dostupný - startup: Spouštěn při každém startu? - language: Jazyk - icon_pack: - label: Ikona balíčky - accent_color: Accent Color -toolbar: - placeholder: - author: Autor - description: Popis - select: Struktura panelu nástrojů - height: Výška - enable: Povolte ozdobný panel nástrojů -wm: - border: - width: Šířka hranic - enable: Povolte hranici okna - offset: Offset hranic - author: Autor - description: Popis - disabled_windows10: Správce oken není k dispozici pro Windows 10. - resize_delta: Změna velikosti delta (%) - workspace_offset: Workspaces Offset (marže) - layout: Rozložení - enable: Povolit správce oken - space_between_containers: Prostor mezi kontejnery - workspace_padding: Polstrování pracovních prostorů -weg: - items: - zoom_size: Zvětšená velikost (použitá pro témata) - gap: Prostor mezi položkami - visible_separators: Viditelné separátory - label: Položky - size: Velikost položky - margin: Okraj - label: Dock/TaskBar - auto_hide: Automatické skrytí - enable: Povolte dock/hlavní panel - width: Šířka - gap: Mezera - padding: Polstrování - dock_side: Dock Side -devtools: - data_folder: Datová složka - settings_file: Nastavení souboru - load: Zatížení - app_folders: Složky aplikací - custom_config_file: Načíst vlastní konfigurační soubor - install_folder: Instalační složka - enable: Povolit vývojáře -apps_configurations: - app: - options: - force: Správa síly - float: Plovák - unmanage: Unmanage - pinned: Připnuto - ok_create: Vytvořit - workspace_placeholder: Žádný - category: Kategorie - ok_edit: Aktualizace - title_readonly: Prohlížení {{name}} - category_placeholder: Žádný - options_label: Další možnosti - monitor_placeholder: Žádný - bindings: Vazba (poznámka o tom, že jsou vyžadovány obě možnosti) - workspace: Pracovní prostor - title_edit: Editace {{name}} - title_create: Vytváření {{name}} - ok_readonly: Upravit jako nové - name: název - monitor: Monitor - identifier: - add_block: Přidat blok - negation: Negovat odpovídající - kind: Identifikovat - and: A - id: Identifikátor - matching_strategy: Srovnávací strategie - remove: Odstranit blok - or: NEBO - confirm_delete: Určitě chcete tuto konfiguraci smazat? - bundled_title: Konfigurace aplikace spojená s Seelen - export: Vývozní - confirm_delete_title: Potvrďte smazání - bundled_msg: >- - Tyto sdružené konfigurace nejsou upravitelné a jsou navrženy tak, aby vám - poskytly nejlepší zážitek bez přizpůsobení. Automaticky nakonfigurují pro - vás nejběžnější aplikace. - swap: Swap - search: Vyhledávání - delete: Vymazat - import: Import - new: Nový -extras: - relaunch: Opětovné - links: Oficiální odkazy - exit: Ukončit/ukončit - discord: Svár - github: GitHub - version: Verze -shortcuts: - labels: - move_to_workspace_2: Přesuňte se do pracovního prostoru 2 - move_to_workspace_4: Přesuňte se do pracovního prostoru 4 - reserve_right: Rezervovat správně - move_to_workspace_0: Přesuňte se do pracovního prostoru 0 - move_to_workspace_5: Přesuňte se do pracovního prostoru 5 - focus_bottom: Zaostřit dole - move_to_workspace_1: Přesuňte se do pracovního prostoru 1 - switch_workspace_9: Přepněte do pracovního prostoru 9 - send_to_workspace_1: Odeslat do pracovního prostoru 1 - reserve_bottom: Rezervní dno - switch_workspace_4: Přepněte do pracovního prostoru 4 - reserve_float: Rezervní plovák - move_to_workspace_8: Přesuňte se do pracovního prostoru 8 - move_to_workspace_6: Přesuňte se do pracovního prostoru 6 - send_to_workspace_2: Odeslat do pracovního prostoru 2 - focus_top: Zaostřit - reserve_top: Rezervní top - send_to_workspace_8: Odeslat do pracovního prostoru 8 - switch_workspace_3: Přepněte do pracovního prostoru 3 - decrease_height: Snížit výšku - switch_workspace_2: Přepněte do pracovního prostoru 2 - increase_height: Zvýšit výšku - switch_workspace_8: Přepněte do pracovního prostoru 8 - decrease_width: Snížit šířku - move_to_workspace_3: Přesuňte se do pracovního prostoru 3 - switch_workspace_6: Přepněte do pracovního prostoru 6 - switch_workspace_0: Přepněte do pracovního prostoru 0 - reserve_left: Rezerva vlevo - increase_width: Zvětšit šířku - restore_sizes: Obnovení velikosti - reserve_stack: Rezervní zásobník - switch_workspace_7: Přepněte do pracovního prostoru 7 - switch_workspace_1: Přepněte do pracovního prostoru 1 - switch_workspace_5: Přepněte do pracovního prostoru 5 - focus_right: Zaměřte se správně - focus_left: Zaostření doleva - focus_latest: Zaostřit nejnovější - send_to_workspace_4: Odeslat do pracovního prostoru 4 - send_to_workspace_0: Odeslat do pracovního prostoru 0 - send_to_workspace_9: Odeslat do pracovního prostoru 9 - send_to_workspace_6: Odeslat do pracovního prostoru 6 - send_to_workspace_5: Odeslat do pracovního prostoru 5 - send_to_workspace_3: Odeslat do pracovního prostoru 3 - move_to_workspace_7: Přesuňte se do pracovního prostoru 7 - send_to_workspace_7: Odeslat do pracovního prostoru 7 - move_to_workspace_9: Přesuňte se do pracovního prostoru 9 - enable: Povolit integrované zkratky (AHK) - enable_tooltip: Zakázat, pokud implementujete své vlastní zkratky pomocí API Seelen Core API -cancel: zrušení -delete: Vymazat -loading: Načítání... -quit: Přestat -save: Uložit -open: OTEVŘENO -inProgress: Probíhá ... +sides: + left: Vlevo, odjet + top: Horní + right: Že jo + bottom: Dno +header: + labels: + info: Informace + developer: Vývojář + seelen_weg: Dock/TaskBar + general: Všeobecné + seelen_wm: Správce oken + seelen_bar: Ozdobný panel nástrojů + monitors: Monitory + specific_apps: Konkrétní aplikace + shortcuts: Zkratky +start: + title: Vítejte! + message: >- + Vítejte v SEELEN UI, Ultimate Desktop Environment s začleněným obkladovým + systémem Windows Manager, aby se zlepšil váš zážitek ze systému Windows 11! + Prozkoumejte novou éru účinnosti a multitaskingu s naším intuitivním + rozhraním a pokročilými funkcemi. + message_accent: Optimalizujte svou produktivitu stylem! +general: + theme: + description: Popis + author: Autor + enabled: Povolená témata + placeholder: Vyberte téma + added: Téma již bylo přidáno + add: Přidat téma + label: Informace o motivu + tags: Tagy + selected: Vybraný + available: Dostupný + startup: Spouštěn při každém startu? + language: Jazyk + icon_pack: + label: Ikona balíčky + accent_color: Accent Color +toolbar: + placeholder: + author: Autor + description: Popis + select: Struktura panelu nástrojů + height: Výška + enable: Povolte ozdobný panel nástrojů +wm: + border: + width: Šířka hranic + enable: Povolte hranici okna + offset: Offset hranic + author: Autor + description: Popis + disabled_windows10: Správce oken není k dispozici pro Windows 10. + resize_delta: Změna velikosti delta (%) + workspace_offset: Workspaces Offset (marže) + layout: Rozložení + enable: Povolit správce oken + space_between_containers: Prostor mezi kontejnery + workspace_padding: Polstrování pracovních prostorů +weg: + items: + zoom_size: Zvětšená velikost (použitá pro témata) + gap: Prostor mezi položkami + visible_separators: Viditelné separátory + label: Položky + size: Velikost položky + margin: Okraj + label: Dock/TaskBar + auto_hide: Automatické skrytí + enable: Povolte dock/hlavní panel + width: Šířka + gap: Mezera + padding: Polstrování + dock_side: Dock Side +devtools: + data_folder: Datová složka + settings_file: Nastavení souboru + load: Zatížení + app_folders: Složky aplikací + custom_config_file: Načíst vlastní konfigurační soubor + install_folder: Instalační složka + enable: Povolit vývojáře +apps_configurations: + app: + options: + force: Správa síly + float: Plovák + unmanage: Unmanage + pinned: Připnuto + ok_create: Vytvořit + workspace_placeholder: Žádný + category: Kategorie + ok_edit: Aktualizace + title_readonly: Prohlížení {{name}} + category_placeholder: Žádný + options_label: Další možnosti + monitor_placeholder: Žádný + bindings: Vazba (poznámka o tom, že jsou vyžadovány obě možnosti) + workspace: Pracovní prostor + title_edit: Editace {{name}} + title_create: Vytváření {{name}} + ok_readonly: Upravit jako nové + name: název + monitor: Monitor + identifier: + add_block: Přidat blok + negation: Negovat odpovídající + kind: Identifikovat + and: A + id: Identifikátor + matching_strategy: Srovnávací strategie + remove: Odstranit blok + or: NEBO + confirm_delete: Určitě chcete tuto konfiguraci smazat? + bundled_title: Konfigurace aplikace spojená s Seelen + export: Vývozní + confirm_delete_title: Potvrďte smazání + bundled_msg: >- + Tyto sdružené konfigurace nejsou upravitelné a jsou navrženy tak, aby vám + poskytly nejlepší zážitek bez přizpůsobení. Automaticky nakonfigurují pro + vás nejběžnější aplikace. + swap: Swap + search: Vyhledávání + delete: Vymazat + import: Import + new: Nový +extras: + relaunch: Opětovné + links: Oficiální odkazy + exit: Ukončit/ukončit + discord: Svár + github: GitHub + version: Verze +shortcuts: + labels: + move_to_workspace_2: Přesuňte se do pracovního prostoru 2 + move_to_workspace_4: Přesuňte se do pracovního prostoru 4 + reserve_right: Rezervovat správně + move_to_workspace_0: Přesuňte se do pracovního prostoru 0 + move_to_workspace_5: Přesuňte se do pracovního prostoru 5 + focus_bottom: Zaostřit dole + move_to_workspace_1: Přesuňte se do pracovního prostoru 1 + switch_workspace_9: Přepněte do pracovního prostoru 9 + send_to_workspace_1: Odeslat do pracovního prostoru 1 + reserve_bottom: Rezervní dno + switch_workspace_4: Přepněte do pracovního prostoru 4 + reserve_float: Rezervní plovák + move_to_workspace_8: Přesuňte se do pracovního prostoru 8 + move_to_workspace_6: Přesuňte se do pracovního prostoru 6 + send_to_workspace_2: Odeslat do pracovního prostoru 2 + focus_top: Zaostřit + reserve_top: Rezervní top + send_to_workspace_8: Odeslat do pracovního prostoru 8 + switch_workspace_3: Přepněte do pracovního prostoru 3 + decrease_height: Snížit výšku + switch_workspace_2: Přepněte do pracovního prostoru 2 + increase_height: Zvýšit výšku + switch_workspace_8: Přepněte do pracovního prostoru 8 + decrease_width: Snížit šířku + move_to_workspace_3: Přesuňte se do pracovního prostoru 3 + switch_workspace_6: Přepněte do pracovního prostoru 6 + switch_workspace_0: Přepněte do pracovního prostoru 0 + reserve_left: Rezerva vlevo + increase_width: Zvětšit šířku + restore_sizes: Obnovení velikosti + reserve_stack: Rezervní zásobník + switch_workspace_7: Přepněte do pracovního prostoru 7 + switch_workspace_1: Přepněte do pracovního prostoru 1 + switch_workspace_5: Přepněte do pracovního prostoru 5 + focus_right: Zaměřte se správně + focus_left: Zaostření doleva + focus_latest: Zaostřit nejnovější + send_to_workspace_4: Odeslat do pracovního prostoru 4 + send_to_workspace_0: Odeslat do pracovního prostoru 0 + send_to_workspace_9: Odeslat do pracovního prostoru 9 + send_to_workspace_6: Odeslat do pracovního prostoru 6 + send_to_workspace_5: Odeslat do pracovního prostoru 5 + send_to_workspace_3: Odeslat do pracovního prostoru 3 + move_to_workspace_7: Přesuňte se do pracovního prostoru 7 + send_to_workspace_7: Odeslat do pracovního prostoru 7 + move_to_workspace_9: Přesuňte se do pracovního prostoru 9 + enable: Povolit integrované zkratky (AHK) + enable_tooltip: Zakázat, pokud implementujete své vlastní zkratky pomocí API Seelen Core API +cancel: zrušení +delete: Vymazat +loading: Načítání... +quit: Přestat +save: Uložit +open: OTEVŘENO +inProgress: Probíhá ... diff --git a/src/apps/settings/i18n/translations/cy.yml b/src/apps/settings/i18n/translations/cy.yml index 049baa14..8bcb7025 100644 --- a/src/apps/settings/i18n/translations/cy.yml +++ b/src/apps/settings/i18n/translations/cy.yml @@ -1,195 +1,195 @@ -sides: - left: Chwith - bottom: Waelod - top: Brigant - right: Dde -header: - labels: - seelen_wm: Rheolwr Ffenestr - general: Gyffredinol - info: Ngwybodaeth - monitors: Monitorau - shortcuts: Llwybrau byr - specific_apps: Apiau penodol - developer: Natblygwr - seelen_weg: Doc/bar tasgau - seelen_bar: Bar offer ffansi -start: - message_accent: Optimeiddio'ch cynhyrchiant gydag arddull! - title: Croeso! - message: >- - Croeso i Seelen UI, yr amgylchedd bwrdd gwaith yn y pen draw gyda rheolwr - ffenestri teils corfforedig i wella'ch profiad Windows 11! Archwiliwch oes - newydd o effeithlonrwydd ac amldasgio gyda'n rhyngwyneb greddfol a'n - nodweddion uwch. -general: - theme: - placeholder: Dewiswch Thema - enabled: Themâu wedi'u galluogi - tags: Tagiau - author: Awduron - add: Ychwanegu Thema - added: Thema wedi'i hychwanegu eisoes - label: Gwybodaeth Thema - description: Disgrifiadau - selected: Dethol - available: AR GAEL - language: Iaith - startup: Rhedeg ar gychwyn? - icon_pack: - label: Pecynnau eicon - accent_color: Lliw acen -toolbar: - placeholder: - author: Awduron - description: Disgrifiadau - select: Strwythur Bar Offer - enable: Galluogi bar offer ffansi - height: Uchder -wm: - border: - width: Lled - enable: Galluogi ffin ffenestr - offset: Gwrthbwyso ar y ffin - disabled_windows10: Nid yw'r Rheolwr Ffenestr ar gael ar gyfer Windows 10. - space_between_containers: Lle rhwng cynwysyddion - author: Awduron - description: Disgrifiadau - enable: Galluogi Rheolwr Ffenestr - workspace_offset: Gwrthbwyso lleoedd gwaith (ymylon) - workspace_padding: Padin lleoedd gwaith - resize_delta: Newid maint Delta (%) - layout: Gynllun -weg: - items: - label: Eitemau - size: Maint eitem - visible_separators: Gwahanyddion gweladwy - zoom_size: Maint chwyddo (a ddefnyddir ar gyfer themâu) - gap: Lle rhwng eitemau - enable: Galluogi doc/bar tasg - auto_hide: Cuddio awto - label: Doc/bar tasgau - width: Lled - padding: Padin - dock_side: Ochr doc - margin: Ngherlong - gap: Bwlch -devtools: - data_folder: Ffolder data - custom_config_file: Llwythwch ffeil ffurfweddu arfer - load: Lwythet - enable: Galluogi Offer Datblygwr - app_folders: Ffolderau app - settings_file: Ffeil Gosodiadau - install_folder: Ffolder gosod -apps_configurations: - app: - options: - pinned: Pined - force: Rheoli Llu - unmanage: Di -reol - float: Harnofion - category: Categori - ok_readonly: Golygu fel NEWYDD - bindings: Rhwymo (nodwch fod angen y ddau opsiwn) - workspace_placeholder: Neb - monitor_placeholder: Neb - monitor: Monitrest - name: Alwai - options_label: Opsiynau ychwanegol - title_create: Creu {{enw}} - workspace: Gweithle - title_readonly: Gweld {{enw}} - ok_edit: Diweddara ’ - category_placeholder: Neb - title_edit: Golygu {{enw}} - ok_create: Chrëid - identifier: - matching_strategy: Strategaeth gyfatebol - id: Dynodwr - remove: Dileu bloc - negation: Negate paru - add_block: Ychwanegu bloc - kind: Adnabod gan - or: Neu - and: A - new: Newydd - bundled_title: App Config wedi'i bwndelu â Seelen - confirm_delete: Ydych chi'n siŵr eich bod chi am ddileu'r cyfluniad/au hwn? - confirm_delete_title: Cadarnhau Dileu - bundled_msg: >- - Nid oes modd golygu'r cyfluniadau bwndelu hyn ac fe'u cynlluniwyd i roi'r - profiad gorau i chi heb addasu. Maent yn ffurfweddu'r cymwysiadau mwyaf - cyffredin ar eich cyfer yn awtomatig. - export: Allforiff - import: Mewnforied - search: Chwiloon - delete: Croeswn - swap: Trwciff -extras: - relaunch: Hail -deirion - github: Github - discord: Anghytgord - version: Fersiwn - exit: Rhoi'r gorau iddi/allanfa - links: Dolenni Swyddogol -shortcuts: - labels: - reserve_right: Cadw Iawn - move_to_workspace_0: Symud i Workpace 0 - focus_right: Canolbwyntiwch yn iawn - switch_workspace_3: Newid i Workpace 3 - focus_left: Ffocws ar ôl - move_to_workspace_3: Symud i Workpace 3 - switch_workspace_7: Newid i Workpace 7 - send_to_workspace_4: Anfonwch i Workpace 4 - reserve_top: Top wrth gefn - increase_height: Cynyddu uchder - increase_width: Cynyddu lled - send_to_workspace_5: Anfonwch i Workpace 5 - focus_top: Top Ffocws - decrease_width: Lleihau lled - switch_workspace_5: Newid i Workpace 5 - reserve_bottom: Cadwch y gwaelod - switch_workspace_2: Newid i Workpace 2 - reserve_stack: Pentwr wrth gefn - reserve_left: Gwarchodfa Chwith - switch_workspace_9: Newid i Workpace 9 - focus_latest: Canolbwyntiwch y Diweddaraf - send_to_workspace_7: Anfon i Workpace 7 - send_to_workspace_9: Anfonwch i Workpace 9 - decrease_height: Lleihau uchder - send_to_workspace_8: Anfonwch i Workpace 8 - switch_workspace_6: Newid i Workpace 6 - switch_workspace_8: Newid i Workpace 8 - focus_bottom: Ffocws Gwaelod - restore_sizes: Adfer Meintiau - switch_workspace_4: Newid i Workpace 4 - switch_workspace_1: Newid i Workpace 1 - move_to_workspace_7: Symud i Workpace 7 - send_to_workspace_6: Anfonwch i Workpace 6 - send_to_workspace_2: Anfonwch i Workpace 2 - move_to_workspace_5: Symud i Workpace 5 - move_to_workspace_9: Symud i Workpace 9 - move_to_workspace_8: Symud i Workpace 8 - move_to_workspace_6: Symud i Workpace 6 - send_to_workspace_1: Anfonwch i Workpace 1 - move_to_workspace_2: Symud i Workpace 2 - reserve_float: Arnofio wrth gefn - switch_workspace_0: Newid i Workpace 0 - send_to_workspace_3: Anfonwch i Workpace 3 - move_to_workspace_4: Symud i Workpace 4 - move_to_workspace_1: Symud i Workpace 1 - send_to_workspace_0: Anfon i Workpace 0 - enable: Galluogi llwybrau byr integredig (AHK) - enable_tooltip: >- - Analluoga os byddwch chi'n gweithredu'ch llwybrau byr eich hun gan - ddefnyddio API craidd Seelen -inProgress: Ar y gweill... -loading: Llwytho ... -cancel: Chansliff -save: Hiachasit -delete: Croeswn -quit: Gadawen -open: Ymagorant +sides: + left: Chwith + bottom: Waelod + top: Brigant + right: Dde +header: + labels: + seelen_wm: Rheolwr Ffenestr + general: Gyffredinol + info: Ngwybodaeth + monitors: Monitorau + shortcuts: Llwybrau byr + specific_apps: Apiau penodol + developer: Natblygwr + seelen_weg: Doc/bar tasgau + seelen_bar: Bar offer ffansi +start: + message_accent: Optimeiddio'ch cynhyrchiant gydag arddull! + title: Croeso! + message: >- + Croeso i Seelen UI, yr amgylchedd bwrdd gwaith yn y pen draw gyda rheolwr + ffenestri teils corfforedig i wella'ch profiad Windows 11! Archwiliwch oes + newydd o effeithlonrwydd ac amldasgio gyda'n rhyngwyneb greddfol a'n + nodweddion uwch. +general: + theme: + placeholder: Dewiswch Thema + enabled: Themâu wedi'u galluogi + tags: Tagiau + author: Awduron + add: Ychwanegu Thema + added: Thema wedi'i hychwanegu eisoes + label: Gwybodaeth Thema + description: Disgrifiadau + selected: Dethol + available: AR GAEL + language: Iaith + startup: Rhedeg ar gychwyn? + icon_pack: + label: Pecynnau eicon + accent_color: Lliw acen +toolbar: + placeholder: + author: Awduron + description: Disgrifiadau + select: Strwythur Bar Offer + enable: Galluogi bar offer ffansi + height: Uchder +wm: + border: + width: Lled + enable: Galluogi ffin ffenestr + offset: Gwrthbwyso ar y ffin + disabled_windows10: Nid yw'r Rheolwr Ffenestr ar gael ar gyfer Windows 10. + space_between_containers: Lle rhwng cynwysyddion + author: Awduron + description: Disgrifiadau + enable: Galluogi Rheolwr Ffenestr + workspace_offset: Gwrthbwyso lleoedd gwaith (ymylon) + workspace_padding: Padin lleoedd gwaith + resize_delta: Newid maint Delta (%) + layout: Gynllun +weg: + items: + label: Eitemau + size: Maint eitem + visible_separators: Gwahanyddion gweladwy + zoom_size: Maint chwyddo (a ddefnyddir ar gyfer themâu) + gap: Lle rhwng eitemau + enable: Galluogi doc/bar tasg + auto_hide: Cuddio awto + label: Doc/bar tasgau + width: Lled + padding: Padin + dock_side: Ochr doc + margin: Ngherlong + gap: Bwlch +devtools: + data_folder: Ffolder data + custom_config_file: Llwythwch ffeil ffurfweddu arfer + load: Lwythet + enable: Galluogi Offer Datblygwr + app_folders: Ffolderau app + settings_file: Ffeil Gosodiadau + install_folder: Ffolder gosod +apps_configurations: + app: + options: + pinned: Pined + force: Rheoli Llu + unmanage: Di -reol + float: Harnofion + category: Categori + ok_readonly: Golygu fel NEWYDD + bindings: Rhwymo (nodwch fod angen y ddau opsiwn) + workspace_placeholder: Neb + monitor_placeholder: Neb + monitor: Monitrest + name: Alwai + options_label: Opsiynau ychwanegol + title_create: Creu {{enw}} + workspace: Gweithle + title_readonly: Gweld {{enw}} + ok_edit: Diweddara ’ + category_placeholder: Neb + title_edit: Golygu {{enw}} + ok_create: Chrëid + identifier: + matching_strategy: Strategaeth gyfatebol + id: Dynodwr + remove: Dileu bloc + negation: Negate paru + add_block: Ychwanegu bloc + kind: Adnabod gan + or: Neu + and: A + new: Newydd + bundled_title: App Config wedi'i bwndelu â Seelen + confirm_delete: Ydych chi'n siŵr eich bod chi am ddileu'r cyfluniad/au hwn? + confirm_delete_title: Cadarnhau Dileu + bundled_msg: >- + Nid oes modd golygu'r cyfluniadau bwndelu hyn ac fe'u cynlluniwyd i roi'r + profiad gorau i chi heb addasu. Maent yn ffurfweddu'r cymwysiadau mwyaf + cyffredin ar eich cyfer yn awtomatig. + export: Allforiff + import: Mewnforied + search: Chwiloon + delete: Croeswn + swap: Trwciff +extras: + relaunch: Hail -deirion + github: Github + discord: Anghytgord + version: Fersiwn + exit: Rhoi'r gorau iddi/allanfa + links: Dolenni Swyddogol +shortcuts: + labels: + reserve_right: Cadw Iawn + move_to_workspace_0: Symud i Workpace 0 + focus_right: Canolbwyntiwch yn iawn + switch_workspace_3: Newid i Workpace 3 + focus_left: Ffocws ar ôl + move_to_workspace_3: Symud i Workpace 3 + switch_workspace_7: Newid i Workpace 7 + send_to_workspace_4: Anfonwch i Workpace 4 + reserve_top: Top wrth gefn + increase_height: Cynyddu uchder + increase_width: Cynyddu lled + send_to_workspace_5: Anfonwch i Workpace 5 + focus_top: Top Ffocws + decrease_width: Lleihau lled + switch_workspace_5: Newid i Workpace 5 + reserve_bottom: Cadwch y gwaelod + switch_workspace_2: Newid i Workpace 2 + reserve_stack: Pentwr wrth gefn + reserve_left: Gwarchodfa Chwith + switch_workspace_9: Newid i Workpace 9 + focus_latest: Canolbwyntiwch y Diweddaraf + send_to_workspace_7: Anfon i Workpace 7 + send_to_workspace_9: Anfonwch i Workpace 9 + decrease_height: Lleihau uchder + send_to_workspace_8: Anfonwch i Workpace 8 + switch_workspace_6: Newid i Workpace 6 + switch_workspace_8: Newid i Workpace 8 + focus_bottom: Ffocws Gwaelod + restore_sizes: Adfer Meintiau + switch_workspace_4: Newid i Workpace 4 + switch_workspace_1: Newid i Workpace 1 + move_to_workspace_7: Symud i Workpace 7 + send_to_workspace_6: Anfonwch i Workpace 6 + send_to_workspace_2: Anfonwch i Workpace 2 + move_to_workspace_5: Symud i Workpace 5 + move_to_workspace_9: Symud i Workpace 9 + move_to_workspace_8: Symud i Workpace 8 + move_to_workspace_6: Symud i Workpace 6 + send_to_workspace_1: Anfonwch i Workpace 1 + move_to_workspace_2: Symud i Workpace 2 + reserve_float: Arnofio wrth gefn + switch_workspace_0: Newid i Workpace 0 + send_to_workspace_3: Anfonwch i Workpace 3 + move_to_workspace_4: Symud i Workpace 4 + move_to_workspace_1: Symud i Workpace 1 + send_to_workspace_0: Anfon i Workpace 0 + enable: Galluogi llwybrau byr integredig (AHK) + enable_tooltip: >- + Analluoga os byddwch chi'n gweithredu'ch llwybrau byr eich hun gan + ddefnyddio API craidd Seelen +inProgress: Ar y gweill... +loading: Llwytho ... +cancel: Chansliff +save: Hiachasit +delete: Croeswn +quit: Gadawen +open: Ymagorant diff --git a/src/apps/settings/i18n/translations/da.yml b/src/apps/settings/i18n/translations/da.yml index 4d981c54..4ac88a18 100644 --- a/src/apps/settings/i18n/translations/da.yml +++ b/src/apps/settings/i18n/translations/da.yml @@ -1,195 +1,195 @@ -sides: - left: Venstre - right: Højre - bottom: Bund - top: Top -header: - labels: - seelen_wm: Window Manager - seelen_weg: Dock/proceslinje - developer: Udvikler - general: Generel - info: Information - seelen_bar: Fancy værktøjslinje - specific_apps: Specifikke apps - shortcuts: Genveje - monitors: Monitors -start: - message_accent: Optimer din produktivitet med stil! - title: Velkommen! - message: >- - Velkommen til Seelen UI, det ultimative desktopmiljø med en inkorporeret - Flising Windows Manager for at forbedre din Windows 11 -oplevelse! Udforsk - en ny æra med effektivitet og multitasking med vores intuitive interface og - avancerede funktioner. -general: - theme: - label: Temaoplysninger - placeholder: Vælg tema - enabled: Aktiverede temaer - author: Forfatter - added: Tema allerede tilføjet - add: Tilføj tema - description: Beskrivelse - tags: Tags - selected: Valgte - available: Ledig - startup: Kør ved opstart? - language: Sprog - icon_pack: - label: Ikonpakker - accent_color: Accentfarve -toolbar: - placeholder: - select: Værktøjslinjestruktur - description: Beskrivelse - author: Forfatter - enable: Aktivér fancy værktøjslinje - height: Højde -wm: - border: - width: Grænsebredde - enable: Aktivér vindues grænse - offset: Border Offset - disabled_windows10: Window Manager er ikke tilgængelig til Windows 10. - author: Forfatter - description: Beskrivelse - resize_delta: Ændre størrelse på Delta (%) - layout: Layout - enable: Aktivér vindueadministrator - space_between_containers: Rum mellem containere - workspace_padding: Arbejdsområder polstring - workspace_offset: Arbejdsområder offset (marginer) -weg: - items: - label: Genstande - zoom_size: Zoomet størrelse (brugt til temaer) - visible_separators: Synlige separatorer - size: Varestørrelse - gap: Rum mellem genstande - width: Bredde - margin: Margin - enable: Aktivér dock/proceslinje - auto_hide: Auto skjul - gap: Gap - padding: Polstring - label: Dock/proceslinje - dock_side: Dock side -devtools: - enable: Aktivér udviklerværktøjer - settings_file: Indstillinger fil - app_folders: Appmapper - custom_config_file: Indlæs brugerdefineret konfigurationsfil - data_folder: Datamappe - load: belastning - install_folder: Installationsmappe -apps_configurations: - app: - options: - force: Force Management - float: Flyde - pinned: Fastgjort - unmanage: Uudvikling - title_edit: Redigering {{navn}} - monitor_placeholder: Ingen - ok_edit: Opdatering - workspace: Arbejdsområde - category: Kategori - options_label: Ekstra muligheder - bindings: Binding (note begge muligheder er påkrævet) - title_readonly: Visning {{navn}} - name: Navn - category_placeholder: Ingen - ok_readonly: Rediger som ny - workspace_placeholder: Ingen - title_create: Oprettelse af {{navn}} - ok_create: skab - monitor: Overvåge - identifier: - id: Identifikator - add_block: Tilføj blok - remove: Slet blok - matching_strategy: Matchende strategi - or: ELLER - kind: Identificer ved - and: OG - negation: Negat matchning - delete: Slet - bundled_title: App Config bundtet med Seelen - confirm_delete: Er du sikker på, at du vil slette denne konfiguration/er? - swap: Bytte rundt - export: Eksport - new: Ny - bundled_msg: >- - Disse samlede konfigurationer kan ikke redigeres og er designet til at give - dig den bedste oplevelse uden tilpasning. De konfigurerer automatisk de mest - almindelige applikationer til dig. - confirm_delete_title: Bekræft slet - search: Søg - import: Importere -extras: - exit: Afslut/exit - links: Officielle links - github: GitHub - discord: Uenighed - version: Version - relaunch: Relancering -shortcuts: - labels: - move_to_workspace_6: Flyt til arbejdsområde 6 - move_to_workspace_4: Flyt til arbejdsområde 4 - decrease_height: Reducer højden - reserve_bottom: Reserve bund - switch_workspace_5: Skift til arbejdsområde 5 - restore_sizes: Gendanstørrelser - reserve_right: Reserver rigtigt - send_to_workspace_9: Send til Workspace 9 - switch_workspace_3: Skift til arbejdsområde 3 - move_to_workspace_5: Flyt til arbejdsområde 5 - send_to_workspace_8: Send til arbejdsområde 8 - move_to_workspace_2: Flyt til arbejdsområde 2 - move_to_workspace_0: Flyt til arbejdsområdet 0 - move_to_workspace_1: Flyt til arbejdsområdet 1 - increase_width: Øg bredden - focus_top: Fokus top - focus_left: Fokus tilbage - send_to_workspace_4: Send til Workspace 4 - focus_latest: Fokus seneste - send_to_workspace_2: Send til Workspace 2 - move_to_workspace_8: Flyt til arbejdsområde 8 - send_to_workspace_0: Send til arbejdsområdet 0 - reserve_stack: Reserve stak - switch_workspace_8: Skift til arbejdsområde 8 - decrease_width: Reducer bredden - switch_workspace_9: Skift til arbejdsområde 9 - move_to_workspace_7: Flyt til arbejdsområde 7 - reserve_left: Reserve til venstre - reserve_float: Reserve float - switch_workspace_1: Skift til arbejdsområde 1 - switch_workspace_7: Skift til arbejdsområde 7 - switch_workspace_4: Skift til arbejdsområde 4 - switch_workspace_2: Skift til arbejdsområde 2 - send_to_workspace_6: Send til arbejdsområde 6 - send_to_workspace_1: Send til arbejdsområde 1 - reserve_top: Reserver top - send_to_workspace_3: Send til Workspace 3 - send_to_workspace_7: Send til Workspace 7 - move_to_workspace_9: Flyt til arbejdsområde 9 - increase_height: Øg højde - focus_bottom: Fokusbund - switch_workspace_6: Skift til arbejdsområde 6 - switch_workspace_0: Skift til arbejdsområdet 0 - move_to_workspace_3: Flyt til arbejdsområde 3 - focus_right: Fokusere rigtigt - send_to_workspace_5: Send til arbejdsområde 5 - enable: Aktivér integrerede genveje (AHK) - enable_tooltip: >- - Deaktiver, hvis du implementerer dine egne genveje ved hjælp af Seelen Core - API -inProgress: I gang... -open: Åben -delete: Slet -quit: Afslut -save: Gemme -loading: Indlæser... -cancel: Afbestille +sides: + left: Venstre + right: Højre + bottom: Bund + top: Top +header: + labels: + seelen_wm: Window Manager + seelen_weg: Dock/proceslinje + developer: Udvikler + general: Generel + info: Information + seelen_bar: Fancy værktøjslinje + specific_apps: Specifikke apps + shortcuts: Genveje + monitors: Monitors +start: + message_accent: Optimer din produktivitet med stil! + title: Velkommen! + message: >- + Velkommen til Seelen UI, det ultimative desktopmiljø med en inkorporeret + Flising Windows Manager for at forbedre din Windows 11 -oplevelse! Udforsk + en ny æra med effektivitet og multitasking med vores intuitive interface og + avancerede funktioner. +general: + theme: + label: Temaoplysninger + placeholder: Vælg tema + enabled: Aktiverede temaer + author: Forfatter + added: Tema allerede tilføjet + add: Tilføj tema + description: Beskrivelse + tags: Tags + selected: Valgte + available: Ledig + startup: Kør ved opstart? + language: Sprog + icon_pack: + label: Ikonpakker + accent_color: Accentfarve +toolbar: + placeholder: + select: Værktøjslinjestruktur + description: Beskrivelse + author: Forfatter + enable: Aktivér fancy værktøjslinje + height: Højde +wm: + border: + width: Grænsebredde + enable: Aktivér vindues grænse + offset: Border Offset + disabled_windows10: Window Manager er ikke tilgængelig til Windows 10. + author: Forfatter + description: Beskrivelse + resize_delta: Ændre størrelse på Delta (%) + layout: Layout + enable: Aktivér vindueadministrator + space_between_containers: Rum mellem containere + workspace_padding: Arbejdsområder polstring + workspace_offset: Arbejdsområder offset (marginer) +weg: + items: + label: Genstande + zoom_size: Zoomet størrelse (brugt til temaer) + visible_separators: Synlige separatorer + size: Varestørrelse + gap: Rum mellem genstande + width: Bredde + margin: Margin + enable: Aktivér dock/proceslinje + auto_hide: Auto skjul + gap: Gap + padding: Polstring + label: Dock/proceslinje + dock_side: Dock side +devtools: + enable: Aktivér udviklerværktøjer + settings_file: Indstillinger fil + app_folders: Appmapper + custom_config_file: Indlæs brugerdefineret konfigurationsfil + data_folder: Datamappe + load: belastning + install_folder: Installationsmappe +apps_configurations: + app: + options: + force: Force Management + float: Flyde + pinned: Fastgjort + unmanage: Uudvikling + title_edit: Redigering {{navn}} + monitor_placeholder: Ingen + ok_edit: Opdatering + workspace: Arbejdsområde + category: Kategori + options_label: Ekstra muligheder + bindings: Binding (note begge muligheder er påkrævet) + title_readonly: Visning {{navn}} + name: Navn + category_placeholder: Ingen + ok_readonly: Rediger som ny + workspace_placeholder: Ingen + title_create: Oprettelse af {{navn}} + ok_create: skab + monitor: Overvåge + identifier: + id: Identifikator + add_block: Tilføj blok + remove: Slet blok + matching_strategy: Matchende strategi + or: ELLER + kind: Identificer ved + and: OG + negation: Negat matchning + delete: Slet + bundled_title: App Config bundtet med Seelen + confirm_delete: Er du sikker på, at du vil slette denne konfiguration/er? + swap: Bytte rundt + export: Eksport + new: Ny + bundled_msg: >- + Disse samlede konfigurationer kan ikke redigeres og er designet til at give + dig den bedste oplevelse uden tilpasning. De konfigurerer automatisk de mest + almindelige applikationer til dig. + confirm_delete_title: Bekræft slet + search: Søg + import: Importere +extras: + exit: Afslut/exit + links: Officielle links + github: GitHub + discord: Uenighed + version: Version + relaunch: Relancering +shortcuts: + labels: + move_to_workspace_6: Flyt til arbejdsområde 6 + move_to_workspace_4: Flyt til arbejdsområde 4 + decrease_height: Reducer højden + reserve_bottom: Reserve bund + switch_workspace_5: Skift til arbejdsområde 5 + restore_sizes: Gendanstørrelser + reserve_right: Reserver rigtigt + send_to_workspace_9: Send til Workspace 9 + switch_workspace_3: Skift til arbejdsområde 3 + move_to_workspace_5: Flyt til arbejdsområde 5 + send_to_workspace_8: Send til arbejdsområde 8 + move_to_workspace_2: Flyt til arbejdsområde 2 + move_to_workspace_0: Flyt til arbejdsområdet 0 + move_to_workspace_1: Flyt til arbejdsområdet 1 + increase_width: Øg bredden + focus_top: Fokus top + focus_left: Fokus tilbage + send_to_workspace_4: Send til Workspace 4 + focus_latest: Fokus seneste + send_to_workspace_2: Send til Workspace 2 + move_to_workspace_8: Flyt til arbejdsområde 8 + send_to_workspace_0: Send til arbejdsområdet 0 + reserve_stack: Reserve stak + switch_workspace_8: Skift til arbejdsområde 8 + decrease_width: Reducer bredden + switch_workspace_9: Skift til arbejdsområde 9 + move_to_workspace_7: Flyt til arbejdsområde 7 + reserve_left: Reserve til venstre + reserve_float: Reserve float + switch_workspace_1: Skift til arbejdsområde 1 + switch_workspace_7: Skift til arbejdsområde 7 + switch_workspace_4: Skift til arbejdsområde 4 + switch_workspace_2: Skift til arbejdsområde 2 + send_to_workspace_6: Send til arbejdsområde 6 + send_to_workspace_1: Send til arbejdsområde 1 + reserve_top: Reserver top + send_to_workspace_3: Send til Workspace 3 + send_to_workspace_7: Send til Workspace 7 + move_to_workspace_9: Flyt til arbejdsområde 9 + increase_height: Øg højde + focus_bottom: Fokusbund + switch_workspace_6: Skift til arbejdsområde 6 + switch_workspace_0: Skift til arbejdsområdet 0 + move_to_workspace_3: Flyt til arbejdsområde 3 + focus_right: Fokusere rigtigt + send_to_workspace_5: Send til arbejdsområde 5 + enable: Aktivér integrerede genveje (AHK) + enable_tooltip: >- + Deaktiver, hvis du implementerer dine egne genveje ved hjælp af Seelen Core + API +inProgress: I gang... +open: Åben +delete: Slet +quit: Afslut +save: Gemme +loading: Indlæser... +cancel: Afbestille diff --git a/src/apps/settings/i18n/translations/de.yml b/src/apps/settings/i18n/translations/de.yml index f750893b..b73d512f 100644 --- a/src/apps/settings/i18n/translations/de.yml +++ b/src/apps/settings/i18n/translations/de.yml @@ -1,195 +1,195 @@ -loading: Laden... -inProgress: In Bearbeitung... -cancel: Abbrechen -save: Speichern -quit: Beenden -open: Öffnen -delete: Löschen -sides: - left: Links - right: Rechts - top: Oben - bottom: Unten -header: - labels: - general: Allgemein - seelen_bar: Elegante Werkzeugleiste - seelen_wm: Fenstermanager - seelen_weg: Dock/Taskleiste - monitors: Monitore - specific_apps: Spezifische Apps - shortcuts: Kurzbefehle - developer: Entwickler - info: Information -start: - title: Willkommen! - message: >- - Willkommen bei Seelen UI, der ultimativen Desktop-Umgebung mit einem - integrierten Kachel-Fenstermanager, um dein Windows 11-Erlebnis zu - verbessern! Erkunde eine neue Ära der Effizienz und Multitasking mit unserer - intuitiven Oberfläche und fortschrittlichen Funktionen. - message_accent: Optimiere deine Produktivität mit Stil! -general: - startup: Beim Start ausführen? - language: Sprache - theme: - label: Themeninformation - placeholder: Thema auswählen - author: Autor - description: Beschreibung - add: Thema hinzufügen - added: Thema bereits hinzugefügt - enabled: Aktivierte Themen - tags: Tags - selected: Ausgewählt - available: Verfügbar - icon_pack: - label: Icon Packs - accent_color: Akzentfarbe -toolbar: - enable: Elegante Werkzeugleiste aktivieren - placeholder: - select: Struktur der Werkzeugleiste - author: Autor - description: Beschreibung - height: Höhe -wm: - enable: Fenstermanager aktivieren - disabled_windows10: Der Fenstermanager ist nicht für Windows 10 verfügbar. - layout: Layout - author: Autor - description: Beschreibung - space_between_containers: Abstand zwischen Containern - workspace_padding: Arbeitsbereichs-Padding - workspace_offset: Arbeitsbereichs-Versatz (Ränder) - resize_delta: Größenänderung Delta (%) - border: - enable: Fensterrand aktivieren - width: Randbreite - offset: Randversatz -weg: - label: Dock/Taskleiste - enable: Dock/Taskleiste aktivieren - width: Breite - auto_hide: Automatisch ausblenden - dock_side: Dock-Seite - padding: Polsterung - margin: Rand - gap: Abstand - items: - label: Elemente - size: Elementgröße - zoom_size: Vergrößerte Größe (für Themen verwendet) - gap: Abstand zwischen Elementen - visible_separators: Sichtbare Trennzeichen -devtools: - enable: Entwicklerwerkzeuge aktivieren - app_folders: Anwendungsordner - install_folder: Installationsordner - data_folder: Datenordner - settings_file: Einstellungsdatei - custom_config_file: Benutzerdefinierte Konfigurationsdatei laden - load: Laden -apps_configurations: - import: Importieren - export: Exportieren - delete: Löschen - swap: Tauschen - new: Neu - bundled_title: Mit Seelen gebündelte App-Konfiguration - bundled_msg: >- - Diese gebündelten Konfigurationen sind nicht bearbeitbar und wurden - entwickelt, um dir das beste Erlebnis ohne Anpassung zu bieten. Sie - konfigurieren die gebräuchlichsten Anwendungen automatisch für dich. - confirm_delete_title: Löschen bestätigen - confirm_delete: Möchtest du diese Konfiguration wirklich löschen? - search: Suchen - app: - name: Name - category: Kategorie - category_placeholder: Keine - bindings: Bindung (beide Optionen sind erforderlich) - monitor: Monitor - monitor_placeholder: Keine - workspace: Arbeitsbereich - workspace_placeholder: Keine - title_edit: '{{name}} bearbeiten' - title_create: '{{name}} erstellen' - title_readonly: '{{name}} ansehen' - ok_edit: Aktualisieren - ok_create: Erstellen - ok_readonly: Als neu bearbeiten - options_label: Zusätzliche Optionen - options: - float: Schwebend - unmanage: Nicht verwalten - force: Verwaltung erzwingen - pinned: Angeheftet - identifier: - remove: Block löschen - id: Identifikator - kind: Identifizieren nach - matching_strategy: Abgleichstrategie - negation: Abgleich negieren - and: UND - or: ODER - add_block: Block hinzufügen -extras: - version: Version - links: Offizielle Links - github: GitHub - discord: Discord - relaunch: Neu starten - exit: Beenden/Verlassen -shortcuts: - enable: Integrierte Kurzbefehle (ahk) aktivieren - enable_tooltip: >- - Deaktivieren, wenn du deine eigenen Kurzbefehle mit der Seelen Core API - implementierst - labels: - reserve_top: Oben reservieren - reserve_bottom: Unten reservieren - reserve_left: Links reservieren - reserve_right: Rechts reservieren - reserve_float: Schwebend reservieren - reserve_stack: Stapel reservieren - focus_top: Oben fokussieren - focus_bottom: Unten fokussieren - focus_left: Links fokussieren - focus_right: Rechts fokussieren - focus_latest: Letztes fokussieren - increase_width: Breite vergrößern - decrease_width: Breite verkleinern - increase_height: Höhe vergrößern - decrease_height: Höhe verkleinern - restore_sizes: Größen wiederherstellen - switch_workspace_0: Zum Arbeitsbereich 0 wechseln - switch_workspace_1: Zum Arbeitsbereich 1 wechseln - switch_workspace_2: Zum Arbeitsbereich 2 wechseln - switch_workspace_3: Zum Arbeitsbereich 3 wechseln - switch_workspace_4: Zum Arbeitsbereich 4 wechseln - switch_workspace_5: Zum Arbeitsbereich 5 wechseln - switch_workspace_6: Zum Arbeitsbereich 6 wechseln - switch_workspace_7: Zum Arbeitsbereich 7 wechseln - switch_workspace_8: Zum Arbeitsbereich 8 wechseln - switch_workspace_9: Zum Arbeitsbereich 9 wechseln - move_to_workspace_0: Zum Arbeitsbereich 0 verschieben - move_to_workspace_1: Zum Arbeitsbereich 1 verschieben - move_to_workspace_2: Zum Arbeitsbereich 2 verschieben - move_to_workspace_3: Zum Arbeitsbereich 3 verschieben - move_to_workspace_4: Zum Arbeitsbereich 4 verschieben - move_to_workspace_5: Zum Arbeitsbereich 5 verschieben - move_to_workspace_6: Zum Arbeitsbereich 6 verschieben - move_to_workspace_7: Zum Arbeitsbereich 7 verschieben - move_to_workspace_8: Zum Arbeitsbereich 8 verschieben - move_to_workspace_9: Zum Arbeitsbereich 9 verschieben - send_to_workspace_0: Zum Arbeitsbereich 0 senden - send_to_workspace_1: Zum Arbeitsbereich 1 senden - send_to_workspace_2: Zum Arbeitsbereich 2 senden - send_to_workspace_3: Zum Arbeitsbereich 3 senden - send_to_workspace_4: Zum Arbeitsbereich 4 senden - send_to_workspace_5: Zum Arbeitsbereich 5 senden - send_to_workspace_6: Zum Arbeitsbereich 6 senden - send_to_workspace_7: Zum Arbeitsbereich 7 senden - send_to_workspace_8: Zum Arbeitsbereich 8 senden - send_to_workspace_9: Zum Arbeitsbereich 9 senden +loading: Laden... +inProgress: In Bearbeitung... +cancel: Abbrechen +save: Speichern +quit: Beenden +open: Öffnen +delete: Löschen +sides: + left: Links + right: Rechts + top: Oben + bottom: Unten +header: + labels: + general: Allgemein + seelen_bar: Elegante Werkzeugleiste + seelen_wm: Fenstermanager + seelen_weg: Dock/Taskleiste + monitors: Monitore + specific_apps: Spezifische Apps + shortcuts: Kurzbefehle + developer: Entwickler + info: Information +start: + title: Willkommen! + message: >- + Willkommen bei Seelen UI, der ultimativen Desktop-Umgebung mit einem + integrierten Kachel-Fenstermanager, um dein Windows 11-Erlebnis zu + verbessern! Erkunde eine neue Ära der Effizienz und Multitasking mit unserer + intuitiven Oberfläche und fortschrittlichen Funktionen. + message_accent: Optimiere deine Produktivität mit Stil! +general: + startup: Beim Start ausführen? + language: Sprache + theme: + label: Themeninformation + placeholder: Thema auswählen + author: Autor + description: Beschreibung + add: Thema hinzufügen + added: Thema bereits hinzugefügt + enabled: Aktivierte Themen + tags: Tags + selected: Ausgewählt + available: Verfügbar + icon_pack: + label: Icon Packs + accent_color: Akzentfarbe +toolbar: + enable: Elegante Werkzeugleiste aktivieren + placeholder: + select: Struktur der Werkzeugleiste + author: Autor + description: Beschreibung + height: Höhe +wm: + enable: Fenstermanager aktivieren + disabled_windows10: Der Fenstermanager ist nicht für Windows 10 verfügbar. + layout: Layout + author: Autor + description: Beschreibung + space_between_containers: Abstand zwischen Containern + workspace_padding: Arbeitsbereichs-Padding + workspace_offset: Arbeitsbereichs-Versatz (Ränder) + resize_delta: Größenänderung Delta (%) + border: + enable: Fensterrand aktivieren + width: Randbreite + offset: Randversatz +weg: + label: Dock/Taskleiste + enable: Dock/Taskleiste aktivieren + width: Breite + auto_hide: Automatisch ausblenden + dock_side: Dock-Seite + padding: Polsterung + margin: Rand + gap: Abstand + items: + label: Elemente + size: Elementgröße + zoom_size: Vergrößerte Größe (für Themen verwendet) + gap: Abstand zwischen Elementen + visible_separators: Sichtbare Trennzeichen +devtools: + enable: Entwicklerwerkzeuge aktivieren + app_folders: Anwendungsordner + install_folder: Installationsordner + data_folder: Datenordner + settings_file: Einstellungsdatei + custom_config_file: Benutzerdefinierte Konfigurationsdatei laden + load: Laden +apps_configurations: + import: Importieren + export: Exportieren + delete: Löschen + swap: Tauschen + new: Neu + bundled_title: Mit Seelen gebündelte App-Konfiguration + bundled_msg: >- + Diese gebündelten Konfigurationen sind nicht bearbeitbar und wurden + entwickelt, um dir das beste Erlebnis ohne Anpassung zu bieten. Sie + konfigurieren die gebräuchlichsten Anwendungen automatisch für dich. + confirm_delete_title: Löschen bestätigen + confirm_delete: Möchtest du diese Konfiguration wirklich löschen? + search: Suchen + app: + name: Name + category: Kategorie + category_placeholder: Keine + bindings: Bindung (beide Optionen sind erforderlich) + monitor: Monitor + monitor_placeholder: Keine + workspace: Arbeitsbereich + workspace_placeholder: Keine + title_edit: '{{name}} bearbeiten' + title_create: '{{name}} erstellen' + title_readonly: '{{name}} ansehen' + ok_edit: Aktualisieren + ok_create: Erstellen + ok_readonly: Als neu bearbeiten + options_label: Zusätzliche Optionen + options: + float: Schwebend + unmanage: Nicht verwalten + force: Verwaltung erzwingen + pinned: Angeheftet + identifier: + remove: Block löschen + id: Identifikator + kind: Identifizieren nach + matching_strategy: Abgleichstrategie + negation: Abgleich negieren + and: UND + or: ODER + add_block: Block hinzufügen +extras: + version: Version + links: Offizielle Links + github: GitHub + discord: Discord + relaunch: Neu starten + exit: Beenden/Verlassen +shortcuts: + enable: Integrierte Kurzbefehle (ahk) aktivieren + enable_tooltip: >- + Deaktivieren, wenn du deine eigenen Kurzbefehle mit der Seelen Core API + implementierst + labels: + reserve_top: Oben reservieren + reserve_bottom: Unten reservieren + reserve_left: Links reservieren + reserve_right: Rechts reservieren + reserve_float: Schwebend reservieren + reserve_stack: Stapel reservieren + focus_top: Oben fokussieren + focus_bottom: Unten fokussieren + focus_left: Links fokussieren + focus_right: Rechts fokussieren + focus_latest: Letztes fokussieren + increase_width: Breite vergrößern + decrease_width: Breite verkleinern + increase_height: Höhe vergrößern + decrease_height: Höhe verkleinern + restore_sizes: Größen wiederherstellen + switch_workspace_0: Zum Arbeitsbereich 0 wechseln + switch_workspace_1: Zum Arbeitsbereich 1 wechseln + switch_workspace_2: Zum Arbeitsbereich 2 wechseln + switch_workspace_3: Zum Arbeitsbereich 3 wechseln + switch_workspace_4: Zum Arbeitsbereich 4 wechseln + switch_workspace_5: Zum Arbeitsbereich 5 wechseln + switch_workspace_6: Zum Arbeitsbereich 6 wechseln + switch_workspace_7: Zum Arbeitsbereich 7 wechseln + switch_workspace_8: Zum Arbeitsbereich 8 wechseln + switch_workspace_9: Zum Arbeitsbereich 9 wechseln + move_to_workspace_0: Zum Arbeitsbereich 0 verschieben + move_to_workspace_1: Zum Arbeitsbereich 1 verschieben + move_to_workspace_2: Zum Arbeitsbereich 2 verschieben + move_to_workspace_3: Zum Arbeitsbereich 3 verschieben + move_to_workspace_4: Zum Arbeitsbereich 4 verschieben + move_to_workspace_5: Zum Arbeitsbereich 5 verschieben + move_to_workspace_6: Zum Arbeitsbereich 6 verschieben + move_to_workspace_7: Zum Arbeitsbereich 7 verschieben + move_to_workspace_8: Zum Arbeitsbereich 8 verschieben + move_to_workspace_9: Zum Arbeitsbereich 9 verschieben + send_to_workspace_0: Zum Arbeitsbereich 0 senden + send_to_workspace_1: Zum Arbeitsbereich 1 senden + send_to_workspace_2: Zum Arbeitsbereich 2 senden + send_to_workspace_3: Zum Arbeitsbereich 3 senden + send_to_workspace_4: Zum Arbeitsbereich 4 senden + send_to_workspace_5: Zum Arbeitsbereich 5 senden + send_to_workspace_6: Zum Arbeitsbereich 6 senden + send_to_workspace_7: Zum Arbeitsbereich 7 senden + send_to_workspace_8: Zum Arbeitsbereich 8 senden + send_to_workspace_9: Zum Arbeitsbereich 9 senden diff --git a/src/apps/settings/i18n/translations/el.yml b/src/apps/settings/i18n/translations/el.yml index 0a592b73..3c68a94b 100644 --- a/src/apps/settings/i18n/translations/el.yml +++ b/src/apps/settings/i18n/translations/el.yml @@ -1,195 +1,195 @@ -sides: - left: Αριστερά - bottom: Κάτω μέρος - top: Μπλουζα - right: σωστά -header: - labels: - info: Πληροφορίες - general: Γενικός - monitors: Παρακολουθεί - developer: Προγραμματιστής - seelen_wm: Διαχειριστής παραθύρων - seelen_bar: Φανταχτερή γραμμή εργαλείων - shortcuts: Συντομεύσεις - specific_apps: Συγκεκριμένες εφαρμογές - seelen_weg: Λέσχη εργασιών -start: - message_accent: Βελτιστοποιήστε την παραγωγικότητά σας με στυλ! - title: Καλως ΗΡΘΑΤΕ! - message: >- - Καλώς ήλθατε στο Seelen UI, το Ultimate Desktop Environment με έναν - ενσωματωμένο διαχειριστή Windows για να βελτιώσετε την εμπειρία των Windows - 11! Εξερευνήστε μια νέα εποχή αποτελεσματικότητας και πολλαπλών εργασιών με - την διαισθητική διεπαφή και τα προηγμένα χαρακτηριστικά μας. -general: - theme: - placeholder: Επέλεξε θέμα - author: Συγγραφέας - description: Περιγραφή - add: Προσθέστε θέμα - label: Πληροφορίες θεμάτων - tags: Ετικέτες - enabled: Ενεργοποιημένα θέματα - added: Το θέμα έχει ήδη προστεθεί - available: Διαθέσιμος - selected: Επιλεγμένος - language: Γλώσσα - startup: Εκτέλεση κατά την εκκίνηση; - icon_pack: - label: Εικονίδια - accent_color: Έμφαση στο χρώμα -toolbar: - placeholder: - select: Δομή γραμμής εργαλείων - author: Συγγραφέας - description: Περιγραφή - height: Υψος - enable: Ενεργοποίηση φανταχτερά εργαλεία εργαλείων -wm: - border: - offset: Μετατόπιση των συνόρων - width: Πλάτος συνόρων - enable: Ενεργοποιήστε τα σύνορα του παραθύρου - description: Περιγραφή - author: Συγγραφέας - disabled_windows10: Ο διαχειριστής παραθύρων δεν είναι διαθέσιμος για τα Windows 10. - layout: Διάταξη - workspace_padding: Πλατύφυλλα - enable: Ενεργοποίηση διαχειριστή παραθύρων - workspace_offset: Μετατόπιση χώρων εργασίας (περιθώρια) - space_between_containers: Χώρος μεταξύ των εμπορευματοκιβωτίων - resize_delta: Αλλαγή μεγέθους Delta (%) -weg: - items: - size: Μέγεθος αντικειμένου - visible_separators: Ορατοί διαχωριστές - label: Αντικείμενα - zoom_size: Μέγεθος μεγέθυνσης (χρησιμοποιείται για θέματα) - gap: Χώρος μεταξύ αντικειμένων - width: Πλάτος - padding: Υλικό παραγεμίσματος - margin: Περιθώριο - gap: Χάσμα - auto_hide: Αυτόματη απόκρυψη - label: Λέσχη εργασιών - enable: Ενεργοποίηση λίστα/γραμμή εργασιών - dock_side: Πλευρά αποβάθρας -devtools: - data_folder: Φάκελος δεδομένων - custom_config_file: Φόρτωση προσαρμοσμένου αρχείου ρυθμίσεων - app_folders: Φακέλους εφαρμογών - load: Φορτώνω - enable: Ενεργοποίηση εργαλείων προγραμματιστή - settings_file: Αρχείο ρυθμίσεων - install_folder: Φάκελος εγκατάστασης -apps_configurations: - app: - options: - float: Φλοτέρ - pinned: Καρφωμένος - force: Διαχειριστείτε τη δύναμη - unmanage: Μη διαχείριση - title_readonly: Προβολή {{όνομα}} - options_label: Επιπλέον επιλογές - title_create: Δημιουργία {{name}} - bindings: Σύνδεση (σημειώστε ότι και οι δύο επιλογές απαιτούνται) - ok_readonly: Επεξεργαστείτε ως νέο - category_placeholder: Κανένας - monitor_placeholder: Κανένας - name: Ονομα - ok_create: Δημιουργώ - monitor: Οθόνη - category: Κατηγορία - ok_edit: Εκσυγχρονίζω - workspace_placeholder: Κανένας - workspace: Χώρος εργασίας - title_edit: Επεξεργασία {{όνομα}} - identifier: - or: Ή - id: Αναγνωριστικό - remove: Διαγραφή μπλοκ - add_block: Προσθέστε μπλοκ - matching_strategy: Στρατηγική αντιστοίχισης - and: ΚΑΙ - kind: Προσδιορίζω - negation: Αρνείστε την αντιστοίχιση - new: Νέος - search: Αναζήτηση - bundled_title: App config που συνδέεται με Seelen - export: Εξαγωγή - confirm_delete: Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν τη διαμόρφωση/s; - delete: Διαγράφω - swap: Ανταλαγή - import: Εισαγωγή - confirm_delete_title: Επιβεβαιώστε τη διαγραφή - bundled_msg: >- - Αυτές οι συνδεδεμένες διαμορφώσεις δεν είναι επεξεργάσιμες και έχουν - σχεδιαστεί για να σας παρέχουν την καλύτερη εμπειρία χωρίς προσαρμογή. - Διαμορφώνουν αυτόματα τις πιο συνηθισμένες εφαρμογές για εσάς. -extras: - relaunch: Ξεκίνησα ξανά - exit: Εγκατάλειψη/έξοδο - links: Επίσημοι σύνδεσμοι - discord: Διχόνοια - version: Εκδοχή - github: Github -shortcuts: - labels: - focus_latest: Επικεντρώνεται το τελευταίο - focus_left: Αριστερά - reserve_float: Επιφυλάκισμα - reserve_right: Διατηρήστε το δικαίωμα - switch_workspace_4: Μεταβείτε στο χώρο εργασίας 4 - switch_workspace_1: Μεταβείτε στο χώρο εργασίας 1 - reserve_bottom: Αποθεματικός - focus_bottom: Επικεντρωμένος κάτω - focus_top: Επικεντρώνεται στην κορυφή - move_to_workspace_5: Μετακίνηση στο χώρο εργασίας 5 - send_to_workspace_2: Αποστολή στο χώρο εργασίας 2 - switch_workspace_3: Μεταβείτε στο χώρο εργασίας 3 - move_to_workspace_1: Μετακίνηση στο χώρο εργασίας 1 - reserve_top: Επιφυλάξτε την κορυφή - reserve_left: Αποθεματικό αριστερά - switch_workspace_7: Μεταβείτε στο χώρο εργασίας 7 - switch_workspace_0: Μεταβείτε στο χώρο εργασίας 0 - send_to_workspace_6: Αποστολή στο χώρο εργασίας 6 - increase_height: Ύψος αύξησης - send_to_workspace_8: Αποστολή στο χώρο εργασίας 8 - increase_width: Αύξηση πλάτους - switch_workspace_2: Μεταβείτε στο χώρο εργασίας 2 - switch_workspace_8: Μεταβείτε στο χώρο εργασίας 8 - focus_right: Εστίαση σωστά - move_to_workspace_6: Μετακίνηση στο χώρο εργασίας 6 - move_to_workspace_4: Μετακίνηση στο χώρο εργασίας 4 - move_to_workspace_9: Μετακίνηση στο χώρο εργασίας 9 - switch_workspace_9: Μεταβείτε στο χώρο εργασίας 9 - switch_workspace_6: Μεταβείτε στο χώρο εργασίας 6 - restore_sizes: Επαναφορά μεγέθους - send_to_workspace_3: Αποστολή στο χώρο εργασίας 3 - switch_workspace_5: Μεταβείτε στο χώρο εργασίας 5 - reserve_stack: Επιφυλάκιση - move_to_workspace_8: Μετακίνηση στο χώρο εργασίας 8 - move_to_workspace_2: Μετακίνηση στο χώρο εργασίας 2 - send_to_workspace_5: Αποστολή στο χώρο εργασίας 5 - send_to_workspace_1: Αποστολή στο χώρο εργασίας 1 - send_to_workspace_7: Αποστολή στο χώρο εργασίας 7 - move_to_workspace_3: Μετακίνηση στο χώρο εργασίας 3 - decrease_height: Μείωση του ύψους - decrease_width: Μείωση του πλάτους - move_to_workspace_7: Μετακίνηση στο χώρο εργασίας 7 - send_to_workspace_4: Αποστολή στο χώρο εργασίας 4 - send_to_workspace_0: Αποστολή στο χώρο εργασίας 0 - send_to_workspace_9: Αποστολή στο χώρο εργασίας 9 - move_to_workspace_0: Μετακίνηση στο χώρο εργασίας 0 - enable: Ενεργοποίηση ολοκληρωμένων συντομεύσεων (AHK) - enable_tooltip: >- - Απενεργοποιήστε εάν θα εφαρμόσετε τις δικές σας συντομεύσεις χρησιμοποιώντας - το API Seelen Core -loading: Φόρτωση... -inProgress: Σε εξέλιξη... -cancel: Ματαίωση -delete: Διαγράφω -quit: Εγκαταλείπω -save: Αποθηκεύσετε -open: Ανοιξε +sides: + left: Αριστερά + bottom: Κάτω μέρος + top: Μπλουζα + right: σωστά +header: + labels: + info: Πληροφορίες + general: Γενικός + monitors: Παρακολουθεί + developer: Προγραμματιστής + seelen_wm: Διαχειριστής παραθύρων + seelen_bar: Φανταχτερή γραμμή εργαλείων + shortcuts: Συντομεύσεις + specific_apps: Συγκεκριμένες εφαρμογές + seelen_weg: Λέσχη εργασιών +start: + message_accent: Βελτιστοποιήστε την παραγωγικότητά σας με στυλ! + title: Καλως ΗΡΘΑΤΕ! + message: >- + Καλώς ήλθατε στο Seelen UI, το Ultimate Desktop Environment με έναν + ενσωματωμένο διαχειριστή Windows για να βελτιώσετε την εμπειρία των Windows + 11! Εξερευνήστε μια νέα εποχή αποτελεσματικότητας και πολλαπλών εργασιών με + την διαισθητική διεπαφή και τα προηγμένα χαρακτηριστικά μας. +general: + theme: + placeholder: Επέλεξε θέμα + author: Συγγραφέας + description: Περιγραφή + add: Προσθέστε θέμα + label: Πληροφορίες θεμάτων + tags: Ετικέτες + enabled: Ενεργοποιημένα θέματα + added: Το θέμα έχει ήδη προστεθεί + available: Διαθέσιμος + selected: Επιλεγμένος + language: Γλώσσα + startup: Εκτέλεση κατά την εκκίνηση; + icon_pack: + label: Εικονίδια + accent_color: Έμφαση στο χρώμα +toolbar: + placeholder: + select: Δομή γραμμής εργαλείων + author: Συγγραφέας + description: Περιγραφή + height: Υψος + enable: Ενεργοποίηση φανταχτερά εργαλεία εργαλείων +wm: + border: + offset: Μετατόπιση των συνόρων + width: Πλάτος συνόρων + enable: Ενεργοποιήστε τα σύνορα του παραθύρου + description: Περιγραφή + author: Συγγραφέας + disabled_windows10: Ο διαχειριστής παραθύρων δεν είναι διαθέσιμος για τα Windows 10. + layout: Διάταξη + workspace_padding: Πλατύφυλλα + enable: Ενεργοποίηση διαχειριστή παραθύρων + workspace_offset: Μετατόπιση χώρων εργασίας (περιθώρια) + space_between_containers: Χώρος μεταξύ των εμπορευματοκιβωτίων + resize_delta: Αλλαγή μεγέθους Delta (%) +weg: + items: + size: Μέγεθος αντικειμένου + visible_separators: Ορατοί διαχωριστές + label: Αντικείμενα + zoom_size: Μέγεθος μεγέθυνσης (χρησιμοποιείται για θέματα) + gap: Χώρος μεταξύ αντικειμένων + width: Πλάτος + padding: Υλικό παραγεμίσματος + margin: Περιθώριο + gap: Χάσμα + auto_hide: Αυτόματη απόκρυψη + label: Λέσχη εργασιών + enable: Ενεργοποίηση λίστα/γραμμή εργασιών + dock_side: Πλευρά αποβάθρας +devtools: + data_folder: Φάκελος δεδομένων + custom_config_file: Φόρτωση προσαρμοσμένου αρχείου ρυθμίσεων + app_folders: Φακέλους εφαρμογών + load: Φορτώνω + enable: Ενεργοποίηση εργαλείων προγραμματιστή + settings_file: Αρχείο ρυθμίσεων + install_folder: Φάκελος εγκατάστασης +apps_configurations: + app: + options: + float: Φλοτέρ + pinned: Καρφωμένος + force: Διαχειριστείτε τη δύναμη + unmanage: Μη διαχείριση + title_readonly: Προβολή {{όνομα}} + options_label: Επιπλέον επιλογές + title_create: Δημιουργία {{name}} + bindings: Σύνδεση (σημειώστε ότι και οι δύο επιλογές απαιτούνται) + ok_readonly: Επεξεργαστείτε ως νέο + category_placeholder: Κανένας + monitor_placeholder: Κανένας + name: Ονομα + ok_create: Δημιουργώ + monitor: Οθόνη + category: Κατηγορία + ok_edit: Εκσυγχρονίζω + workspace_placeholder: Κανένας + workspace: Χώρος εργασίας + title_edit: Επεξεργασία {{όνομα}} + identifier: + or: Ή + id: Αναγνωριστικό + remove: Διαγραφή μπλοκ + add_block: Προσθέστε μπλοκ + matching_strategy: Στρατηγική αντιστοίχισης + and: ΚΑΙ + kind: Προσδιορίζω + negation: Αρνείστε την αντιστοίχιση + new: Νέος + search: Αναζήτηση + bundled_title: App config που συνδέεται με Seelen + export: Εξαγωγή + confirm_delete: Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν τη διαμόρφωση/s; + delete: Διαγράφω + swap: Ανταλαγή + import: Εισαγωγή + confirm_delete_title: Επιβεβαιώστε τη διαγραφή + bundled_msg: >- + Αυτές οι συνδεδεμένες διαμορφώσεις δεν είναι επεξεργάσιμες και έχουν + σχεδιαστεί για να σας παρέχουν την καλύτερη εμπειρία χωρίς προσαρμογή. + Διαμορφώνουν αυτόματα τις πιο συνηθισμένες εφαρμογές για εσάς. +extras: + relaunch: Ξεκίνησα ξανά + exit: Εγκατάλειψη/έξοδο + links: Επίσημοι σύνδεσμοι + discord: Διχόνοια + version: Εκδοχή + github: Github +shortcuts: + labels: + focus_latest: Επικεντρώνεται το τελευταίο + focus_left: Αριστερά + reserve_float: Επιφυλάκισμα + reserve_right: Διατηρήστε το δικαίωμα + switch_workspace_4: Μεταβείτε στο χώρο εργασίας 4 + switch_workspace_1: Μεταβείτε στο χώρο εργασίας 1 + reserve_bottom: Αποθεματικός + focus_bottom: Επικεντρωμένος κάτω + focus_top: Επικεντρώνεται στην κορυφή + move_to_workspace_5: Μετακίνηση στο χώρο εργασίας 5 + send_to_workspace_2: Αποστολή στο χώρο εργασίας 2 + switch_workspace_3: Μεταβείτε στο χώρο εργασίας 3 + move_to_workspace_1: Μετακίνηση στο χώρο εργασίας 1 + reserve_top: Επιφυλάξτε την κορυφή + reserve_left: Αποθεματικό αριστερά + switch_workspace_7: Μεταβείτε στο χώρο εργασίας 7 + switch_workspace_0: Μεταβείτε στο χώρο εργασίας 0 + send_to_workspace_6: Αποστολή στο χώρο εργασίας 6 + increase_height: Ύψος αύξησης + send_to_workspace_8: Αποστολή στο χώρο εργασίας 8 + increase_width: Αύξηση πλάτους + switch_workspace_2: Μεταβείτε στο χώρο εργασίας 2 + switch_workspace_8: Μεταβείτε στο χώρο εργασίας 8 + focus_right: Εστίαση σωστά + move_to_workspace_6: Μετακίνηση στο χώρο εργασίας 6 + move_to_workspace_4: Μετακίνηση στο χώρο εργασίας 4 + move_to_workspace_9: Μετακίνηση στο χώρο εργασίας 9 + switch_workspace_9: Μεταβείτε στο χώρο εργασίας 9 + switch_workspace_6: Μεταβείτε στο χώρο εργασίας 6 + restore_sizes: Επαναφορά μεγέθους + send_to_workspace_3: Αποστολή στο χώρο εργασίας 3 + switch_workspace_5: Μεταβείτε στο χώρο εργασίας 5 + reserve_stack: Επιφυλάκιση + move_to_workspace_8: Μετακίνηση στο χώρο εργασίας 8 + move_to_workspace_2: Μετακίνηση στο χώρο εργασίας 2 + send_to_workspace_5: Αποστολή στο χώρο εργασίας 5 + send_to_workspace_1: Αποστολή στο χώρο εργασίας 1 + send_to_workspace_7: Αποστολή στο χώρο εργασίας 7 + move_to_workspace_3: Μετακίνηση στο χώρο εργασίας 3 + decrease_height: Μείωση του ύψους + decrease_width: Μείωση του πλάτους + move_to_workspace_7: Μετακίνηση στο χώρο εργασίας 7 + send_to_workspace_4: Αποστολή στο χώρο εργασίας 4 + send_to_workspace_0: Αποστολή στο χώρο εργασίας 0 + send_to_workspace_9: Αποστολή στο χώρο εργασίας 9 + move_to_workspace_0: Μετακίνηση στο χώρο εργασίας 0 + enable: Ενεργοποίηση ολοκληρωμένων συντομεύσεων (AHK) + enable_tooltip: >- + Απενεργοποιήστε εάν θα εφαρμόσετε τις δικές σας συντομεύσεις χρησιμοποιώντας + το API Seelen Core +loading: Φόρτωση... +inProgress: Σε εξέλιξη... +cancel: Ματαίωση +delete: Διαγράφω +quit: Εγκαταλείπω +save: Αποθηκεύσετε +open: Ανοιξε diff --git a/src/apps/settings/i18n/translations/en.yml b/src/apps/settings/i18n/translations/en.yml index 5afdb97d..6bb65eef 100644 --- a/src/apps/settings/i18n/translations/en.yml +++ b/src/apps/settings/i18n/translations/en.yml @@ -1,193 +1,193 @@ -loading: Loading... -inProgress: In Progress... -cancel: Cancel -save: Save -quit: Quit -open: Open -delete: Delete -sides: - left: Left - right: Right - top: Top - bottom: Bottom -header: - labels: - general: General - seelen_bar: Fancy Toolbar - seelen_wm: Window Manager - seelen_weg: Dock/Taskbar - monitors: Monitors - specific_apps: Specific Apps - shortcuts: Shortcuts - developer: Developer - info: Information -start: - title: Welcome! - message: >- - Welcome to Seelen UI, the ultimate Desktop Environment with an incorporated tiling windows manager - to enhance your Windows 11 experience! Explore a new era of efficiency and multitasking with our - intuitive interface and advanced features. - message_accent: Optimize your productivity with style! -general: - startup: Run on startup? - language: Language - theme: - label: Themes - placeholder: Select theme - author: Author - description: Description - add: Add theme - added: Theme already added - enabled: Enabled Themes - tags: Tags - available: Available - selected: Selected - icon_pack: - label: Icon Packs - wallpaper: - select: Select Wallpaper - accent_color: Accent Color -toolbar: - enable: Enable Fancy Toolbar - placeholder: - select: Toolbar Structure - author: Author - description: Description - height: Height -wm: - enable: Enable Window Manager - disabled_windows10: The Window Manager is not available for Windows 10. - layout: Layout - author: Author - description: Description - space_between_containers: Space Between Containers - workspace_padding: Workspaces Padding - workspace_offset: Workspaces Offset (Margins) - resize_delta: Resize Delta (%) - border: - enable: Enable Window's Border - width: Border Width - offset: Border Offset -weg: - label: Dock/Taskbar - enable: Enable Dock/Taskbar - width: Width - auto_hide: Auto Hide - dock_side: Dock Side - padding: Padding - margin: Margin - gap: Gap - items: - label: Items - size: Item Size - zoom_size: Zoomed Size (used for themes) - gap: Space Between Items - visible_separators: Visible Separators -devtools: - enable: Enable Developer Tools - app_folders: App Folders - install_folder: Installation Folder - data_folder: Data Folder - settings_file: Settings File - custom_config_file: Load Custom Config File - load: Load -apps_configurations: - import: Import - export: Export - delete: Delete - swap: Swap - new: New - bundled_title: App Config Bundled with Seelen - bundled_msg: >- - These bundled configurations are not editable and are designed to provide you with the best - experience without customization. They automatically configure the most common applications for you. - confirm_delete_title: Confirm Delete - confirm_delete: Are you sure you want to delete this configuration/s? - search: Search - app: - name: Name - category: Category - category_placeholder: None - bindings: Binding (note both options are required) - monitor: Monitor - monitor_placeholder: None - workspace: Workspace - workspace_placeholder: None - title_edit: Editting {{name}} - title_create: Creating {{name}} - title_readonly: Viewing {{name}} - ok_edit: Update - ok_create: Create - ok_readonly: Edit as New - options_label: Extra Options - options: - float: Float - unmanage: Unmanage - force: Force Manage - pinned: Pinned - identifier: - remove: Delete Block - id: Identifier - kind: Identify By - matching_strategy: Matching Strategy - negation: Negate Matching - and: AND - or: OR - add_block: Add Block -extras: - version: Version - links: Official Links - github: GitHub - discord: Discord - relaunch: Relaunch - exit: Quit/Exit -shortcuts: - enable: Enable Integrated Shortcuts (ahk) - enable_tooltip: Disable if you will implement your own shortcuts using the Seelen Core Api - labels: - reserve_top: Reserve Top - reserve_bottom: Reserve Bottom - reserve_left: Reserve Left - reserve_right: Reserve Right - reserve_float: Reserve Float - reserve_stack: Reserve Stack - focus_top: Focus Top - focus_bottom: Focus Bottom - focus_left: Focus Left - focus_right: Focus Right - focus_latest: Focus Latest - increase_width: Increase Width - decrease_width: Decrease Width - increase_height: Increase Height - decrease_height: Decrease Height - restore_sizes: Restore Sizes - switch_workspace_0: Switch to Workspace 0 - switch_workspace_1: Switch to Workspace 1 - switch_workspace_2: Switch to Workspace 2 - switch_workspace_3: Switch to Workspace 3 - switch_workspace_4: Switch to Workspace 4 - switch_workspace_5: Switch to Workspace 5 - switch_workspace_6: Switch to Workspace 6 - switch_workspace_7: Switch to Workspace 7 - switch_workspace_8: Switch to Workspace 8 - switch_workspace_9: Switch to Workspace 9 - move_to_workspace_0: Move to Workspace 0 - move_to_workspace_1: Move to Workspace 1 - move_to_workspace_2: Move to Workspace 2 - move_to_workspace_3: Move to Workspace 3 - move_to_workspace_4: Move to Workspace 4 - move_to_workspace_5: Move to Workspace 5 - move_to_workspace_6: Move to Workspace 6 - move_to_workspace_7: Move to Workspace 7 - move_to_workspace_8: Move to Workspace 8 - move_to_workspace_9: Move to Workspace 9 - send_to_workspace_0: Send to Workspace 0 - send_to_workspace_1: Send to Workspace 1 - send_to_workspace_2: Send to Workspace 2 - send_to_workspace_3: Send to Workspace 3 - send_to_workspace_4: Send to Workspace 4 - send_to_workspace_5: Send to Workspace 5 - send_to_workspace_6: Send to Workspace 6 - send_to_workspace_7: Send to Workspace 7 - send_to_workspace_8: Send to Workspace 8 - send_to_workspace_9: Send to Workspace 9 +loading: Loading... +inProgress: In Progress... +cancel: Cancel +save: Save +quit: Quit +open: Open +delete: Delete +sides: + left: Left + right: Right + top: Top + bottom: Bottom +header: + labels: + general: General + seelen_bar: Fancy Toolbar + seelen_wm: Window Manager + seelen_weg: Dock/Taskbar + monitors: Monitors + specific_apps: Specific Apps + shortcuts: Shortcuts + developer: Developer + info: Information +start: + title: Welcome! + message: >- + Welcome to Seelen UI, the ultimate Desktop Environment with an incorporated tiling windows manager + to enhance your Windows 11 experience! Explore a new era of efficiency and multitasking with our + intuitive interface and advanced features. + message_accent: Optimize your productivity with style! +general: + startup: Run on startup? + language: Language + theme: + label: Themes + placeholder: Select theme + author: Author + description: Description + add: Add theme + added: Theme already added + enabled: Enabled Themes + tags: Tags + available: Available + selected: Selected + icon_pack: + label: Icon Packs + wallpaper: + select: Select Wallpaper + accent_color: Accent Color +toolbar: + enable: Enable Fancy Toolbar + placeholder: + select: Toolbar Structure + author: Author + description: Description + height: Height +wm: + enable: Enable Window Manager + disabled_windows10: The Window Manager is not available for Windows 10. + layout: Layout + author: Author + description: Description + space_between_containers: Space Between Containers + workspace_padding: Workspaces Padding + workspace_offset: Workspaces Offset (Margins) + resize_delta: Resize Delta (%) + border: + enable: Enable Window's Border + width: Border Width + offset: Border Offset +weg: + label: Dock/Taskbar + enable: Enable Dock/Taskbar + width: Width + auto_hide: Auto Hide + dock_side: Dock Side + padding: Padding + margin: Margin + gap: Gap + items: + label: Items + size: Item Size + zoom_size: Zoomed Size (used for themes) + gap: Space Between Items + visible_separators: Visible Separators +devtools: + enable: Enable Developer Tools + app_folders: App Folders + install_folder: Installation Folder + data_folder: Data Folder + settings_file: Settings File + custom_config_file: Load Custom Config File + load: Load +apps_configurations: + import: Import + export: Export + delete: Delete + swap: Swap + new: New + bundled_title: App Config Bundled with Seelen + bundled_msg: >- + These bundled configurations are not editable and are designed to provide you with the best + experience without customization. They automatically configure the most common applications for you. + confirm_delete_title: Confirm Delete + confirm_delete: Are you sure you want to delete this configuration/s? + search: Search + app: + name: Name + category: Category + category_placeholder: None + bindings: Binding (note both options are required) + monitor: Monitor + monitor_placeholder: None + workspace: Workspace + workspace_placeholder: None + title_edit: Editting {{name}} + title_create: Creating {{name}} + title_readonly: Viewing {{name}} + ok_edit: Update + ok_create: Create + ok_readonly: Edit as New + options_label: Extra Options + options: + float: Float + unmanage: Unmanage + force: Force Manage + pinned: Pinned + identifier: + remove: Delete Block + id: Identifier + kind: Identify By + matching_strategy: Matching Strategy + negation: Negate Matching + and: AND + or: OR + add_block: Add Block +extras: + version: Version + links: Official Links + github: GitHub + discord: Discord + relaunch: Relaunch + exit: Quit/Exit +shortcuts: + enable: Enable Integrated Shortcuts (ahk) + enable_tooltip: Disable if you will implement your own shortcuts using the Seelen Core Api + labels: + reserve_top: Reserve Top + reserve_bottom: Reserve Bottom + reserve_left: Reserve Left + reserve_right: Reserve Right + reserve_float: Reserve Float + reserve_stack: Reserve Stack + focus_top: Focus Top + focus_bottom: Focus Bottom + focus_left: Focus Left + focus_right: Focus Right + focus_latest: Focus Latest + increase_width: Increase Width + decrease_width: Decrease Width + increase_height: Increase Height + decrease_height: Decrease Height + restore_sizes: Restore Sizes + switch_workspace_0: Switch to Workspace 0 + switch_workspace_1: Switch to Workspace 1 + switch_workspace_2: Switch to Workspace 2 + switch_workspace_3: Switch to Workspace 3 + switch_workspace_4: Switch to Workspace 4 + switch_workspace_5: Switch to Workspace 5 + switch_workspace_6: Switch to Workspace 6 + switch_workspace_7: Switch to Workspace 7 + switch_workspace_8: Switch to Workspace 8 + switch_workspace_9: Switch to Workspace 9 + move_to_workspace_0: Move to Workspace 0 + move_to_workspace_1: Move to Workspace 1 + move_to_workspace_2: Move to Workspace 2 + move_to_workspace_3: Move to Workspace 3 + move_to_workspace_4: Move to Workspace 4 + move_to_workspace_5: Move to Workspace 5 + move_to_workspace_6: Move to Workspace 6 + move_to_workspace_7: Move to Workspace 7 + move_to_workspace_8: Move to Workspace 8 + move_to_workspace_9: Move to Workspace 9 + send_to_workspace_0: Send to Workspace 0 + send_to_workspace_1: Send to Workspace 1 + send_to_workspace_2: Send to Workspace 2 + send_to_workspace_3: Send to Workspace 3 + send_to_workspace_4: Send to Workspace 4 + send_to_workspace_5: Send to Workspace 5 + send_to_workspace_6: Send to Workspace 6 + send_to_workspace_7: Send to Workspace 7 + send_to_workspace_8: Send to Workspace 8 + send_to_workspace_9: Send to Workspace 9 diff --git a/src/apps/settings/i18n/translations/es.yml b/src/apps/settings/i18n/translations/es.yml index 2e06cea8..e74616b7 100644 --- a/src/apps/settings/i18n/translations/es.yml +++ b/src/apps/settings/i18n/translations/es.yml @@ -1,195 +1,195 @@ -loading: Cargando... -inProgress: En progreso... -cancel: Cancelar -save: Guardar -quit: Salir -open: Abrir -delete: Eliminar -sides: - left: Izquierda - right: Derecha - top: Arriba - bottom: Abajo -header: - labels: - general: General - seelen_bar: Barra elegante - seelen_wm: Gestor de ventanas - seelen_weg: Dock/Barra de tareas - monitors: Monitores - specific_apps: Aplicaciones específicas - shortcuts: Atajos - developer: Desarrollador - info: Información -start: - title: ¡Bienvenido! - message: >- - ¡Bienvenido a Seelen UI, el entorno de escritorio definitivo con un gestor - de ventanas en mosaico incorporado para mejorar tu experiencia en Windows - 11! Explora una nueva era de eficiencia y multitarea con nuestra interfaz - intuitiva y funciones avanzadas. - message_accent: ¡Optimiza tu productividad con estilo! -general: - startup: ¿Ejecutar al inicio? - language: Idioma - theme: - label: Información del tema - placeholder: Selecciona un tema - author: Autor - description: Descripción - add: Agregar tema - added: Tema ya agregado - enabled: Temas habilitados - tags: Etiquetas - available: Disponible - selected: Seleccionada - icon_pack: - label: Paquetes de iconos - accent_color: Acentuar el color -toolbar: - enable: Habilitar barra elegante - placeholder: - select: Estructura de la barra - author: Autor - description: Descripción - height: Altura -wm: - enable: Habilitar gestor de ventanas - disabled_windows10: El gestor de ventanas no está disponible para Windows 10. - layout: Distribución - author: Autor - description: Descripción - space_between_containers: Espacio entre contenedores - workspace_padding: Relleno de espacios de trabajo - workspace_offset: Desplazamiento de espacios de trabajo (Márgenes) - resize_delta: Delta de redimensionamiento (%) - border: - enable: Habilitar borde de ventana - width: Ancho del borde - offset: Desplazamiento del borde -weg: - label: Dock/Barra de tareas - enable: Habilitar dock/barra de tareas - width: Ancho - auto_hide: Ocultar automáticamente - dock_side: Lado del dock - padding: Relleno - margin: Margen - gap: Espacio - items: - label: Elementos - size: Tamaño del elemento - zoom_size: Tamaño ampliado (usado para temas) - gap: Espacio entre elementos - visible_separators: Separadores visibles -devtools: - enable: Habilitar herramientas de desarrollador - app_folders: Carpetas de aplicaciones - install_folder: Carpeta de instalación - data_folder: Carpeta de datos - settings_file: Archivo de configuración - custom_config_file: Cargar archivo de configuración personalizado - load: Cargar -apps_configurations: - import: Importar - export: Exportar - delete: Eliminar - swap: Intercambiar - new: Nuevo - bundled_title: Configuración de la aplicación incluida con Seelen - bundled_msg: >- - Estas configuraciones incluidas no son editables y están diseñadas para - proporcionarte la mejor experiencia sin personalización. Configuran - automáticamente las aplicaciones más comunes para ti. - confirm_delete_title: Confirmar eliminación - confirm_delete: ¿Estás seguro de que deseas eliminar esta configuración? - search: Buscar - app: - name: Nombre - category: Categoría - category_placeholder: Ninguna - bindings: Vinculación (nota, se requieren ambas opciones) - monitor: Monitor - monitor_placeholder: Ninguno - workspace: Espacio de trabajo - workspace_placeholder: Ninguno - title_edit: Editando {{name}} - title_create: Creando {{name}} - title_readonly: Viendo {{name}} - ok_edit: Actualizar - ok_create: Crear - ok_readonly: Editar como nuevo - options_label: Opciones adicionales - options: - float: Flotar - unmanage: No gestionar - force: Forzar gestión - pinned: Fijado - identifier: - remove: Eliminar bloque - id: Identificador - kind: Identificar por - matching_strategy: Estrategia de coincidencia - negation: Negar coincidencia - and: Y (AND) - or: O (OR) - add_block: Agregar bloque -extras: - version: Versión - links: Enlaces oficiales - github: GitHub - discord: Discord - relaunch: Reiniciar - exit: Salir/Salir -shortcuts: - enable: Habilitar atajos integrados (ahk) - enable_tooltip: >- - Desactiva si vas a implementar tus propios atajos usando la API de Seelen - Core - labels: - reserve_top: Reservar arriba - reserve_bottom: Reservar abajo - reserve_left: Reservar izquierda - reserve_right: Reservar derecha - reserve_float: Reservar flotar - reserve_stack: Reservar pila - focus_top: Enfocar arriba - focus_bottom: Enfocar abajo - focus_left: Enfocar izquierda - focus_right: Enfocar derecha - focus_latest: Enfocar último - increase_width: Aumentar ancho - decrease_width: Disminuir ancho - increase_height: Aumentar altura - decrease_height: Disminuir altura - restore_sizes: Restaurar tamaños - switch_workspace_0: Cambiar al espacio de trabajo 0 - switch_workspace_1: Cambiar al espacio de trabajo 1 - switch_workspace_2: Cambiar al espacio de trabajo 2 - switch_workspace_3: Cambiar al espacio de trabajo 3 - switch_workspace_4: Cambiar al espacio de trabajo 4 - switch_workspace_5: Cambiar al espacio de trabajo 5 - switch_workspace_6: Cambiar al espacio de trabajo 6 - switch_workspace_7: Cambiar al espacio de trabajo 7 - switch_workspace_8: Cambiar al espacio de trabajo 8 - switch_workspace_9: Cambiar al espacio de trabajo 9 - move_to_workspace_0: Mover al espacio de trabajo 0 - move_to_workspace_1: Mover al espacio de trabajo 1 - move_to_workspace_2: Mover al espacio de trabajo 2 - move_to_workspace_3: Mover al espacio de trabajo 3 - move_to_workspace_4: Mover al espacio de trabajo 4 - move_to_workspace_5: Mover al espacio de trabajo 5 - move_to_workspace_6: Mover al espacio de trabajo 6 - move_to_workspace_7: Mover al espacio de trabajo 7 - move_to_workspace_8: Mover al espacio de trabajo 8 - move_to_workspace_9: Mover al espacio de trabajo 9 - send_to_workspace_0: Enviar al espacio de trabajo 0 - send_to_workspace_1: Enviar al espacio de trabajo 1 - send_to_workspace_2: Enviar al espacio de trabajo 2 - send_to_workspace_3: Enviar al espacio de trabajo 3 - send_to_workspace_4: Enviar al espacio de trabajo 4 - send_to_workspace_5: Enviar al espacio de trabajo 5 - send_to_workspace_6: Enviar al espacio de trabajo 6 - send_to_workspace_7: Enviar al espacio de trabajo 7 - send_to_workspace_8: Enviar al espacio de trabajo 8 - send_to_workspace_9: Enviar al espacio de trabajo 9 +loading: Cargando... +inProgress: En progreso... +cancel: Cancelar +save: Guardar +quit: Salir +open: Abrir +delete: Eliminar +sides: + left: Izquierda + right: Derecha + top: Arriba + bottom: Abajo +header: + labels: + general: General + seelen_bar: Barra elegante + seelen_wm: Gestor de ventanas + seelen_weg: Dock/Barra de tareas + monitors: Monitores + specific_apps: Aplicaciones específicas + shortcuts: Atajos + developer: Desarrollador + info: Información +start: + title: ¡Bienvenido! + message: >- + ¡Bienvenido a Seelen UI, el entorno de escritorio definitivo con un gestor + de ventanas en mosaico incorporado para mejorar tu experiencia en Windows + 11! Explora una nueva era de eficiencia y multitarea con nuestra interfaz + intuitiva y funciones avanzadas. + message_accent: ¡Optimiza tu productividad con estilo! +general: + startup: ¿Ejecutar al inicio? + language: Idioma + theme: + label: Información del tema + placeholder: Selecciona un tema + author: Autor + description: Descripción + add: Agregar tema + added: Tema ya agregado + enabled: Temas habilitados + tags: Etiquetas + available: Disponible + selected: Seleccionada + icon_pack: + label: Paquetes de iconos + accent_color: Acentuar el color +toolbar: + enable: Habilitar barra elegante + placeholder: + select: Estructura de la barra + author: Autor + description: Descripción + height: Altura +wm: + enable: Habilitar gestor de ventanas + disabled_windows10: El gestor de ventanas no está disponible para Windows 10. + layout: Distribución + author: Autor + description: Descripción + space_between_containers: Espacio entre contenedores + workspace_padding: Relleno de espacios de trabajo + workspace_offset: Desplazamiento de espacios de trabajo (Márgenes) + resize_delta: Delta de redimensionamiento (%) + border: + enable: Habilitar borde de ventana + width: Ancho del borde + offset: Desplazamiento del borde +weg: + label: Dock/Barra de tareas + enable: Habilitar dock/barra de tareas + width: Ancho + auto_hide: Ocultar automáticamente + dock_side: Lado del dock + padding: Relleno + margin: Margen + gap: Espacio + items: + label: Elementos + size: Tamaño del elemento + zoom_size: Tamaño ampliado (usado para temas) + gap: Espacio entre elementos + visible_separators: Separadores visibles +devtools: + enable: Habilitar herramientas de desarrollador + app_folders: Carpetas de aplicaciones + install_folder: Carpeta de instalación + data_folder: Carpeta de datos + settings_file: Archivo de configuración + custom_config_file: Cargar archivo de configuración personalizado + load: Cargar +apps_configurations: + import: Importar + export: Exportar + delete: Eliminar + swap: Intercambiar + new: Nuevo + bundled_title: Configuración de la aplicación incluida con Seelen + bundled_msg: >- + Estas configuraciones incluidas no son editables y están diseñadas para + proporcionarte la mejor experiencia sin personalización. Configuran + automáticamente las aplicaciones más comunes para ti. + confirm_delete_title: Confirmar eliminación + confirm_delete: ¿Estás seguro de que deseas eliminar esta configuración? + search: Buscar + app: + name: Nombre + category: Categoría + category_placeholder: Ninguna + bindings: Vinculación (nota, se requieren ambas opciones) + monitor: Monitor + monitor_placeholder: Ninguno + workspace: Espacio de trabajo + workspace_placeholder: Ninguno + title_edit: Editando {{name}} + title_create: Creando {{name}} + title_readonly: Viendo {{name}} + ok_edit: Actualizar + ok_create: Crear + ok_readonly: Editar como nuevo + options_label: Opciones adicionales + options: + float: Flotar + unmanage: No gestionar + force: Forzar gestión + pinned: Fijado + identifier: + remove: Eliminar bloque + id: Identificador + kind: Identificar por + matching_strategy: Estrategia de coincidencia + negation: Negar coincidencia + and: Y (AND) + or: O (OR) + add_block: Agregar bloque +extras: + version: Versión + links: Enlaces oficiales + github: GitHub + discord: Discord + relaunch: Reiniciar + exit: Salir/Salir +shortcuts: + enable: Habilitar atajos integrados (ahk) + enable_tooltip: >- + Desactiva si vas a implementar tus propios atajos usando la API de Seelen + Core + labels: + reserve_top: Reservar arriba + reserve_bottom: Reservar abajo + reserve_left: Reservar izquierda + reserve_right: Reservar derecha + reserve_float: Reservar flotar + reserve_stack: Reservar pila + focus_top: Enfocar arriba + focus_bottom: Enfocar abajo + focus_left: Enfocar izquierda + focus_right: Enfocar derecha + focus_latest: Enfocar último + increase_width: Aumentar ancho + decrease_width: Disminuir ancho + increase_height: Aumentar altura + decrease_height: Disminuir altura + restore_sizes: Restaurar tamaños + switch_workspace_0: Cambiar al espacio de trabajo 0 + switch_workspace_1: Cambiar al espacio de trabajo 1 + switch_workspace_2: Cambiar al espacio de trabajo 2 + switch_workspace_3: Cambiar al espacio de trabajo 3 + switch_workspace_4: Cambiar al espacio de trabajo 4 + switch_workspace_5: Cambiar al espacio de trabajo 5 + switch_workspace_6: Cambiar al espacio de trabajo 6 + switch_workspace_7: Cambiar al espacio de trabajo 7 + switch_workspace_8: Cambiar al espacio de trabajo 8 + switch_workspace_9: Cambiar al espacio de trabajo 9 + move_to_workspace_0: Mover al espacio de trabajo 0 + move_to_workspace_1: Mover al espacio de trabajo 1 + move_to_workspace_2: Mover al espacio de trabajo 2 + move_to_workspace_3: Mover al espacio de trabajo 3 + move_to_workspace_4: Mover al espacio de trabajo 4 + move_to_workspace_5: Mover al espacio de trabajo 5 + move_to_workspace_6: Mover al espacio de trabajo 6 + move_to_workspace_7: Mover al espacio de trabajo 7 + move_to_workspace_8: Mover al espacio de trabajo 8 + move_to_workspace_9: Mover al espacio de trabajo 9 + send_to_workspace_0: Enviar al espacio de trabajo 0 + send_to_workspace_1: Enviar al espacio de trabajo 1 + send_to_workspace_2: Enviar al espacio de trabajo 2 + send_to_workspace_3: Enviar al espacio de trabajo 3 + send_to_workspace_4: Enviar al espacio de trabajo 4 + send_to_workspace_5: Enviar al espacio de trabajo 5 + send_to_workspace_6: Enviar al espacio de trabajo 6 + send_to_workspace_7: Enviar al espacio de trabajo 7 + send_to_workspace_8: Enviar al espacio de trabajo 8 + send_to_workspace_9: Enviar al espacio de trabajo 9 diff --git a/src/apps/settings/i18n/translations/et.yml b/src/apps/settings/i18n/translations/et.yml index 1527024c..dcab3066 100644 --- a/src/apps/settings/i18n/translations/et.yml +++ b/src/apps/settings/i18n/translations/et.yml @@ -1,193 +1,193 @@ -sides: - bottom: Alumine - left: Vasakul - right: Paremale - top: Tipus -header: - labels: - seelen_wm: Aknahaldur - seelen_weg: Dokk/ülesanderiba - specific_apps: Konkreetsed rakendused - monitors: Monitorid - shortcuts: Otseteed - general: Üld- - developer: Arendaja - info: Teave - seelen_bar: Väljamõeldud tööriistariba -start: - message: >- - Tere tulemast Seelen UI -sse, mis on Ultimate Desktop -keskkond koos - inkorporeeritud plaatidega Windowsi halduriga, et täiustada oma Windows 11 - kogemust! Uurige meie intuitiivse liidese ja edasijõudnute funktsioonidega - uut tõhususe ja multitegumtöötluse ajastut. - title: Tere tulemast! - message_accent: Optimeerige oma tootlikkust stiiliga! -general: - theme: - added: Teema on juba lisatud - label: Teemateave - placeholder: Valige teema - description: Kirjeldus - tags: Sildid - enabled: Lubatud teemad - author: Autor - add: Lisada teema - available: Saadav - selected: Valitud - language: Keel - startup: Kas joosta startup? - icon_pack: - label: Ikoonipakid - accent_color: Aktsentvärv -toolbar: - placeholder: - author: Autor - description: Kirjeldus - select: Tööriistariba struktuur - height: Kõrgus - enable: Luba väljamõeldud tööriistariba -wm: - border: - width: Piirilaius - offset: Piiride nihke - enable: Luba akna piir - space_between_containers: Konteinerite vaheline ruum - disabled_windows10: Windows 10 jaoks pole aknahaldur saadaval. - workspace_offset: Tööruumide nihkumine (veerised) - enable: Luba aknahaldur - author: Autor - description: Kirjeldus - layout: Paigutus - workspace_padding: Tööruumide polsterdus - resize_delta: Suuruse muutmine delta (%) -weg: - items: - visible_separators: Nähtavad eraldajad - label: Esemed - size: Üksuse suurus - gap: Esemete vaheline ruum - zoom_size: Suumendatud suurus (kasutatud teemade jaoks) - label: Dokk/ülesanderiba - width: Laius - padding: Polsterdamine - gap: Lüngad - auto_hide: Automaatne peida - margin: Marginaal - dock_side: Doki pool - enable: Luba dokk/ülesanderiba -devtools: - app_folders: Rakenduse kaustad - data_folder: Andmekaust - install_folder: Installi kaust - load: Laadima - custom_config_file: Laadige kohandatud konfiguratsioonifail - settings_file: Seadete fail - enable: Luba arendaja tööriistad -apps_configurations: - app: - options: - force: Jõudu juhtima - unmanage: Juhtimine - pinned: Kinnitatud - float: Ujuk - category: Kategooria - category_placeholder: Mitte ükski - monitor_placeholder: Mitte ükski - workspace: Tööruum - ok_readonly: Redigeerimine uuena - ok_create: Looma - title_create: '{{Name}} loomine' - options_label: Lisavalikud - workspace_placeholder: Mitte ükski - monitor: Ekraan - name: Nimetus - title_edit: Redigeerimine {{nimi}} - title_readonly: Vaatamine {{nimi}} - bindings: Sidumine (pange tähele mõlemat suvandit) - ok_edit: Värskendama - identifier: - negation: Eitav sobitamine - matching_strategy: Sobiv strateegia - and: Ja - add_block: Lisa plokk - or: Või - id: Identifikaator - remove: Kustutamisplokk - kind: Tuvastama - delete: Kustutama - confirm_delete: Kas olete kindel, et soovite selle konfiguratsiooni/S kustutada? - export: Ekspordi- - bundled_msg: >- - Need komplekteeritud konfiguratsioonid ei ole redigeeritavad ja on loodud - selleks, et pakkuda teile parimat kogemust ilma kohandamiseta. Nad - konfigureerivad teie jaoks automaatselt kõige levinumaid rakendusi. - swap: Vahetama - search: Otsing - import: Import - new: Uus - confirm_delete_title: Kinnitage kustutamine - bundled_title: Rakenduse konfiguratsioon, mis on komplekteeritud Seeleniga -extras: - exit: Lõpeta/väljumine - relaunch: Taaskäivitama - github: Github - links: Ametlikud lingid - version: Versioon - discord: Ebakõla -shortcuts: - labels: - increase_width: Suurendama laiust - switch_workspace_1: Lülitage tööalale 1 - send_to_workspace_9: Saada Workspace 9 - move_to_workspace_7: Kolige tööruumi 7 - switch_workspace_2: Lülitage tööruum 2 - move_to_workspace_1: Kolige tööalale 1 - increase_height: Suurendage kõrgust - switch_workspace_6: Lülitage tööruumi 6 -le - move_to_workspace_9: Kolige tööruumi 9 - move_to_workspace_5: Kolige tööruumi 5 - focus_left: Fookus vasakule - switch_workspace_4: Lülitage tööruum 4 - switch_workspace_0: Lülitage tööalale 0 - focus_top: Fookus ülaosa - focus_latest: Keskenduda uusim - move_to_workspace_0: Liikuge tööruumi 0 - send_to_workspace_6: Saada tööala 6 - decrease_height: Vähendamine kõrgus - move_to_workspace_6: Kolige tööruumi 6 - move_to_workspace_3: Kolige tööruumi 3 - send_to_workspace_2: Saada tööala 2 - focus_bottom: Fookuse põhi - move_to_workspace_8: Kolige tööalale 8 - reserve_left: Reserv vasak - switch_workspace_8: Lülitage tööruumi 8 -le - move_to_workspace_4: Kolige tööalale 4 - move_to_workspace_2: Kolige tööruumi 2 - reserve_right: Reservõigus - focus_right: Fookuse õigus - send_to_workspace_3: Saada tööala 3 - send_to_workspace_7: Saada tööruumi 7 - send_to_workspace_8: Saada tööala 8 - reserve_top: Reservi ülaosa - reserve_stack: Reservvirn - decrease_width: Languslaius - send_to_workspace_0: Saada tööalale 0 - reserve_float: Reservvajutus - reserve_bottom: Reservpõhja - send_to_workspace_4: Saada tööalale 4 - restore_sizes: Taastada suurused - send_to_workspace_1: Saada tööala 1 - switch_workspace_7: Lülitage tööruumi 7 -le - send_to_workspace_5: Saada tööalale 5 - switch_workspace_3: Lülitage tööruum 3 - switch_workspace_5: Lülitage tööruum 5 - switch_workspace_9: Lülitage Workspace 9 -le - enable_tooltip: Keelake, kui rakendate oma otseteid, kasutades seda Seelen Core API -d - enable: Lubage integreeritud otseteed (AHK) -inProgress: Pooleli ... -delete: Kustutama -quit: Loobuma -save: Kokkuhoid -loading: Laadimine ... -cancel: Tühistama -open: Avatud +sides: + bottom: Alumine + left: Vasakul + right: Paremale + top: Tipus +header: + labels: + seelen_wm: Aknahaldur + seelen_weg: Dokk/ülesanderiba + specific_apps: Konkreetsed rakendused + monitors: Monitorid + shortcuts: Otseteed + general: Üld- + developer: Arendaja + info: Teave + seelen_bar: Väljamõeldud tööriistariba +start: + message: >- + Tere tulemast Seelen UI -sse, mis on Ultimate Desktop -keskkond koos + inkorporeeritud plaatidega Windowsi halduriga, et täiustada oma Windows 11 + kogemust! Uurige meie intuitiivse liidese ja edasijõudnute funktsioonidega + uut tõhususe ja multitegumtöötluse ajastut. + title: Tere tulemast! + message_accent: Optimeerige oma tootlikkust stiiliga! +general: + theme: + added: Teema on juba lisatud + label: Teemateave + placeholder: Valige teema + description: Kirjeldus + tags: Sildid + enabled: Lubatud teemad + author: Autor + add: Lisada teema + available: Saadav + selected: Valitud + language: Keel + startup: Kas joosta startup? + icon_pack: + label: Ikoonipakid + accent_color: Aktsentvärv +toolbar: + placeholder: + author: Autor + description: Kirjeldus + select: Tööriistariba struktuur + height: Kõrgus + enable: Luba väljamõeldud tööriistariba +wm: + border: + width: Piirilaius + offset: Piiride nihke + enable: Luba akna piir + space_between_containers: Konteinerite vaheline ruum + disabled_windows10: Windows 10 jaoks pole aknahaldur saadaval. + workspace_offset: Tööruumide nihkumine (veerised) + enable: Luba aknahaldur + author: Autor + description: Kirjeldus + layout: Paigutus + workspace_padding: Tööruumide polsterdus + resize_delta: Suuruse muutmine delta (%) +weg: + items: + visible_separators: Nähtavad eraldajad + label: Esemed + size: Üksuse suurus + gap: Esemete vaheline ruum + zoom_size: Suumendatud suurus (kasutatud teemade jaoks) + label: Dokk/ülesanderiba + width: Laius + padding: Polsterdamine + gap: Lüngad + auto_hide: Automaatne peida + margin: Marginaal + dock_side: Doki pool + enable: Luba dokk/ülesanderiba +devtools: + app_folders: Rakenduse kaustad + data_folder: Andmekaust + install_folder: Installi kaust + load: Laadima + custom_config_file: Laadige kohandatud konfiguratsioonifail + settings_file: Seadete fail + enable: Luba arendaja tööriistad +apps_configurations: + app: + options: + force: Jõudu juhtima + unmanage: Juhtimine + pinned: Kinnitatud + float: Ujuk + category: Kategooria + category_placeholder: Mitte ükski + monitor_placeholder: Mitte ükski + workspace: Tööruum + ok_readonly: Redigeerimine uuena + ok_create: Looma + title_create: '{{Name}} loomine' + options_label: Lisavalikud + workspace_placeholder: Mitte ükski + monitor: Ekraan + name: Nimetus + title_edit: Redigeerimine {{nimi}} + title_readonly: Vaatamine {{nimi}} + bindings: Sidumine (pange tähele mõlemat suvandit) + ok_edit: Värskendama + identifier: + negation: Eitav sobitamine + matching_strategy: Sobiv strateegia + and: Ja + add_block: Lisa plokk + or: Või + id: Identifikaator + remove: Kustutamisplokk + kind: Tuvastama + delete: Kustutama + confirm_delete: Kas olete kindel, et soovite selle konfiguratsiooni/S kustutada? + export: Ekspordi- + bundled_msg: >- + Need komplekteeritud konfiguratsioonid ei ole redigeeritavad ja on loodud + selleks, et pakkuda teile parimat kogemust ilma kohandamiseta. Nad + konfigureerivad teie jaoks automaatselt kõige levinumaid rakendusi. + swap: Vahetama + search: Otsing + import: Import + new: Uus + confirm_delete_title: Kinnitage kustutamine + bundled_title: Rakenduse konfiguratsioon, mis on komplekteeritud Seeleniga +extras: + exit: Lõpeta/väljumine + relaunch: Taaskäivitama + github: Github + links: Ametlikud lingid + version: Versioon + discord: Ebakõla +shortcuts: + labels: + increase_width: Suurendama laiust + switch_workspace_1: Lülitage tööalale 1 + send_to_workspace_9: Saada Workspace 9 + move_to_workspace_7: Kolige tööruumi 7 + switch_workspace_2: Lülitage tööruum 2 + move_to_workspace_1: Kolige tööalale 1 + increase_height: Suurendage kõrgust + switch_workspace_6: Lülitage tööruumi 6 -le + move_to_workspace_9: Kolige tööruumi 9 + move_to_workspace_5: Kolige tööruumi 5 + focus_left: Fookus vasakule + switch_workspace_4: Lülitage tööruum 4 + switch_workspace_0: Lülitage tööalale 0 + focus_top: Fookus ülaosa + focus_latest: Keskenduda uusim + move_to_workspace_0: Liikuge tööruumi 0 + send_to_workspace_6: Saada tööala 6 + decrease_height: Vähendamine kõrgus + move_to_workspace_6: Kolige tööruumi 6 + move_to_workspace_3: Kolige tööruumi 3 + send_to_workspace_2: Saada tööala 2 + focus_bottom: Fookuse põhi + move_to_workspace_8: Kolige tööalale 8 + reserve_left: Reserv vasak + switch_workspace_8: Lülitage tööruumi 8 -le + move_to_workspace_4: Kolige tööalale 4 + move_to_workspace_2: Kolige tööruumi 2 + reserve_right: Reservõigus + focus_right: Fookuse õigus + send_to_workspace_3: Saada tööala 3 + send_to_workspace_7: Saada tööruumi 7 + send_to_workspace_8: Saada tööala 8 + reserve_top: Reservi ülaosa + reserve_stack: Reservvirn + decrease_width: Languslaius + send_to_workspace_0: Saada tööalale 0 + reserve_float: Reservvajutus + reserve_bottom: Reservpõhja + send_to_workspace_4: Saada tööalale 4 + restore_sizes: Taastada suurused + send_to_workspace_1: Saada tööala 1 + switch_workspace_7: Lülitage tööruumi 7 -le + send_to_workspace_5: Saada tööalale 5 + switch_workspace_3: Lülitage tööruum 3 + switch_workspace_5: Lülitage tööruum 5 + switch_workspace_9: Lülitage Workspace 9 -le + enable_tooltip: Keelake, kui rakendate oma otseteid, kasutades seda Seelen Core API -d + enable: Lubage integreeritud otseteed (AHK) +inProgress: Pooleli ... +delete: Kustutama +quit: Loobuma +save: Kokkuhoid +loading: Laadimine ... +cancel: Tühistama +open: Avatud diff --git a/src/apps/settings/i18n/translations/eu.yml b/src/apps/settings/i18n/translations/eu.yml index c919a586..d248786d 100644 --- a/src/apps/settings/i18n/translations/eu.yml +++ b/src/apps/settings/i18n/translations/eu.yml @@ -1,193 +1,193 @@ -sides: - left: Ezker - right: Zuzen - bottom: Azpi - top: Tontor -header: - labels: - info: Informazio - seelen_wm: Leiho kudeatzailea - specific_apps: Aplikazio espezifikoak - monitors: Monitore - developer: Garatzaile - shortcuts: Lasterbideak - general: Jeneral - seelen_weg: Dock / ataza barra - seelen_bar: Fancy tresna barra -start: - message: >- - Ongi etorri Seelen UI-ra, azken mahaigaineko ingurunea, fitxategien leiho - kudeatzailearekin txertatu zure Windows 11 esperientzia hobetzeko! Arakatu - eraginkortasunaren eta multiataza aro berria gure interfaze intuitiboarekin - eta ezaugarri aurreratuekin. - title: Ongi etorri! - message_accent: Optimizatu zure produktibitatea estiloarekin! -general: - theme: - label: Gaiaren informazioa - add: Gehitu gaia - placeholder: Hautatu Gaia - author: Idazle - tags: Teskak - description: Deskribapen - added: Gaia dagoeneko gehitu da - enabled: Gaitutako gaiak - available: Erabilgarri - selected: Hautatu - startup: Korrika abiaraztean? - language: Mintzaira - icon_pack: - label: Ikono paketeak - accent_color: Azentu kolorea -toolbar: - placeholder: - select: Tresna-barraren egitura - author: Idazle - description: Deskribapen - enable: Gaitu tresna-barra - height: Luzera -wm: - border: - width: Ertzaren zabalera - offset: Ertzaren desplazamendua - enable: Gaitu leihoen ertza - disabled_windows10: Leiho kudeatzailea ez dago erabilgarri Windows 10-erako. - enable: Gaitu leiho kudeatzailea - description: Deskribapen - space_between_containers: Edukiontzien arteko espazioa - workspace_offset: Laneko espazioak desplazamendua (marjinak) - layout: Diseinu - resize_delta: RETIZE DELTA (%) - author: Idazle - workspace_padding: Laneko guneak betegarria -weg: - items: - gap: Elementuen arteko espazioa - size: Elementuen tamaina - visible_separators: Ikusgai bereizgailuak - zoom_size: Zoom tamaina (gaietarako erabiltzen da) - label: Manatu - auto_hide: Ezkutatu automatikoa - width: Zabalera - enable: Gaitu kaia / ataza barra - dock_side: Kaiaren alde - margin: Emandar - gap: Tarte - label: Dock / ataza barra - padding: Betegarri -devtools: - enable: Gaitu garatzaileen tresnak - load: Zamatu - data_folder: Datu karpeta - custom_config_file: Kargatu Config fitxategi pertsonalizatua - install_folder: Instalazio karpeta - app_folders: Aplikazio karpetak - settings_file: Ezarpenak fitxategia -apps_configurations: - app: - options: - float: Flotatu - force: Indar kudeatzea - pinned: Pipe - unmanage: Loraza - title_readonly: '{{Name}} ikustea' - ok_readonly: Editatu berria - monitor: Behatu - monitor_placeholder: Ezein ez - options_label: Aukera gehigarriak - category_placeholder: Ezein ez - category: Kategoria - bindings: Lotura (kontuan bi aukerak behar dira) - workspace_placeholder: Ezein ez - title_create: '{{Name}} sortzea' - ok_edit: Eguneratu - workspace: Laneko espazioa - name: Izen - ok_create: Sortu - title_edit: '{{Name}} editatzea' - identifier: - add_block: Gehitu blokea - kind: Identifikatu - negation: Ezeztatu bat datozenak - and: Eta - remove: Ezabatu blokea - or: Ala - matching_strategy: Bat datorren estrategia - id: Identifikatzaile - export: Esportagai - bundled_title: App konfigurazioa Seelen-ekin lotuta - confirm_delete: Ziur konfigurazio hau ezabatu nahi duzula? - delete: Ezabatu - new: Berri - import: Inportatu - bundled_msg: >- - Konfigurazio multzo hauek ez dira editagarriak eta pertsonalizaziorik gabeko - esperientzia onena emateko diseinatuta daude. Zuretzako aplikazio ohikoenak - automatikoki konfiguratzen dituzte. - search: Araketa - swap: Tratu - confirm_delete_title: Berretsi Ezabatu -extras: - github: Github - discord: Deskudun - exit: Irten / irten - relaunch: Errorefrika - links: Lotura Ofizialak - version: Bertsio -shortcuts: - labels: - restore_sizes: Neurriak leheneratu - increase_width: Zabalera handitzea - reserve_left: Erreserba ezkerrera - reserve_stack: Erreserba pila - move_to_workspace_7: Mugitu lan-eremura 7 - decrease_height: Altuera gutxitu - send_to_workspace_8: Bidali lantokira 8 - reserve_top: Erreserba Top - switch_workspace_2: Aldatu Workspace 2ra - move_to_workspace_1: Mugitu lan-eremura 1 - focus_bottom: Fokua Behean - switch_workspace_0: Aldatu Workspace 0ra - focus_latest: Fokua azkena - increase_height: Altuera handitzea - switch_workspace_8: Aldatu lan-eremura 8 - focus_right: Argindu eskubidea - switch_workspace_6: Aldatu lan-eremura 6 - switch_workspace_3: Aldatu lan-eremura 3 - send_to_workspace_5: Bidali lantokira 5 - switch_workspace_9: Aldatu Workspace 9ra - switch_workspace_7: Aldatu Workspace 7ra - reserve_right: Erreserbatu eskubidea - send_to_workspace_7: Bidali lantokira 7 - focus_left: Focus ezkerrera - switch_workspace_5: Aldatu Workspace 5era - move_to_workspace_9: Mugitu Workspace 9ra - move_to_workspace_6: Mugitu lan-eremura 6 - reserve_bottom: Erreserbatu behealdea - move_to_workspace_3: Mugitu lan-eremura 3 - move_to_workspace_2: Mugitu Workspace 2ra - decrease_width: Murriztu zabalera - send_to_workspace_4: Bidali Workspace 4ra - move_to_workspace_8: Mugitu lan-eremura 8 - move_to_workspace_4: Mugitu Workspace 4ra - move_to_workspace_5: Mugitu lan-eremura 5 - send_to_workspace_6: Bidali lantokira 6 - switch_workspace_4: Aldatu Workspace 4ra - move_to_workspace_0: Mugitu 0 lanera - send_to_workspace_2: Bidali Workspace 2ra - switch_workspace_1: Aldatu lan-eremura 1 - send_to_workspace_3: Bidali lantokira 3 - send_to_workspace_0: Bidali lan-eremura 0 - reserve_float: Erreserba karroza - send_to_workspace_9: Bidali Workspace 9ra - send_to_workspace_1: Bidali lan-eremura 1 - focus_top: Focus Top - enable: Gaitu lasterbide integratuak (Ahk) - enable_tooltip: Desgaitu Seelen Core APIa erabiliz zure lasterbideak ezartzen badituzu -cancel: Indargabetu -quit: Laga -delete: Ezabatu -open: Ireki -save: Aurreztu -loading: Kargatzen ... -inProgress: Abian ... +sides: + left: Ezker + right: Zuzen + bottom: Azpi + top: Tontor +header: + labels: + info: Informazio + seelen_wm: Leiho kudeatzailea + specific_apps: Aplikazio espezifikoak + monitors: Monitore + developer: Garatzaile + shortcuts: Lasterbideak + general: Jeneral + seelen_weg: Dock / ataza barra + seelen_bar: Fancy tresna barra +start: + message: >- + Ongi etorri Seelen UI-ra, azken mahaigaineko ingurunea, fitxategien leiho + kudeatzailearekin txertatu zure Windows 11 esperientzia hobetzeko! Arakatu + eraginkortasunaren eta multiataza aro berria gure interfaze intuitiboarekin + eta ezaugarri aurreratuekin. + title: Ongi etorri! + message_accent: Optimizatu zure produktibitatea estiloarekin! +general: + theme: + label: Gaiaren informazioa + add: Gehitu gaia + placeholder: Hautatu Gaia + author: Idazle + tags: Teskak + description: Deskribapen + added: Gaia dagoeneko gehitu da + enabled: Gaitutako gaiak + available: Erabilgarri + selected: Hautatu + startup: Korrika abiaraztean? + language: Mintzaira + icon_pack: + label: Ikono paketeak + accent_color: Azentu kolorea +toolbar: + placeholder: + select: Tresna-barraren egitura + author: Idazle + description: Deskribapen + enable: Gaitu tresna-barra + height: Luzera +wm: + border: + width: Ertzaren zabalera + offset: Ertzaren desplazamendua + enable: Gaitu leihoen ertza + disabled_windows10: Leiho kudeatzailea ez dago erabilgarri Windows 10-erako. + enable: Gaitu leiho kudeatzailea + description: Deskribapen + space_between_containers: Edukiontzien arteko espazioa + workspace_offset: Laneko espazioak desplazamendua (marjinak) + layout: Diseinu + resize_delta: RETIZE DELTA (%) + author: Idazle + workspace_padding: Laneko guneak betegarria +weg: + items: + gap: Elementuen arteko espazioa + size: Elementuen tamaina + visible_separators: Ikusgai bereizgailuak + zoom_size: Zoom tamaina (gaietarako erabiltzen da) + label: Manatu + auto_hide: Ezkutatu automatikoa + width: Zabalera + enable: Gaitu kaia / ataza barra + dock_side: Kaiaren alde + margin: Emandar + gap: Tarte + label: Dock / ataza barra + padding: Betegarri +devtools: + enable: Gaitu garatzaileen tresnak + load: Zamatu + data_folder: Datu karpeta + custom_config_file: Kargatu Config fitxategi pertsonalizatua + install_folder: Instalazio karpeta + app_folders: Aplikazio karpetak + settings_file: Ezarpenak fitxategia +apps_configurations: + app: + options: + float: Flotatu + force: Indar kudeatzea + pinned: Pipe + unmanage: Loraza + title_readonly: '{{Name}} ikustea' + ok_readonly: Editatu berria + monitor: Behatu + monitor_placeholder: Ezein ez + options_label: Aukera gehigarriak + category_placeholder: Ezein ez + category: Kategoria + bindings: Lotura (kontuan bi aukerak behar dira) + workspace_placeholder: Ezein ez + title_create: '{{Name}} sortzea' + ok_edit: Eguneratu + workspace: Laneko espazioa + name: Izen + ok_create: Sortu + title_edit: '{{Name}} editatzea' + identifier: + add_block: Gehitu blokea + kind: Identifikatu + negation: Ezeztatu bat datozenak + and: Eta + remove: Ezabatu blokea + or: Ala + matching_strategy: Bat datorren estrategia + id: Identifikatzaile + export: Esportagai + bundled_title: App konfigurazioa Seelen-ekin lotuta + confirm_delete: Ziur konfigurazio hau ezabatu nahi duzula? + delete: Ezabatu + new: Berri + import: Inportatu + bundled_msg: >- + Konfigurazio multzo hauek ez dira editagarriak eta pertsonalizaziorik gabeko + esperientzia onena emateko diseinatuta daude. Zuretzako aplikazio ohikoenak + automatikoki konfiguratzen dituzte. + search: Araketa + swap: Tratu + confirm_delete_title: Berretsi Ezabatu +extras: + github: Github + discord: Deskudun + exit: Irten / irten + relaunch: Errorefrika + links: Lotura Ofizialak + version: Bertsio +shortcuts: + labels: + restore_sizes: Neurriak leheneratu + increase_width: Zabalera handitzea + reserve_left: Erreserba ezkerrera + reserve_stack: Erreserba pila + move_to_workspace_7: Mugitu lan-eremura 7 + decrease_height: Altuera gutxitu + send_to_workspace_8: Bidali lantokira 8 + reserve_top: Erreserba Top + switch_workspace_2: Aldatu Workspace 2ra + move_to_workspace_1: Mugitu lan-eremura 1 + focus_bottom: Fokua Behean + switch_workspace_0: Aldatu Workspace 0ra + focus_latest: Fokua azkena + increase_height: Altuera handitzea + switch_workspace_8: Aldatu lan-eremura 8 + focus_right: Argindu eskubidea + switch_workspace_6: Aldatu lan-eremura 6 + switch_workspace_3: Aldatu lan-eremura 3 + send_to_workspace_5: Bidali lantokira 5 + switch_workspace_9: Aldatu Workspace 9ra + switch_workspace_7: Aldatu Workspace 7ra + reserve_right: Erreserbatu eskubidea + send_to_workspace_7: Bidali lantokira 7 + focus_left: Focus ezkerrera + switch_workspace_5: Aldatu Workspace 5era + move_to_workspace_9: Mugitu Workspace 9ra + move_to_workspace_6: Mugitu lan-eremura 6 + reserve_bottom: Erreserbatu behealdea + move_to_workspace_3: Mugitu lan-eremura 3 + move_to_workspace_2: Mugitu Workspace 2ra + decrease_width: Murriztu zabalera + send_to_workspace_4: Bidali Workspace 4ra + move_to_workspace_8: Mugitu lan-eremura 8 + move_to_workspace_4: Mugitu Workspace 4ra + move_to_workspace_5: Mugitu lan-eremura 5 + send_to_workspace_6: Bidali lantokira 6 + switch_workspace_4: Aldatu Workspace 4ra + move_to_workspace_0: Mugitu 0 lanera + send_to_workspace_2: Bidali Workspace 2ra + switch_workspace_1: Aldatu lan-eremura 1 + send_to_workspace_3: Bidali lantokira 3 + send_to_workspace_0: Bidali lan-eremura 0 + reserve_float: Erreserba karroza + send_to_workspace_9: Bidali Workspace 9ra + send_to_workspace_1: Bidali lan-eremura 1 + focus_top: Focus Top + enable: Gaitu lasterbide integratuak (Ahk) + enable_tooltip: Desgaitu Seelen Core APIa erabiliz zure lasterbideak ezartzen badituzu +cancel: Indargabetu +quit: Laga +delete: Ezabatu +open: Ireki +save: Aurreztu +loading: Kargatzen ... +inProgress: Abian ... diff --git a/src/apps/settings/i18n/translations/fa.yml b/src/apps/settings/i18n/translations/fa.yml index b1e27a7b..20337909 100644 --- a/src/apps/settings/i18n/translations/fa.yml +++ b/src/apps/settings/i18n/translations/fa.yml @@ -1,194 +1,194 @@ -sides: - top: بالا - right: درست - left: ترک کرد - bottom: پایین -header: - labels: - monitors: مانیتور - shortcuts: میانبرها - info: اطلاعات - developer: توسعه دهنده - general: عمومی - seelen_wm: مدیر پنجره - seelen_bar: نوار ابزار فانتزی - seelen_weg: اسکله/نوار وظیفه - specific_apps: برنامه های خاص -start: - title: خوش آمدی! - message_accent: بهره وری خود را با سبک بهینه کنید! - message: >- - به Seelen UI ، محیط دسک تاپ نهایی با یک مدیر کاشی کاری ویندوز برای تقویت - تجربه ویندوز 11 خوش آمدید! دوره جدیدی از کارآیی و چند وظیفه ای را با رابط - بصری و ویژگی های پیشرفته ما کاوش کنید. -general: - theme: - placeholder: انتخاب قالب - tags: برچسب ها - description: شرح - author: نویسنده - add: موضوع را اضافه کنید - added: موضوع قبلاً اضافه شده است - label: اطلاعات تم - enabled: مضامین را فعال کرد - available: در دسترس - selected: انتخاب شد - language: زبان - startup: در راه اندازی اجرا می شود؟ - icon_pack: - label: بسته های نماد - accent_color: رنگ لهجه -toolbar: - placeholder: - description: شرح - author: نویسنده - select: نوار ابزار - height: قد - enable: نوار ابزار فانتزی را فعال کنید -wm: - border: - enable: مرز پنجره را فعال کنید - width: عرض مرز - offset: جبران مرز - layout: چیدمان - author: نویسنده - description: شرح - workspace_offset: مکانهای کار افست (حاشیه) - space_between_containers: فضای بین ظروف - enable: مدیر پنجره را فعال کنید - resize_delta: تغییر اندازه دلتا (٪) - disabled_windows10: مدیر پنجره برای ویندوز 10 در دسترس نیست. - workspace_padding: قسمتهای کاری PADING -weg: - items: - label: موارد - size: اندازه مورد - gap: فضای بین موارد - zoom_size: اندازه بزرگنمایی (برای مضامین استفاده می شود) - visible_separators: جداکننده های قابل مشاهده - padding: لایه گذاری - gap: شکاف - margin: لبه - label: اسکله/نوار وظیفه - dock_side: طرف اسکله - auto_hide: پنهان خودکار - enable: Dock/TaskBar را فعال کنید - width: عرض -devtools: - load: بار - install_folder: پوشه نصب - custom_config_file: بارگیری پرونده پیکربندی سفارشی - enable: ابزارهای توسعه دهنده را فعال کنید - settings_file: پرونده تنظیمات - data_folder: پوشه داده ها - app_folders: پوشه های برنامه -apps_configurations: - app: - options: - float: شناور - pinned: بریده شده - unmanage: از بین بردن - force: زور مدیریت - category: دسته بندی - ok_edit: به روز رسانی - category_placeholder: هیچ یک - name: نام - workspace_placeholder: هیچ یک - monitor_placeholder: هیچ یک - ok_create: ايجاد كردن - workspace: فضای کاری - options_label: گزینه های اضافی - title_create: ایجاد {{name}} - title_readonly: مشاهده {{نام}} - title_edit: ویرایش {{نام}} - bindings: اتصال (توجه داشته باشید هر دو گزینه مورد نیاز است) - ok_readonly: ویرایش به عنوان جدید - monitor: نظارت - identifier: - and: وت - or: یا - id: مشخص کننده - kind: شناسایی توسط - add_block: اضافه کردن - negation: نفی تطبیق - matching_strategy: استراتژی تطبیق - remove: حذف بلوک - new: جدید - confirm_delete_title: تایید حذف - delete: حذف - swap: مبادله کردن - import: وارد كردن - search: جستجو کردن - bundled_title: پیکربندی برنامه همراه با Seelen - confirm_delete: آیا مطمئن هستید که می خواهید این پیکربندی/s را حذف کنید؟ - export: صادر کردن - bundled_msg: >- - این تنظیمات بسته بندی شده قابل ویرایش نیستند و به گونه ای طراحی شده اند که - بدون شخصی سازی بهترین تجربه را برای شما فراهم می کنند. آنها به طور خودکار - متداول ترین برنامه ها را برای شما پیکربندی می کنند. -extras: - github: گیتوب - discord: اختلاف - version: نسخه - links: پیوندهای رسمی - exit: ترک/خروج - relaunch: مجدداً -shortcuts: - labels: - reserve_stack: پشته ذخیره - switch_workspace_6: تغییر به فضای کاری 6 - move_to_workspace_8: حرکت به فضای کاری 8 - reserve_float: شناور رزرو - send_to_workspace_9: ارسال به فضای کاری 9 - switch_workspace_4: تغییر به فضای کاری 4 - move_to_workspace_3: حرکت به فضای کاری 3 - move_to_workspace_0: حرکت به فضای کاری 0 - focus_right: راست تمرکز کنید - send_to_workspace_1: ارسال به فضای کاری 1 - send_to_workspace_3: ارسال به فضای کاری 3 - send_to_workspace_8: ارسال به فضای کاری 8 - focus_bottom: پایین تمرکز - switch_workspace_1: تغییر به فضای کاری 1 - reserve_bottom: قسمت پایین ذخیره - send_to_workspace_7: ارسال به فضای کاری 7 - focus_top: تمرکز بالا - increase_height: افزایش ارتفاع - send_to_workspace_6: ارسال به فضای کاری 6 - switch_workspace_9: تغییر به فضای کاری 9 - decrease_height: کاهش قد - move_to_workspace_5: حرکت به فضای کاری 5 - switch_workspace_0: تغییر به فضای کاری 0 - focus_latest: آخرین تمرکز - move_to_workspace_7: حرکت به فضای کاری 7 - move_to_workspace_4: حرکت به فضای کاری 4 - move_to_workspace_6: حرکت به فضای کاری 6 - switch_workspace_8: تغییر به فضای کاری 8 - move_to_workspace_9: حرکت به فضای کاری 9 - reserve_left: رزرو سمت چپ - send_to_workspace_5: ارسال به فضای کاری 5 - move_to_workspace_2: حرکت به فضای کاری 2 - move_to_workspace_1: حرکت به فضای کاری 1 - send_to_workspace_0: ارسال به فضای کاری 0 - send_to_workspace_2: ارسال به فضای کاری 2 - send_to_workspace_4: ارسال به فضای کاری 4 - switch_workspace_7: تغییر به فضای کاری 7 - increase_width: عرض را افزایش دهید - reserve_top: بالای ذخیره - switch_workspace_3: تغییر به فضای کاری 3 - focus_left: تمرکز سمت چپ - decrease_width: کاهش عرض - switch_workspace_5: تغییر به فضای کاری 5 - switch_workspace_2: تغییر به فضای کاری 2 - restore_sizes: اندازه ها را بازیابی کنید - reserve_right: حق رزرو - enable_tooltip: >- - اگر میانبرهای خود را با استفاده از API Seelen Core پیاده سازی خواهید کرد ، - غیرفعال کنید - enable: میانبرهای یکپارچه (AHK) را فعال کنید -inProgress: در حال پیش رفت... -cancel: لغو کردن -save: صرفه جویی -open: باز کن -loading: بارگذاری... -delete: حذف -quit: ترک +sides: + top: بالا + right: درست + left: ترک کرد + bottom: پایین +header: + labels: + monitors: مانیتور + shortcuts: میانبرها + info: اطلاعات + developer: توسعه دهنده + general: عمومی + seelen_wm: مدیر پنجره + seelen_bar: نوار ابزار فانتزی + seelen_weg: اسکله/نوار وظیفه + specific_apps: برنامه های خاص +start: + title: خوش آمدی! + message_accent: بهره وری خود را با سبک بهینه کنید! + message: >- + به Seelen UI ، محیط دسک تاپ نهایی با یک مدیر کاشی کاری ویندوز برای تقویت + تجربه ویندوز 11 خوش آمدید! دوره جدیدی از کارآیی و چند وظیفه ای را با رابط + بصری و ویژگی های پیشرفته ما کاوش کنید. +general: + theme: + placeholder: انتخاب قالب + tags: برچسب ها + description: شرح + author: نویسنده + add: موضوع را اضافه کنید + added: موضوع قبلاً اضافه شده است + label: اطلاعات تم + enabled: مضامین را فعال کرد + available: در دسترس + selected: انتخاب شد + language: زبان + startup: در راه اندازی اجرا می شود؟ + icon_pack: + label: بسته های نماد + accent_color: رنگ لهجه +toolbar: + placeholder: + description: شرح + author: نویسنده + select: نوار ابزار + height: قد + enable: نوار ابزار فانتزی را فعال کنید +wm: + border: + enable: مرز پنجره را فعال کنید + width: عرض مرز + offset: جبران مرز + layout: چیدمان + author: نویسنده + description: شرح + workspace_offset: مکانهای کار افست (حاشیه) + space_between_containers: فضای بین ظروف + enable: مدیر پنجره را فعال کنید + resize_delta: تغییر اندازه دلتا (٪) + disabled_windows10: مدیر پنجره برای ویندوز 10 در دسترس نیست. + workspace_padding: قسمتهای کاری PADING +weg: + items: + label: موارد + size: اندازه مورد + gap: فضای بین موارد + zoom_size: اندازه بزرگنمایی (برای مضامین استفاده می شود) + visible_separators: جداکننده های قابل مشاهده + padding: لایه گذاری + gap: شکاف + margin: لبه + label: اسکله/نوار وظیفه + dock_side: طرف اسکله + auto_hide: پنهان خودکار + enable: Dock/TaskBar را فعال کنید + width: عرض +devtools: + load: بار + install_folder: پوشه نصب + custom_config_file: بارگیری پرونده پیکربندی سفارشی + enable: ابزارهای توسعه دهنده را فعال کنید + settings_file: پرونده تنظیمات + data_folder: پوشه داده ها + app_folders: پوشه های برنامه +apps_configurations: + app: + options: + float: شناور + pinned: بریده شده + unmanage: از بین بردن + force: زور مدیریت + category: دسته بندی + ok_edit: به روز رسانی + category_placeholder: هیچ یک + name: نام + workspace_placeholder: هیچ یک + monitor_placeholder: هیچ یک + ok_create: ايجاد كردن + workspace: فضای کاری + options_label: گزینه های اضافی + title_create: ایجاد {{name}} + title_readonly: مشاهده {{نام}} + title_edit: ویرایش {{نام}} + bindings: اتصال (توجه داشته باشید هر دو گزینه مورد نیاز است) + ok_readonly: ویرایش به عنوان جدید + monitor: نظارت + identifier: + and: وت + or: یا + id: مشخص کننده + kind: شناسایی توسط + add_block: اضافه کردن + negation: نفی تطبیق + matching_strategy: استراتژی تطبیق + remove: حذف بلوک + new: جدید + confirm_delete_title: تایید حذف + delete: حذف + swap: مبادله کردن + import: وارد كردن + search: جستجو کردن + bundled_title: پیکربندی برنامه همراه با Seelen + confirm_delete: آیا مطمئن هستید که می خواهید این پیکربندی/s را حذف کنید؟ + export: صادر کردن + bundled_msg: >- + این تنظیمات بسته بندی شده قابل ویرایش نیستند و به گونه ای طراحی شده اند که + بدون شخصی سازی بهترین تجربه را برای شما فراهم می کنند. آنها به طور خودکار + متداول ترین برنامه ها را برای شما پیکربندی می کنند. +extras: + github: گیتوب + discord: اختلاف + version: نسخه + links: پیوندهای رسمی + exit: ترک/خروج + relaunch: مجدداً +shortcuts: + labels: + reserve_stack: پشته ذخیره + switch_workspace_6: تغییر به فضای کاری 6 + move_to_workspace_8: حرکت به فضای کاری 8 + reserve_float: شناور رزرو + send_to_workspace_9: ارسال به فضای کاری 9 + switch_workspace_4: تغییر به فضای کاری 4 + move_to_workspace_3: حرکت به فضای کاری 3 + move_to_workspace_0: حرکت به فضای کاری 0 + focus_right: راست تمرکز کنید + send_to_workspace_1: ارسال به فضای کاری 1 + send_to_workspace_3: ارسال به فضای کاری 3 + send_to_workspace_8: ارسال به فضای کاری 8 + focus_bottom: پایین تمرکز + switch_workspace_1: تغییر به فضای کاری 1 + reserve_bottom: قسمت پایین ذخیره + send_to_workspace_7: ارسال به فضای کاری 7 + focus_top: تمرکز بالا + increase_height: افزایش ارتفاع + send_to_workspace_6: ارسال به فضای کاری 6 + switch_workspace_9: تغییر به فضای کاری 9 + decrease_height: کاهش قد + move_to_workspace_5: حرکت به فضای کاری 5 + switch_workspace_0: تغییر به فضای کاری 0 + focus_latest: آخرین تمرکز + move_to_workspace_7: حرکت به فضای کاری 7 + move_to_workspace_4: حرکت به فضای کاری 4 + move_to_workspace_6: حرکت به فضای کاری 6 + switch_workspace_8: تغییر به فضای کاری 8 + move_to_workspace_9: حرکت به فضای کاری 9 + reserve_left: رزرو سمت چپ + send_to_workspace_5: ارسال به فضای کاری 5 + move_to_workspace_2: حرکت به فضای کاری 2 + move_to_workspace_1: حرکت به فضای کاری 1 + send_to_workspace_0: ارسال به فضای کاری 0 + send_to_workspace_2: ارسال به فضای کاری 2 + send_to_workspace_4: ارسال به فضای کاری 4 + switch_workspace_7: تغییر به فضای کاری 7 + increase_width: عرض را افزایش دهید + reserve_top: بالای ذخیره + switch_workspace_3: تغییر به فضای کاری 3 + focus_left: تمرکز سمت چپ + decrease_width: کاهش عرض + switch_workspace_5: تغییر به فضای کاری 5 + switch_workspace_2: تغییر به فضای کاری 2 + restore_sizes: اندازه ها را بازیابی کنید + reserve_right: حق رزرو + enable_tooltip: >- + اگر میانبرهای خود را با استفاده از API Seelen Core پیاده سازی خواهید کرد ، + غیرفعال کنید + enable: میانبرهای یکپارچه (AHK) را فعال کنید +inProgress: در حال پیش رفت... +cancel: لغو کردن +save: صرفه جویی +open: باز کن +loading: بارگذاری... +delete: حذف +quit: ترک diff --git a/src/apps/settings/i18n/translations/fi.yml b/src/apps/settings/i18n/translations/fi.yml index cab0826d..ed01cc18 100644 --- a/src/apps/settings/i18n/translations/fi.yml +++ b/src/apps/settings/i18n/translations/fi.yml @@ -1,195 +1,195 @@ -sides: - right: Oikea - bottom: Pohja - top: Ylhäältä - left: Vasen -header: - labels: - developer: Kehittäjä - info: Tiedot - seelen_bar: Hieno työkalurivi - seelen_weg: Telakka/tehtäväpalkki - seelen_wm: Ikkunanhallinta - shortcuts: Pikakuvakkeet - monitors: Näytöt - specific_apps: Erityiset sovellukset - general: Yleinen -start: - title: Tervetuloa! - message_accent: Optimoi tuottavuus tyylillä! - message: >- - Tervetuloa Seelen UI: hen, Ultimate Desktop -ympäristöön, jossa on - sisällytetty laatoitus Windows Manager, parantaaksesi Windows 11 - -kokemustasi! Tutustu uuteen tehokkuuden ja monitehtavan aikakauteen - intuitiivisella rajapinnalla ja edistyneillä ominaisuuksilla. -general: - theme: - description: Kuvaus - label: Teematiedot - added: Jo lisätty teema - enabled: Mahdolliset teemat - add: Lisätä teemaa - tags: Tunnisteet - author: Kirjoittaja - placeholder: Valitse teema - available: Saatavilla - selected: Valittu - language: Kieli - startup: Suorittaa käynnistyksen yhteydessä? - icon_pack: - label: Kuvakepakkaukset - accent_color: Korostusväri -toolbar: - placeholder: - description: Kuvaus - select: Työkalurivin rakenne - author: Kirjoittaja - height: Korkeus - enable: Ota hieno työkalurivi käyttöön -wm: - border: - offset: Rajan siirtyminen - enable: Ota ikkunan reuna käyttöön - width: Rajan leveys - layout: Layout - description: Kuvaus - workspace_padding: Työtilat - disabled_windows10: 'Windows Manager ei ole käytettävissä Windows 10: lle.' - enable: Ota ikkunanhallinta käyttöön - resize_delta: Muuttaa Delta (%) - space_between_containers: Konttien välinen tila - author: Kirjoittaja - workspace_offset: Työtilojen siirtymä (marginaalit) -weg: - items: - zoom_size: Zoomoitu koko (käytetty teemoihin) - size: Esineen koko - visible_separators: Näkyvät erottimet - gap: Tilaa esineiden välillä - label: Kohteet - width: Leveys - margin: Marginaali - gap: Kuilu - auto_hide: Automaattinen piilo - padding: Pehmuste - label: Telakka/tehtäväpalkki - enable: Ota Dock/tehtäväpalkki käyttöön - dock_side: Laituri -devtools: - load: Ladata - custom_config_file: Lataa mukautettu konfigurointitiedosto - settings_file: Asetustiedosto - data_folder: Tietokansio - enable: Ota kehittäjätyökalut käyttöön - install_folder: Asennuskansio - app_folders: Sovelluskansiot -apps_configurations: - app: - options: - force: Voimankäyttö - float: Kellua - unmanage: Hallinta - pinned: Kiinnitetty - category: Kategoria - title_create: '{{Nimi}} luominen' - title_edit: Muokkaaminen {{nimi}} - category_placeholder: Ei mitään - options_label: Ylimääräiset vaihtoehdot - ok_edit: Päivittää - workspace: Työtila - workspace_placeholder: Ei mitään - ok_create: Luoda - bindings: Sidonta (huomautus tarvitaan molemmat vaihtoehdot) - ok_readonly: Muokata UUSIA - monitor_placeholder: Ei mitään - name: Nimi - title_readonly: Katselu {{nimi}} - monitor: Monitori - identifier: - add_block: Lisätä - remove: Poistaa lohko - negation: Negatiivista vastaavuus - and: JA - kind: Tunnistaa jtk - matching_strategy: Sovitusstrategia - id: Tunniste - or: TAI - delete: Poistaa - new: Uusi - export: Viedä - confirm_delete: Haluatko varmasti poistaa tämän kokoonpanon/S? - swap: Vaihtaa - search: Hae - import: Tuonti - confirm_delete_title: Vahvista poistaminen - bundled_msg: >- - Näitä pauhutettuja kokoonpanoja ei voida muokata, ja ne on suunniteltu - tarjoamaan sinulle paras kokemus ilman räätälöintiä. Ne määrittelevät - sinulle yleisimmät sovellukset automaattisesti. - bundled_title: APP -konfigurointi, joka on mukana Seelenin kanssa -extras: - exit: Lopettaa/poistua - relaunch: Käynnistää uudelleen - links: Viralliset linkit - github: Github - version: Versio - discord: Erimielisyys -shortcuts: - labels: - reserve_bottom: Varata pohja - switch_workspace_6: Vaihda työtilaan 6 - switch_workspace_4: Vaihda työtilaan 4 - send_to_workspace_9: Lähetä työtilaan 9 - restore_sizes: Palauttaa koot - move_to_workspace_8: Siirry työtilaan 8 - send_to_workspace_0: Lähetä työtilaan 0 - reserve_top: Varaa - move_to_workspace_2: Siirry työtilaan 2 - decrease_width: Vähentynyt leveys - send_to_workspace_5: Lähetä työtilaan 5 - send_to_workspace_1: Lähetä työtilaan 1 - move_to_workspace_3: Siirry työtilaan 3 - move_to_workspace_9: Siirry työtilaan 9 - switch_workspace_7: Vaihda työtilaan 7 - reserve_left: Varaa jäljellä - send_to_workspace_8: Lähetä työtilaan 8 - focus_latest: Focus -viimeisin - increase_width: Lisätä leveyttä - increase_height: Lisätä korkeutta - switch_workspace_2: Vaihda työtilaan 2 - move_to_workspace_1: Siirry työtilaan 1 - switch_workspace_3: Vaihda työtilaan 3 - move_to_workspace_7: Siirry työtilaan 7 - move_to_workspace_0: Siirry työtilaan 0 - switch_workspace_8: Vaihda työtilaan 8 - move_to_workspace_6: Siirry työtilaan 6 - focus_bottom: Tarkennuspohja - switch_workspace_5: Vaihda työtilaan 5 - decrease_height: Pienenee - focus_top: Keskittyä - focus_right: Keskittyä oikein - reserve_stack: Varantopino - reserve_float: Varaa kelluva - switch_workspace_9: Vaihda työtilaan 9 - switch_workspace_0: Vaihda työtilaan 0 - reserve_right: Varaa oikea - send_to_workspace_6: Lähetä työtilaan 6 - move_to_workspace_5: Siirry työtilaan 5 - switch_workspace_1: Vaihda työtilaan 1 - focus_left: Focus jäljellä - send_to_workspace_4: Lähetä työtilaan 4 - send_to_workspace_2: Lähetä työtilaan 2 - send_to_workspace_7: Lähetä työtilaan 7 - move_to_workspace_4: Siirry työtilaan 4 - send_to_workspace_3: Lähetä työtilaan 3 - enable_tooltip: >- - Poista käytöstä, jos otat käyttöön omat pikakuvakkeet Seelen Core - -sovellusliittymällä - enable: Ota integroidut pikakuvakkeet käyttöön (AHK) -inProgress: Käynnissä... -delete: Poistaa -quit: Lopettaa -save: Tallentaa -loading: Ladataan... -cancel: Peruuttaa -open: Avata +sides: + right: Oikea + bottom: Pohja + top: Ylhäältä + left: Vasen +header: + labels: + developer: Kehittäjä + info: Tiedot + seelen_bar: Hieno työkalurivi + seelen_weg: Telakka/tehtäväpalkki + seelen_wm: Ikkunanhallinta + shortcuts: Pikakuvakkeet + monitors: Näytöt + specific_apps: Erityiset sovellukset + general: Yleinen +start: + title: Tervetuloa! + message_accent: Optimoi tuottavuus tyylillä! + message: >- + Tervetuloa Seelen UI: hen, Ultimate Desktop -ympäristöön, jossa on + sisällytetty laatoitus Windows Manager, parantaaksesi Windows 11 + -kokemustasi! Tutustu uuteen tehokkuuden ja monitehtavan aikakauteen + intuitiivisella rajapinnalla ja edistyneillä ominaisuuksilla. +general: + theme: + description: Kuvaus + label: Teematiedot + added: Jo lisätty teema + enabled: Mahdolliset teemat + add: Lisätä teemaa + tags: Tunnisteet + author: Kirjoittaja + placeholder: Valitse teema + available: Saatavilla + selected: Valittu + language: Kieli + startup: Suorittaa käynnistyksen yhteydessä? + icon_pack: + label: Kuvakepakkaukset + accent_color: Korostusväri +toolbar: + placeholder: + description: Kuvaus + select: Työkalurivin rakenne + author: Kirjoittaja + height: Korkeus + enable: Ota hieno työkalurivi käyttöön +wm: + border: + offset: Rajan siirtyminen + enable: Ota ikkunan reuna käyttöön + width: Rajan leveys + layout: Layout + description: Kuvaus + workspace_padding: Työtilat + disabled_windows10: 'Windows Manager ei ole käytettävissä Windows 10: lle.' + enable: Ota ikkunanhallinta käyttöön + resize_delta: Muuttaa Delta (%) + space_between_containers: Konttien välinen tila + author: Kirjoittaja + workspace_offset: Työtilojen siirtymä (marginaalit) +weg: + items: + zoom_size: Zoomoitu koko (käytetty teemoihin) + size: Esineen koko + visible_separators: Näkyvät erottimet + gap: Tilaa esineiden välillä + label: Kohteet + width: Leveys + margin: Marginaali + gap: Kuilu + auto_hide: Automaattinen piilo + padding: Pehmuste + label: Telakka/tehtäväpalkki + enable: Ota Dock/tehtäväpalkki käyttöön + dock_side: Laituri +devtools: + load: Ladata + custom_config_file: Lataa mukautettu konfigurointitiedosto + settings_file: Asetustiedosto + data_folder: Tietokansio + enable: Ota kehittäjätyökalut käyttöön + install_folder: Asennuskansio + app_folders: Sovelluskansiot +apps_configurations: + app: + options: + force: Voimankäyttö + float: Kellua + unmanage: Hallinta + pinned: Kiinnitetty + category: Kategoria + title_create: '{{Nimi}} luominen' + title_edit: Muokkaaminen {{nimi}} + category_placeholder: Ei mitään + options_label: Ylimääräiset vaihtoehdot + ok_edit: Päivittää + workspace: Työtila + workspace_placeholder: Ei mitään + ok_create: Luoda + bindings: Sidonta (huomautus tarvitaan molemmat vaihtoehdot) + ok_readonly: Muokata UUSIA + monitor_placeholder: Ei mitään + name: Nimi + title_readonly: Katselu {{nimi}} + monitor: Monitori + identifier: + add_block: Lisätä + remove: Poistaa lohko + negation: Negatiivista vastaavuus + and: JA + kind: Tunnistaa jtk + matching_strategy: Sovitusstrategia + id: Tunniste + or: TAI + delete: Poistaa + new: Uusi + export: Viedä + confirm_delete: Haluatko varmasti poistaa tämän kokoonpanon/S? + swap: Vaihtaa + search: Hae + import: Tuonti + confirm_delete_title: Vahvista poistaminen + bundled_msg: >- + Näitä pauhutettuja kokoonpanoja ei voida muokata, ja ne on suunniteltu + tarjoamaan sinulle paras kokemus ilman räätälöintiä. Ne määrittelevät + sinulle yleisimmät sovellukset automaattisesti. + bundled_title: APP -konfigurointi, joka on mukana Seelenin kanssa +extras: + exit: Lopettaa/poistua + relaunch: Käynnistää uudelleen + links: Viralliset linkit + github: Github + version: Versio + discord: Erimielisyys +shortcuts: + labels: + reserve_bottom: Varata pohja + switch_workspace_6: Vaihda työtilaan 6 + switch_workspace_4: Vaihda työtilaan 4 + send_to_workspace_9: Lähetä työtilaan 9 + restore_sizes: Palauttaa koot + move_to_workspace_8: Siirry työtilaan 8 + send_to_workspace_0: Lähetä työtilaan 0 + reserve_top: Varaa + move_to_workspace_2: Siirry työtilaan 2 + decrease_width: Vähentynyt leveys + send_to_workspace_5: Lähetä työtilaan 5 + send_to_workspace_1: Lähetä työtilaan 1 + move_to_workspace_3: Siirry työtilaan 3 + move_to_workspace_9: Siirry työtilaan 9 + switch_workspace_7: Vaihda työtilaan 7 + reserve_left: Varaa jäljellä + send_to_workspace_8: Lähetä työtilaan 8 + focus_latest: Focus -viimeisin + increase_width: Lisätä leveyttä + increase_height: Lisätä korkeutta + switch_workspace_2: Vaihda työtilaan 2 + move_to_workspace_1: Siirry työtilaan 1 + switch_workspace_3: Vaihda työtilaan 3 + move_to_workspace_7: Siirry työtilaan 7 + move_to_workspace_0: Siirry työtilaan 0 + switch_workspace_8: Vaihda työtilaan 8 + move_to_workspace_6: Siirry työtilaan 6 + focus_bottom: Tarkennuspohja + switch_workspace_5: Vaihda työtilaan 5 + decrease_height: Pienenee + focus_top: Keskittyä + focus_right: Keskittyä oikein + reserve_stack: Varantopino + reserve_float: Varaa kelluva + switch_workspace_9: Vaihda työtilaan 9 + switch_workspace_0: Vaihda työtilaan 0 + reserve_right: Varaa oikea + send_to_workspace_6: Lähetä työtilaan 6 + move_to_workspace_5: Siirry työtilaan 5 + switch_workspace_1: Vaihda työtilaan 1 + focus_left: Focus jäljellä + send_to_workspace_4: Lähetä työtilaan 4 + send_to_workspace_2: Lähetä työtilaan 2 + send_to_workspace_7: Lähetä työtilaan 7 + move_to_workspace_4: Siirry työtilaan 4 + send_to_workspace_3: Lähetä työtilaan 3 + enable_tooltip: >- + Poista käytöstä, jos otat käyttöön omat pikakuvakkeet Seelen Core + -sovellusliittymällä + enable: Ota integroidut pikakuvakkeet käyttöön (AHK) +inProgress: Käynnissä... +delete: Poistaa +quit: Lopettaa +save: Tallentaa +loading: Ladataan... +cancel: Peruuttaa +open: Avata diff --git a/src/apps/settings/i18n/translations/fr.yml b/src/apps/settings/i18n/translations/fr.yml index 5a7aad48..57c1534b 100644 --- a/src/apps/settings/i18n/translations/fr.yml +++ b/src/apps/settings/i18n/translations/fr.yml @@ -1,191 +1,191 @@ -loading: Chargement... -inProgress: En cours... -cancel: Annuler -save: Sauvegarder -quit: Quitter -open: Ouvrir -delete: Supprimer -sides: - left: Gauche - right: Droite - top: Haut - bottom: Bas -header: - labels: - general: Général - seelen_bar: Barre d'outils sophistiquée - seelen_wm: Gestionnaire de fenêtres - seelen_weg: Dock/Barre des tâches - monitors: Moniteurs - specific_apps: Applications spécifiques - shortcuts: Raccourcis - developer: Développeur - info: Information -start: - title: Accueillir! - message: "Bienvenue dans Seelen UI, l'environnement de bureau ultime avec un gestionnaire de fenêtres en mosaïque intégré pour améliorer votre expérience Windows 11\_! Explorez une nouvelle ère d'efficacité et de multitâche avec notre interface intuitive et nos fonctionnalités avancées." - message_accent: Optimisez votre productivité avec style ! -general: - startup: Exécuter au démarrage? - language: Langue - theme: - label: Informations sur le thème - placeholder: Sélectionne un thème - author: Auteur - description: Description - add: Ajouter un thème - added: Thème déjà ajouté - enabled: Thèmes activés - tags: Mots clés - selected: Choisie - available: Disponible - icon_pack: - label: Packs d'icônes - accent_color: Couleur accent -toolbar: - enable: Activer la barre d'outils sophistiquée - placeholder: - select: Structure de la barre d'outils - author: Auteur - description: Description - height: Hauteur -wm: - enable: Activer le gestionnaire de fenêtres - disabled_windows10: Le gestionnaire de fenêtres n'est pas disponible pour Windows 10. - layout: Mise en page - author: Auteur - description: Description - space_between_containers: Espace entre les conteneurs - workspace_padding: Rembourrage des espaces de travail - workspace_offset: Décalage des espaces de travail (marges) - resize_delta: Redimensionner le Delta (%) - border: - enable: Activer la bordure de la fenêtre - width: Largeur de la bordure - offset: Décalage de bordure -weg: - label: Dock/Barre des tâches - enable: Activer le Dock/la barre des tâches - width: Largeur - auto_hide: Masquage automatique - dock_side: Côté quai - padding: Rembourrage - margin: Marge - gap: Écart - items: - label: Articles - size: Taille de l'article - zoom_size: Taille agrandie (utilisée pour les thèmes) - gap: Espace entre les éléments - visible_separators: Séparateurs visibles -devtools: - enable: Activer les outils de développement - app_folders: Dossiers d'applications - install_folder: Dossier d'installation - data_folder: Dossier de données - settings_file: Fichier de paramètres - custom_config_file: Charger le fichier de configuration personnalisé - load: Charger -apps_configurations: - import: Importer - export: Exporter - delete: Supprimer - swap: Échanger - new: Nouveau - bundled_title: Configuration de l'application fournie avec Seelen - bundled_msg: >- - Ces configurations groupées ne sont pas modifiables et sont conçues pour - vous offrir la meilleure expérience sans personnalisation. Ils configurent - automatiquement pour vous les applications les plus courantes. - confirm_delete_title: Confirmation de la suppression - confirm_delete: "Êtes-vous sûr de vouloir supprimer cette ou ces configurations\_?" - search: Recherche - app: - name: Nom - category: Catégorie - category_placeholder: Aucun - bindings: Reliure (notez que les deux options sont obligatoires) - monitor: Moniteur - monitor_placeholder: Aucun - workspace: Espace de travail - workspace_placeholder: Aucun - title_edit: Modification de {{name}} - title_create: Création de {{name}} - title_readonly: Affichage de {{name}} - ok_edit: Mise à jour - ok_create: Créer - ok_readonly: Modifier comme nouveau - options_label: Options supplémentaires - options: - float: Flotter - unmanage: Annuler la gestion - force: Forcer la gestion - pinned: Épinglé - identifier: - remove: Supprimer le bloc - id: Identifiant - kind: Identifier par - matching_strategy: Stratégie de correspondance - negation: Annuler la correspondance - and: ET - or: OU - add_block: Ajouter un bloc -extras: - version: Version - links: Liens officiels - github: GitHub - discord: Discorde - relaunch: Relance - exit: Quitter/Quitter -shortcuts: - enable: Activer les raccourcis intégrés (ahk) - enable_tooltip: >- - Désactivez si vous implémentez vos propres raccourcis à l'aide de l'API - Seelen Core - labels: - reserve_top: Réserver Haut - reserve_bottom: Fond de réserve - reserve_left: Réserver à gauche - reserve_right: Droit de réserve - reserve_float: Flotteur de réserve - reserve_stack: Pile de réserve - focus_top: Focus Haut - focus_bottom: Focus en bas - focus_left: Concentrez-vous à gauche - focus_right: Concentrez-vous à droite - focus_latest: Focus sur les dernières - increase_width: Augmenter la largeur - decrease_width: Diminuer la largeur - increase_height: Augmenter la hauteur - decrease_height: Diminuer la hauteur - restore_sizes: Restaurer les tailles - switch_workspace_0: Passer à l'espace de travail 0 - switch_workspace_1: Passer à l'espace de travail 1 - switch_workspace_2: Passer à l'espace de travail 2 - switch_workspace_3: Passer à l'espace de travail 3 - switch_workspace_4: Passer à l'espace de travail 4 - switch_workspace_5: Passer à l'espace de travail 5 - switch_workspace_6: Passer à l'espace de travail 6 - switch_workspace_7: Passer à Workspace 7 - switch_workspace_8: Passer à l'espace de travail 8 - switch_workspace_9: Passer à l'espace de travail 9 - move_to_workspace_0: Déplacer vers l'espace de travail 0 - move_to_workspace_1: Déplacer vers l'espace de travail 1 - move_to_workspace_2: Déplacer vers l'espace de travail 2 - move_to_workspace_3: Déplacer vers l'espace de travail 3 - move_to_workspace_4: Déplacer vers l'espace de travail 4 - move_to_workspace_5: Déplacer vers l'espace de travail 5 - move_to_workspace_6: Déplacer vers l'espace de travail 6 - move_to_workspace_7: Déplacer vers l'espace de travail 7 - move_to_workspace_8: Déplacer vers l'espace de travail 8 - move_to_workspace_9: Déplacer vers l'espace de travail 9 - send_to_workspace_0: Envoyer à l'espace de travail 0 - send_to_workspace_1: Envoyer à l'espace de travail 1 - send_to_workspace_2: Envoyer à l'espace de travail 2 - send_to_workspace_3: Envoyer à l'espace de travail 3 - send_to_workspace_4: Envoyer à l'espace de travail 4 - send_to_workspace_5: Envoyer à l'espace de travail 5 - send_to_workspace_6: Envoyer à l'espace de travail 6 - send_to_workspace_7: Envoyer à Workspace 7 - send_to_workspace_8: Envoyer à l'espace de travail 8 - send_to_workspace_9: Envoyer à l'espace de travail 9 +loading: Chargement... +inProgress: En cours... +cancel: Annuler +save: Sauvegarder +quit: Quitter +open: Ouvrir +delete: Supprimer +sides: + left: Gauche + right: Droite + top: Haut + bottom: Bas +header: + labels: + general: Général + seelen_bar: Barre d'outils sophistiquée + seelen_wm: Gestionnaire de fenêtres + seelen_weg: Dock/Barre des tâches + monitors: Moniteurs + specific_apps: Applications spécifiques + shortcuts: Raccourcis + developer: Développeur + info: Information +start: + title: Accueillir! + message: "Bienvenue dans Seelen UI, l'environnement de bureau ultime avec un gestionnaire de fenêtres en mosaïque intégré pour améliorer votre expérience Windows 11\_! Explorez une nouvelle ère d'efficacité et de multitâche avec notre interface intuitive et nos fonctionnalités avancées." + message_accent: Optimisez votre productivité avec style ! +general: + startup: Exécuter au démarrage? + language: Langue + theme: + label: Informations sur le thème + placeholder: Sélectionne un thème + author: Auteur + description: Description + add: Ajouter un thème + added: Thème déjà ajouté + enabled: Thèmes activés + tags: Mots clés + selected: Choisie + available: Disponible + icon_pack: + label: Packs d'icônes + accent_color: Couleur accent +toolbar: + enable: Activer la barre d'outils sophistiquée + placeholder: + select: Structure de la barre d'outils + author: Auteur + description: Description + height: Hauteur +wm: + enable: Activer le gestionnaire de fenêtres + disabled_windows10: Le gestionnaire de fenêtres n'est pas disponible pour Windows 10. + layout: Mise en page + author: Auteur + description: Description + space_between_containers: Espace entre les conteneurs + workspace_padding: Rembourrage des espaces de travail + workspace_offset: Décalage des espaces de travail (marges) + resize_delta: Redimensionner le Delta (%) + border: + enable: Activer la bordure de la fenêtre + width: Largeur de la bordure + offset: Décalage de bordure +weg: + label: Dock/Barre des tâches + enable: Activer le Dock/la barre des tâches + width: Largeur + auto_hide: Masquage automatique + dock_side: Côté quai + padding: Rembourrage + margin: Marge + gap: Écart + items: + label: Articles + size: Taille de l'article + zoom_size: Taille agrandie (utilisée pour les thèmes) + gap: Espace entre les éléments + visible_separators: Séparateurs visibles +devtools: + enable: Activer les outils de développement + app_folders: Dossiers d'applications + install_folder: Dossier d'installation + data_folder: Dossier de données + settings_file: Fichier de paramètres + custom_config_file: Charger le fichier de configuration personnalisé + load: Charger +apps_configurations: + import: Importer + export: Exporter + delete: Supprimer + swap: Échanger + new: Nouveau + bundled_title: Configuration de l'application fournie avec Seelen + bundled_msg: >- + Ces configurations groupées ne sont pas modifiables et sont conçues pour + vous offrir la meilleure expérience sans personnalisation. Ils configurent + automatiquement pour vous les applications les plus courantes. + confirm_delete_title: Confirmation de la suppression + confirm_delete: "Êtes-vous sûr de vouloir supprimer cette ou ces configurations\_?" + search: Recherche + app: + name: Nom + category: Catégorie + category_placeholder: Aucun + bindings: Reliure (notez que les deux options sont obligatoires) + monitor: Moniteur + monitor_placeholder: Aucun + workspace: Espace de travail + workspace_placeholder: Aucun + title_edit: Modification de {{name}} + title_create: Création de {{name}} + title_readonly: Affichage de {{name}} + ok_edit: Mise à jour + ok_create: Créer + ok_readonly: Modifier comme nouveau + options_label: Options supplémentaires + options: + float: Flotter + unmanage: Annuler la gestion + force: Forcer la gestion + pinned: Épinglé + identifier: + remove: Supprimer le bloc + id: Identifiant + kind: Identifier par + matching_strategy: Stratégie de correspondance + negation: Annuler la correspondance + and: ET + or: OU + add_block: Ajouter un bloc +extras: + version: Version + links: Liens officiels + github: GitHub + discord: Discorde + relaunch: Relance + exit: Quitter/Quitter +shortcuts: + enable: Activer les raccourcis intégrés (ahk) + enable_tooltip: >- + Désactivez si vous implémentez vos propres raccourcis à l'aide de l'API + Seelen Core + labels: + reserve_top: Réserver Haut + reserve_bottom: Fond de réserve + reserve_left: Réserver à gauche + reserve_right: Droit de réserve + reserve_float: Flotteur de réserve + reserve_stack: Pile de réserve + focus_top: Focus Haut + focus_bottom: Focus en bas + focus_left: Concentrez-vous à gauche + focus_right: Concentrez-vous à droite + focus_latest: Focus sur les dernières + increase_width: Augmenter la largeur + decrease_width: Diminuer la largeur + increase_height: Augmenter la hauteur + decrease_height: Diminuer la hauteur + restore_sizes: Restaurer les tailles + switch_workspace_0: Passer à l'espace de travail 0 + switch_workspace_1: Passer à l'espace de travail 1 + switch_workspace_2: Passer à l'espace de travail 2 + switch_workspace_3: Passer à l'espace de travail 3 + switch_workspace_4: Passer à l'espace de travail 4 + switch_workspace_5: Passer à l'espace de travail 5 + switch_workspace_6: Passer à l'espace de travail 6 + switch_workspace_7: Passer à Workspace 7 + switch_workspace_8: Passer à l'espace de travail 8 + switch_workspace_9: Passer à l'espace de travail 9 + move_to_workspace_0: Déplacer vers l'espace de travail 0 + move_to_workspace_1: Déplacer vers l'espace de travail 1 + move_to_workspace_2: Déplacer vers l'espace de travail 2 + move_to_workspace_3: Déplacer vers l'espace de travail 3 + move_to_workspace_4: Déplacer vers l'espace de travail 4 + move_to_workspace_5: Déplacer vers l'espace de travail 5 + move_to_workspace_6: Déplacer vers l'espace de travail 6 + move_to_workspace_7: Déplacer vers l'espace de travail 7 + move_to_workspace_8: Déplacer vers l'espace de travail 8 + move_to_workspace_9: Déplacer vers l'espace de travail 9 + send_to_workspace_0: Envoyer à l'espace de travail 0 + send_to_workspace_1: Envoyer à l'espace de travail 1 + send_to_workspace_2: Envoyer à l'espace de travail 2 + send_to_workspace_3: Envoyer à l'espace de travail 3 + send_to_workspace_4: Envoyer à l'espace de travail 4 + send_to_workspace_5: Envoyer à l'espace de travail 5 + send_to_workspace_6: Envoyer à l'espace de travail 6 + send_to_workspace_7: Envoyer à Workspace 7 + send_to_workspace_8: Envoyer à l'espace de travail 8 + send_to_workspace_9: Envoyer à l'espace de travail 9 diff --git a/src/apps/settings/i18n/translations/gu.yml b/src/apps/settings/i18n/translations/gu.yml index 5541261e..5d993393 100644 --- a/src/apps/settings/i18n/translations/gu.yml +++ b/src/apps/settings/i18n/translations/gu.yml @@ -1,195 +1,195 @@ -sides: - right: અધિકાર - left: ડાબી - top: ટોચ - bottom: તળિયે -header: - labels: - seelen_weg: ડોક/ટાસ્કબાર - monitors: મોનિટર - general: જનરલ - developer: વિકાસકર્તા - seelen_bar: ફેન્સી ટૂલબાર - shortcuts: શૉર્ટકટ્સ - info: માહિતી - specific_apps: વિશિષ્ટ એપ્લિકેશનો - seelen_wm: વિન્ડો મેનેજર -start: - title: સ્વાગત છે! - message_accent: શૈલી સાથે તમારી ઉત્પાદકતાને ઑપ્ટિમાઇઝ કરો! - message: >- - તમારા Windows 11 અનુભવને વધારવા માટે સમાવિષ્ટ ટાઇલિંગ વિન્ડોઝ મેનેજર સાથે - અંતિમ ડેસ્કટોપ પર્યાવરણ, સીલેન UI માં આપનું સ્વાગત છે! અમારા સાહજિક ઇન્ટરફેસ - અને અદ્યતન સુવિધાઓ સાથે કાર્યક્ષમતા અને મલ્ટિટાસ્કિંગના નવા યુગનું અન્વેષણ - કરો. -general: - theme: - placeholder: થીમ પસંદ કરો - description: વર્ણન - author: લેખક - tags: ટૅગ્સ - added: થીમ પહેલેથી જ ઉમેરવામાં આવી છે - enabled: સક્ષમ થીમ્સ - add: થીમ ઉમેરો - label: થીમ માહિતી - available: ઉપલબ્ધ - selected: પસંદ કરેલું - language: ભાષા - startup: સ્ટાર્ટઅપ પર ચલાવો? - icon_pack: - label: ચિહ્ન - accent_color: ઉચ્ચારણ રંગ -toolbar: - placeholder: - author: લેખક - description: વર્ણન - select: ટૂલબાર માળખું - height: ઊંચાઈ - enable: ફેન્સી ટૂલબાર સક્ષમ કરો -wm: - border: - width: સરહદની પહોળાઈ - offset: બોર્ડર ઓફસેટ - enable: વિન્ડોની બોર્ડર સક્ષમ કરો - layout: લેઆઉટ - space_between_containers: કન્ટેનર વચ્ચે જગ્યા - enable: વિન્ડો મેનેજરને સક્ષમ કરો - workspace_offset: વર્કસ્પેસ ઓફસેટ (માર્જિન) - workspace_padding: વર્કસ્પેસ પેડિંગ - disabled_windows10: વિન્ડોઝ 10 માટે વિન્ડો મેનેજર ઉપલબ્ધ નથી. - description: વર્ણન - author: લેખક - resize_delta: ડેલ્ટાનું કદ બદલો (%) -weg: - items: - label: વસ્તુઓ - visible_separators: દૃશ્યમાન વિભાજક - zoom_size: ઝૂમ કરેલ કદ (થીમ્સ માટે વપરાયેલ) - size: વસ્તુનું કદ - gap: વસ્તુઓ વચ્ચે જગ્યા - label: ડોક/ટાસ્કબાર - auto_hide: સ્વતઃ છુપાવો - margin: માર્જિન - padding: ગાદી - enable: ડોક/ટાસ્કબારને સક્ષમ કરો - width: પહોળાઈ - gap: ગેપ - dock_side: ડોક સાઇડ -devtools: - install_folder: ઇન્સ્ટોલેશન ફોલ્ડર - custom_config_file: કસ્ટમ રૂપરેખા ફાઇલ લોડ કરો - enable: વિકાસકર્તા સાધનો સક્ષમ કરો - settings_file: સેટિંગ્સ ફાઇલ - app_folders: એપ્લિકેશન ફોલ્ડર્સ - load: લોડ - data_folder: ડેટા ફોલ્ડર -apps_configurations: - app: - options: - float: ફ્લોટ - pinned: પિન કરેલ - unmanage: અનમેનેજ કરો - force: ફોર્સ મેનેજ કરો - options_label: વધારાના વિકલ્પો - title_create: '{{name}} બનાવી રહ્યાં છીએ' - workspace_placeholder: કોઈ નહિ - workspace: વર્કસ્પેસ - category_placeholder: કોઈ નહિ - monitor_placeholder: કોઈ નહિ - name: નામ - ok_readonly: નવા તરીકે સંપાદિત કરો - monitor: મોનીટર - category: શ્રેણી - ok_edit: અપડેટ કરો - title_readonly: '{{name}} જોઈ રહ્યાં છીએ' - bindings: બંધનકર્તા (નોંધો કે બંને વિકલ્પો જરૂરી છે) - title_edit: સંપાદન {{name}} - ok_create: બનાવો - identifier: - remove: બ્લોક કાઢી નાખો - add_block: બ્લોક ઉમેરો - negation: નેગેટ મેચિંગ - and: અને - or: અથવા - kind: દ્વારા ઓળખો - matching_strategy: મેચિંગ સ્ટ્રેટેજી - id: ઓળખકર્તા - new: નવી - swap: સ્વેપ - search: શોધો - import: આયાત કરો - bundled_title: સીલેન સાથે બંડલ કરેલ એપ્લિકેશન રૂપરેખા - export: નિકાસ કરો - bundled_msg: >- - આ બંડલ કરેલ રૂપરેખાંકનો સંપાદનયોગ્ય નથી અને કસ્ટમાઇઝેશન વિના તમને શ્રેષ્ઠ - અનુભવ પ્રદાન કરવા માટે રચાયેલ છે. તેઓ આપમેળે તમારા માટે સૌથી સામાન્ય - એપ્લિકેશનોને ગોઠવે છે. - confirm_delete_title: કાઢી નાખવાની પુષ્ટિ કરો - delete: કાઢી નાખો - confirm_delete: શું તમે ખરેખર આ ગોઠવણી/ઓ કાઢી નાખવા માંગો છો? -extras: - github: GitHub - version: સંસ્કરણ - links: સત્તાવાર લિંક્સ - exit: છોડો/બહાર નીકળો - discord: વિખવાદ - relaunch: ફરીથી લોંચ કરો -shortcuts: - labels: - send_to_workspace_2: વર્કસ્પેસ 2 પર મોકલો - send_to_workspace_1: વર્કસ્પેસ 1 પર મોકલો - switch_workspace_0: વર્કસ્પેસ 0 પર સ્વિચ કરો - switch_workspace_1: વર્કસ્પેસ 1 પર સ્વિચ કરો - switch_workspace_6: વર્કસ્પેસ 6 પર સ્વિચ કરો - send_to_workspace_7: વર્કસ્પેસ પર મોકલો 7 - send_to_workspace_5: વર્કસ્પેસ 5 પર મોકલો - send_to_workspace_9: વર્કસ્પેસ પર મોકલો 9 - move_to_workspace_2: વર્કસ્પેસ 2 પર ખસેડો - move_to_workspace_5: વર્કસ્પેસ 5 પર જાઓ - focus_latest: ફોકસ લેટેસ્ટ - send_to_workspace_3: વર્કસ્પેસ પર મોકલો 3 - move_to_workspace_4: વર્કસ્પેસ 4 પર ખસેડો - restore_sizes: કદ પુનઃસ્થાપિત કરો - reserve_float: રિઝર્વ ફ્લોટ - focus_right: જમણે ફોકસ કરો - increase_height: ઊંચાઈ વધારો - move_to_workspace_9: વર્કસ્પેસ પર ખસેડો 9 - move_to_workspace_7: વર્કસ્પેસ 7 પર જાઓ - send_to_workspace_4: વર્કસ્પેસ 4 પર મોકલો - send_to_workspace_0: વર્કસ્પેસ 0 પર મોકલો - focus_left: ડાબે ફોકસ કરો - reserve_stack: અનામત સ્ટેક - switch_workspace_5: વર્કસ્પેસ 5 પર સ્વિચ કરો - reserve_left: ડાબી બાજુ અનામત રાખો - move_to_workspace_6: વર્કસ્પેસ 6 પર જાઓ - reserve_top: અનામત ટોચ - decrease_height: ઊંચાઈ ઘટાડો - move_to_workspace_1: વર્કસ્પેસ 1 પર ખસેડો - reserve_bottom: અનામત નીચે - send_to_workspace_6: વર્કસ્પેસ પર મોકલો 6 - switch_workspace_8: વર્કસ્પેસ 8 પર સ્વિચ કરો - move_to_workspace_8: વર્કસ્પેસ 8 પર જાઓ - switch_workspace_2: વર્કસ્પેસ 2 પર સ્વિચ કરો - focus_top: ફોકસ ટોપ - move_to_workspace_0: વર્કસ્પેસ 0 પર ખસેડો - decrease_width: પહોળાઈ ઘટાડો - move_to_workspace_3: વર્કસ્પેસ 3 પર ખસેડો - increase_width: પહોળાઈ વધારો - switch_workspace_4: વર્કસ્પેસ 4 પર સ્વિચ કરો - send_to_workspace_8: વર્કસ્પેસ 8 પર મોકલો - reserve_right: અનામત અધિકાર - switch_workspace_9: વર્કસ્પેસ 9 પર સ્વિચ કરો - switch_workspace_3: વર્કસ્પેસ 3 પર સ્વિચ કરો - focus_bottom: ફોકસ બોટમ - switch_workspace_7: વર્કસ્પેસ 7 પર સ્વિચ કરો - enable_tooltip: >- - જો તમે સીલેન કોર એપીઆઈનો ઉપયોગ કરીને તમારા પોતાના શોર્ટકટ્સનો અમલ કરશો તો - અક્ષમ કરો - enable: સંકલિત શૉર્ટકટ્સ સક્ષમ કરો (ahk) -open: ખુલ્લા -delete: કાઢી નાખો -save: સાચવો -loading: લોડ કરી રહ્યું છે... -inProgress: ચાલુ છે... -cancel: રદ કરો -quit: છોડો +sides: + right: અધિકાર + left: ડાબી + top: ટોચ + bottom: તળિયે +header: + labels: + seelen_weg: ડોક/ટાસ્કબાર + monitors: મોનિટર + general: જનરલ + developer: વિકાસકર્તા + seelen_bar: ફેન્સી ટૂલબાર + shortcuts: શૉર્ટકટ્સ + info: માહિતી + specific_apps: વિશિષ્ટ એપ્લિકેશનો + seelen_wm: વિન્ડો મેનેજર +start: + title: સ્વાગત છે! + message_accent: શૈલી સાથે તમારી ઉત્પાદકતાને ઑપ્ટિમાઇઝ કરો! + message: >- + તમારા Windows 11 અનુભવને વધારવા માટે સમાવિષ્ટ ટાઇલિંગ વિન્ડોઝ મેનેજર સાથે + અંતિમ ડેસ્કટોપ પર્યાવરણ, સીલેન UI માં આપનું સ્વાગત છે! અમારા સાહજિક ઇન્ટરફેસ + અને અદ્યતન સુવિધાઓ સાથે કાર્યક્ષમતા અને મલ્ટિટાસ્કિંગના નવા યુગનું અન્વેષણ + કરો. +general: + theme: + placeholder: થીમ પસંદ કરો + description: વર્ણન + author: લેખક + tags: ટૅગ્સ + added: થીમ પહેલેથી જ ઉમેરવામાં આવી છે + enabled: સક્ષમ થીમ્સ + add: થીમ ઉમેરો + label: થીમ માહિતી + available: ઉપલબ્ધ + selected: પસંદ કરેલું + language: ભાષા + startup: સ્ટાર્ટઅપ પર ચલાવો? + icon_pack: + label: ચિહ્ન + accent_color: ઉચ્ચારણ રંગ +toolbar: + placeholder: + author: લેખક + description: વર્ણન + select: ટૂલબાર માળખું + height: ઊંચાઈ + enable: ફેન્સી ટૂલબાર સક્ષમ કરો +wm: + border: + width: સરહદની પહોળાઈ + offset: બોર્ડર ઓફસેટ + enable: વિન્ડોની બોર્ડર સક્ષમ કરો + layout: લેઆઉટ + space_between_containers: કન્ટેનર વચ્ચે જગ્યા + enable: વિન્ડો મેનેજરને સક્ષમ કરો + workspace_offset: વર્કસ્પેસ ઓફસેટ (માર્જિન) + workspace_padding: વર્કસ્પેસ પેડિંગ + disabled_windows10: વિન્ડોઝ 10 માટે વિન્ડો મેનેજર ઉપલબ્ધ નથી. + description: વર્ણન + author: લેખક + resize_delta: ડેલ્ટાનું કદ બદલો (%) +weg: + items: + label: વસ્તુઓ + visible_separators: દૃશ્યમાન વિભાજક + zoom_size: ઝૂમ કરેલ કદ (થીમ્સ માટે વપરાયેલ) + size: વસ્તુનું કદ + gap: વસ્તુઓ વચ્ચે જગ્યા + label: ડોક/ટાસ્કબાર + auto_hide: સ્વતઃ છુપાવો + margin: માર્જિન + padding: ગાદી + enable: ડોક/ટાસ્કબારને સક્ષમ કરો + width: પહોળાઈ + gap: ગેપ + dock_side: ડોક સાઇડ +devtools: + install_folder: ઇન્સ્ટોલેશન ફોલ્ડર + custom_config_file: કસ્ટમ રૂપરેખા ફાઇલ લોડ કરો + enable: વિકાસકર્તા સાધનો સક્ષમ કરો + settings_file: સેટિંગ્સ ફાઇલ + app_folders: એપ્લિકેશન ફોલ્ડર્સ + load: લોડ + data_folder: ડેટા ફોલ્ડર +apps_configurations: + app: + options: + float: ફ્લોટ + pinned: પિન કરેલ + unmanage: અનમેનેજ કરો + force: ફોર્સ મેનેજ કરો + options_label: વધારાના વિકલ્પો + title_create: '{{name}} બનાવી રહ્યાં છીએ' + workspace_placeholder: કોઈ નહિ + workspace: વર્કસ્પેસ + category_placeholder: કોઈ નહિ + monitor_placeholder: કોઈ નહિ + name: નામ + ok_readonly: નવા તરીકે સંપાદિત કરો + monitor: મોનીટર + category: શ્રેણી + ok_edit: અપડેટ કરો + title_readonly: '{{name}} જોઈ રહ્યાં છીએ' + bindings: બંધનકર્તા (નોંધો કે બંને વિકલ્પો જરૂરી છે) + title_edit: સંપાદન {{name}} + ok_create: બનાવો + identifier: + remove: બ્લોક કાઢી નાખો + add_block: બ્લોક ઉમેરો + negation: નેગેટ મેચિંગ + and: અને + or: અથવા + kind: દ્વારા ઓળખો + matching_strategy: મેચિંગ સ્ટ્રેટેજી + id: ઓળખકર્તા + new: નવી + swap: સ્વેપ + search: શોધો + import: આયાત કરો + bundled_title: સીલેન સાથે બંડલ કરેલ એપ્લિકેશન રૂપરેખા + export: નિકાસ કરો + bundled_msg: >- + આ બંડલ કરેલ રૂપરેખાંકનો સંપાદનયોગ્ય નથી અને કસ્ટમાઇઝેશન વિના તમને શ્રેષ્ઠ + અનુભવ પ્રદાન કરવા માટે રચાયેલ છે. તેઓ આપમેળે તમારા માટે સૌથી સામાન્ય + એપ્લિકેશનોને ગોઠવે છે. + confirm_delete_title: કાઢી નાખવાની પુષ્ટિ કરો + delete: કાઢી નાખો + confirm_delete: શું તમે ખરેખર આ ગોઠવણી/ઓ કાઢી નાખવા માંગો છો? +extras: + github: GitHub + version: સંસ્કરણ + links: સત્તાવાર લિંક્સ + exit: છોડો/બહાર નીકળો + discord: વિખવાદ + relaunch: ફરીથી લોંચ કરો +shortcuts: + labels: + send_to_workspace_2: વર્કસ્પેસ 2 પર મોકલો + send_to_workspace_1: વર્કસ્પેસ 1 પર મોકલો + switch_workspace_0: વર્કસ્પેસ 0 પર સ્વિચ કરો + switch_workspace_1: વર્કસ્પેસ 1 પર સ્વિચ કરો + switch_workspace_6: વર્કસ્પેસ 6 પર સ્વિચ કરો + send_to_workspace_7: વર્કસ્પેસ પર મોકલો 7 + send_to_workspace_5: વર્કસ્પેસ 5 પર મોકલો + send_to_workspace_9: વર્કસ્પેસ પર મોકલો 9 + move_to_workspace_2: વર્કસ્પેસ 2 પર ખસેડો + move_to_workspace_5: વર્કસ્પેસ 5 પર જાઓ + focus_latest: ફોકસ લેટેસ્ટ + send_to_workspace_3: વર્કસ્પેસ પર મોકલો 3 + move_to_workspace_4: વર્કસ્પેસ 4 પર ખસેડો + restore_sizes: કદ પુનઃસ્થાપિત કરો + reserve_float: રિઝર્વ ફ્લોટ + focus_right: જમણે ફોકસ કરો + increase_height: ઊંચાઈ વધારો + move_to_workspace_9: વર્કસ્પેસ પર ખસેડો 9 + move_to_workspace_7: વર્કસ્પેસ 7 પર જાઓ + send_to_workspace_4: વર્કસ્પેસ 4 પર મોકલો + send_to_workspace_0: વર્કસ્પેસ 0 પર મોકલો + focus_left: ડાબે ફોકસ કરો + reserve_stack: અનામત સ્ટેક + switch_workspace_5: વર્કસ્પેસ 5 પર સ્વિચ કરો + reserve_left: ડાબી બાજુ અનામત રાખો + move_to_workspace_6: વર્કસ્પેસ 6 પર જાઓ + reserve_top: અનામત ટોચ + decrease_height: ઊંચાઈ ઘટાડો + move_to_workspace_1: વર્કસ્પેસ 1 પર ખસેડો + reserve_bottom: અનામત નીચે + send_to_workspace_6: વર્કસ્પેસ પર મોકલો 6 + switch_workspace_8: વર્કસ્પેસ 8 પર સ્વિચ કરો + move_to_workspace_8: વર્કસ્પેસ 8 પર જાઓ + switch_workspace_2: વર્કસ્પેસ 2 પર સ્વિચ કરો + focus_top: ફોકસ ટોપ + move_to_workspace_0: વર્કસ્પેસ 0 પર ખસેડો + decrease_width: પહોળાઈ ઘટાડો + move_to_workspace_3: વર્કસ્પેસ 3 પર ખસેડો + increase_width: પહોળાઈ વધારો + switch_workspace_4: વર્કસ્પેસ 4 પર સ્વિચ કરો + send_to_workspace_8: વર્કસ્પેસ 8 પર મોકલો + reserve_right: અનામત અધિકાર + switch_workspace_9: વર્કસ્પેસ 9 પર સ્વિચ કરો + switch_workspace_3: વર્કસ્પેસ 3 પર સ્વિચ કરો + focus_bottom: ફોકસ બોટમ + switch_workspace_7: વર્કસ્પેસ 7 પર સ્વિચ કરો + enable_tooltip: >- + જો તમે સીલેન કોર એપીઆઈનો ઉપયોગ કરીને તમારા પોતાના શોર્ટકટ્સનો અમલ કરશો તો + અક્ષમ કરો + enable: સંકલિત શૉર્ટકટ્સ સક્ષમ કરો (ahk) +open: ખુલ્લા +delete: કાઢી નાખો +save: સાચવો +loading: લોડ કરી રહ્યું છે... +inProgress: ચાલુ છે... +cancel: રદ કરો +quit: છોડો diff --git a/src/apps/settings/i18n/translations/he.yml b/src/apps/settings/i18n/translations/he.yml index 06725ccf..2aea1249 100644 --- a/src/apps/settings/i18n/translations/he.yml +++ b/src/apps/settings/i18n/translations/he.yml @@ -1,191 +1,191 @@ -sides: - bottom: תַחתִית - right: ימין - left: שמאלה - top: חלק עליון -header: - labels: - developer: מפתח - info: מֵידָע - specific_apps: אפליקציות ספציפיות - general: כללי - seelen_weg: שורת המזח/המשימות - shortcuts: קיצורי דרך - seelen_wm: מנהל חלונות - seelen_bar: סרגל כלים מפואר - monitors: צגים -start: - title: ברוך הבא! - message: >- - ברוך הבא ל- Seelen UI, סביבת שולחן העבודה האולטימטיבית עם מנהל Windows משולב - אריחים כדי לשפר את חווית Windows 11 שלך! חקור עידן חדש של יעילות ורב משימות - עם הממשק האינטואיטיבי והתכונות המתקדמות שלנו. - message_accent: אופטימיזציה של הפרודוקטיביות שלך עם סגנון! -general: - theme: - author: מְחַבֵּר - description: תיאור - label: מידע על נושא - enabled: נושאים מופעלים - tags: תגיות - added: הנושא כבר הוסיף - placeholder: בחר נושא - add: הוסף נושא - selected: נבחר - available: זמין - language: שפה - startup: לרוץ בהפעלה? - icon_pack: - label: חבילות אייקונים - accent_color: צבע הדגשה -toolbar: - placeholder: - author: מְחַבֵּר - description: תיאור - select: מבנה סרגל הכלים - height: גוֹבַה - enable: אפשר סרגל כלים מפואר -wm: - border: - offset: קיזוז גבול - width: רוחב גבול - enable: אפשר את גבול החלון - space_between_containers: מרחב בין מכולות - layout: מַעֲרָך - author: מְחַבֵּר - disabled_windows10: מנהל החלונות אינו זמין עבור Windows 10. - description: תיאור - workspace_padding: מרחבי עבודה ריפוד - enable: אפשר מנהל חלונות - resize_delta: שינוי גודל דלתא (%) - workspace_offset: מרחבי עבודה קיזזו (שוליים) -weg: - items: - gap: שטח בין פריטים - label: פריטים - visible_separators: מפרידים גלויים - zoom_size: גודל מתקרב (משמש לנושאים) - size: גודל פריט - width: רוֹחַב - gap: פער - auto_hide: הסתר אוטומטי - label: שורת המזח/המשימות - margin: שולים - enable: הפעל את המזח/שורת המשימות - dock_side: צד המזח - padding: ריפוד -devtools: - load: לִטעוֹן - install_folder: תיקיית התקנה - custom_config_file: טען קובץ תצורה מותאם אישית - data_folder: תיקיית נתונים - app_folders: תיקיות אפליקציות - settings_file: קובץ הגדרות - enable: אפשר כלי מפתחים -apps_configurations: - app: - options: - float: לָצוּף - force: כוח לנהל - pinned: מוצמד - unmanage: לא מנוהל - name: שֵׁם - monitor_placeholder: אף אחד - category_placeholder: אף אחד - ok_edit: עדכון - bindings: כריכה (שימו לב לשתי האפשרויות נדרשות) - category: קטגוריה - title_edit: עריכה {{name}} - ok_readonly: ערוך כחדש - monitor: צג - options_label: אפשרויות נוספות - ok_create: לִיצוֹר - workspace_placeholder: אף אחד - title_create: יצירת {{name}} - workspace: סביבת עבודה - title_readonly: צופה {{name}} - identifier: - id: מזהה - or: אוֹ - and: וכן - add_block: הוסף בלוק - kind: לזהות על ידי - remove: מחק בלוק - matching_strategy: אסטרטגיה תואמת - negation: שולל התאמה - new: חָדָשׁ - search: לחפש - confirm_delete: האם אתה בטוח שברצונך למחוק תצורה/ים אלה? - export: יְצוּא - delete: לִמְחוֹק - import: יְבוּא - swap: לְהַחלִיף - confirm_delete_title: אשר מחק - bundled_title: תצורת אפליקציה מצורפת עם Seelen - bundled_msg: >- - תצורות מצורפות אלה אינן ניתנות לעריכה ונועדו לספק לך את החוויה הטובה ביותר - ללא התאמה אישית. הם מגדירים באופן אוטומטי את היישומים הנפוצים ביותר עבורך. -extras: - discord: מַחֲלוֹקֶת - relaunch: השקה מחדש - github: Github - version: גִרְסָה - links: קישורים רשמיים - exit: יצא/יציאה -shortcuts: - labels: - move_to_workspace_4: עברו לסביבת העבודה 4 - move_to_workspace_9: עברו לסביבת העבודה 9 - switch_workspace_3: עבור לסביבת העבודה 3 - switch_workspace_4: עברו לסביבת העבודה 4 - switch_workspace_8: עברו לסביבת העבודה 8 - decrease_width: ירידה ברוחב - focus_latest: התמקד האחרון - send_to_workspace_3: שלח לסביבת העבודה 3 - reserve_bottom: שמורה בתחתית - move_to_workspace_8: עברו לסביבת העבודה 8 - reserve_stack: ערימת מילואים - switch_workspace_7: לעבור לסביבת עבודה 7 - move_to_workspace_0: עברו לסביבת העבודה 0 - reserve_right: שמור ימינה - move_to_workspace_6: עברו לסביבת העבודה 6 - send_to_workspace_9: שלח לסביבת העבודה 9 - send_to_workspace_0: שלח לסביבת עבודה 0 - move_to_workspace_2: לעבור לסביבת העבודה 2 - move_to_workspace_1: לעבור לסביבת העבודה 1 - switch_workspace_1: עבור לסביבת העבודה 1 - increase_width: הגדל את הרוחב - move_to_workspace_7: לעבור לסביבת העבודה 7 - send_to_workspace_5: שלח לסביבת העבודה 5 - restore_sizes: שחזור גדלים - increase_height: הגדל את הגובה - move_to_workspace_5: לעבור לסביבת העבודה 5 - switch_workspace_5: עברו לסביבת העבודה 5 - focus_top: מיקוד למעלה - focus_right: להתמקד נכון - send_to_workspace_1: שלח לסביבת עבודה 1 - switch_workspace_9: עבור לסביבת העבודה 9 - reserve_top: עליון מילואים - switch_workspace_6: לעבור לסביבת עבודה 6 - switch_workspace_0: לעבור לסביבת עבודה 0 - focus_bottom: מיקוד תחתון - send_to_workspace_4: שלח לסביבת העבודה 4 - switch_workspace_2: עבור לסביבת העבודה 2 - reserve_float: שמורה לצוף - send_to_workspace_7: שלח לסביבת עבודה 7 - send_to_workspace_6: שלח לסביבת עבודה 6 - focus_left: פוקוס שמאלה - reserve_left: רזרבה שמאלה - move_to_workspace_3: לעבור לסביבת העבודה 3 - send_to_workspace_8: שלח לסביבת עבודה 8 - send_to_workspace_2: שלח לסביבת עבודה 2 - decrease_height: ירידה בגובה - enable: אפשר קיצורי דרך משולבים (AHK) - enable_tooltip: השבת אם תיישם קיצורי דרך משלך באמצעות ממשק ה- API של Seelen Core -inProgress: בתהליך... -loading: טוען... -open: לִפְתוֹחַ -cancel: לְבַטֵל -quit: לְהַפְסִיק -delete: לִמְחוֹק -save: להציל +sides: + bottom: תַחתִית + right: ימין + left: שמאלה + top: חלק עליון +header: + labels: + developer: מפתח + info: מֵידָע + specific_apps: אפליקציות ספציפיות + general: כללי + seelen_weg: שורת המזח/המשימות + shortcuts: קיצורי דרך + seelen_wm: מנהל חלונות + seelen_bar: סרגל כלים מפואר + monitors: צגים +start: + title: ברוך הבא! + message: >- + ברוך הבא ל- Seelen UI, סביבת שולחן העבודה האולטימטיבית עם מנהל Windows משולב + אריחים כדי לשפר את חווית Windows 11 שלך! חקור עידן חדש של יעילות ורב משימות + עם הממשק האינטואיטיבי והתכונות המתקדמות שלנו. + message_accent: אופטימיזציה של הפרודוקטיביות שלך עם סגנון! +general: + theme: + author: מְחַבֵּר + description: תיאור + label: מידע על נושא + enabled: נושאים מופעלים + tags: תגיות + added: הנושא כבר הוסיף + placeholder: בחר נושא + add: הוסף נושא + selected: נבחר + available: זמין + language: שפה + startup: לרוץ בהפעלה? + icon_pack: + label: חבילות אייקונים + accent_color: צבע הדגשה +toolbar: + placeholder: + author: מְחַבֵּר + description: תיאור + select: מבנה סרגל הכלים + height: גוֹבַה + enable: אפשר סרגל כלים מפואר +wm: + border: + offset: קיזוז גבול + width: רוחב גבול + enable: אפשר את גבול החלון + space_between_containers: מרחב בין מכולות + layout: מַעֲרָך + author: מְחַבֵּר + disabled_windows10: מנהל החלונות אינו זמין עבור Windows 10. + description: תיאור + workspace_padding: מרחבי עבודה ריפוד + enable: אפשר מנהל חלונות + resize_delta: שינוי גודל דלתא (%) + workspace_offset: מרחבי עבודה קיזזו (שוליים) +weg: + items: + gap: שטח בין פריטים + label: פריטים + visible_separators: מפרידים גלויים + zoom_size: גודל מתקרב (משמש לנושאים) + size: גודל פריט + width: רוֹחַב + gap: פער + auto_hide: הסתר אוטומטי + label: שורת המזח/המשימות + margin: שולים + enable: הפעל את המזח/שורת המשימות + dock_side: צד המזח + padding: ריפוד +devtools: + load: לִטעוֹן + install_folder: תיקיית התקנה + custom_config_file: טען קובץ תצורה מותאם אישית + data_folder: תיקיית נתונים + app_folders: תיקיות אפליקציות + settings_file: קובץ הגדרות + enable: אפשר כלי מפתחים +apps_configurations: + app: + options: + float: לָצוּף + force: כוח לנהל + pinned: מוצמד + unmanage: לא מנוהל + name: שֵׁם + monitor_placeholder: אף אחד + category_placeholder: אף אחד + ok_edit: עדכון + bindings: כריכה (שימו לב לשתי האפשרויות נדרשות) + category: קטגוריה + title_edit: עריכה {{name}} + ok_readonly: ערוך כחדש + monitor: צג + options_label: אפשרויות נוספות + ok_create: לִיצוֹר + workspace_placeholder: אף אחד + title_create: יצירת {{name}} + workspace: סביבת עבודה + title_readonly: צופה {{name}} + identifier: + id: מזהה + or: אוֹ + and: וכן + add_block: הוסף בלוק + kind: לזהות על ידי + remove: מחק בלוק + matching_strategy: אסטרטגיה תואמת + negation: שולל התאמה + new: חָדָשׁ + search: לחפש + confirm_delete: האם אתה בטוח שברצונך למחוק תצורה/ים אלה? + export: יְצוּא + delete: לִמְחוֹק + import: יְבוּא + swap: לְהַחלִיף + confirm_delete_title: אשר מחק + bundled_title: תצורת אפליקציה מצורפת עם Seelen + bundled_msg: >- + תצורות מצורפות אלה אינן ניתנות לעריכה ונועדו לספק לך את החוויה הטובה ביותר + ללא התאמה אישית. הם מגדירים באופן אוטומטי את היישומים הנפוצים ביותר עבורך. +extras: + discord: מַחֲלוֹקֶת + relaunch: השקה מחדש + github: Github + version: גִרְסָה + links: קישורים רשמיים + exit: יצא/יציאה +shortcuts: + labels: + move_to_workspace_4: עברו לסביבת העבודה 4 + move_to_workspace_9: עברו לסביבת העבודה 9 + switch_workspace_3: עבור לסביבת העבודה 3 + switch_workspace_4: עברו לסביבת העבודה 4 + switch_workspace_8: עברו לסביבת העבודה 8 + decrease_width: ירידה ברוחב + focus_latest: התמקד האחרון + send_to_workspace_3: שלח לסביבת העבודה 3 + reserve_bottom: שמורה בתחתית + move_to_workspace_8: עברו לסביבת העבודה 8 + reserve_stack: ערימת מילואים + switch_workspace_7: לעבור לסביבת עבודה 7 + move_to_workspace_0: עברו לסביבת העבודה 0 + reserve_right: שמור ימינה + move_to_workspace_6: עברו לסביבת העבודה 6 + send_to_workspace_9: שלח לסביבת העבודה 9 + send_to_workspace_0: שלח לסביבת עבודה 0 + move_to_workspace_2: לעבור לסביבת העבודה 2 + move_to_workspace_1: לעבור לסביבת העבודה 1 + switch_workspace_1: עבור לסביבת העבודה 1 + increase_width: הגדל את הרוחב + move_to_workspace_7: לעבור לסביבת העבודה 7 + send_to_workspace_5: שלח לסביבת העבודה 5 + restore_sizes: שחזור גדלים + increase_height: הגדל את הגובה + move_to_workspace_5: לעבור לסביבת העבודה 5 + switch_workspace_5: עברו לסביבת העבודה 5 + focus_top: מיקוד למעלה + focus_right: להתמקד נכון + send_to_workspace_1: שלח לסביבת עבודה 1 + switch_workspace_9: עבור לסביבת העבודה 9 + reserve_top: עליון מילואים + switch_workspace_6: לעבור לסביבת עבודה 6 + switch_workspace_0: לעבור לסביבת עבודה 0 + focus_bottom: מיקוד תחתון + send_to_workspace_4: שלח לסביבת העבודה 4 + switch_workspace_2: עבור לסביבת העבודה 2 + reserve_float: שמורה לצוף + send_to_workspace_7: שלח לסביבת עבודה 7 + send_to_workspace_6: שלח לסביבת עבודה 6 + focus_left: פוקוס שמאלה + reserve_left: רזרבה שמאלה + move_to_workspace_3: לעבור לסביבת העבודה 3 + send_to_workspace_8: שלח לסביבת עבודה 8 + send_to_workspace_2: שלח לסביבת עבודה 2 + decrease_height: ירידה בגובה + enable: אפשר קיצורי דרך משולבים (AHK) + enable_tooltip: השבת אם תיישם קיצורי דרך משלך באמצעות ממשק ה- API של Seelen Core +inProgress: בתהליך... +loading: טוען... +open: לִפְתוֹחַ +cancel: לְבַטֵל +quit: לְהַפְסִיק +delete: לִמְחוֹק +save: להציל diff --git a/src/apps/settings/i18n/translations/hi.yml b/src/apps/settings/i18n/translations/hi.yml index ff0a4230..7d75c58e 100644 --- a/src/apps/settings/i18n/translations/hi.yml +++ b/src/apps/settings/i18n/translations/hi.yml @@ -1,195 +1,195 @@ -sides: - left: बाएं - top: शीर्ष - right: सही - bottom: तल -header: - labels: - seelen_wm: खिड़की प्रबंधक - general: सामान्य - seelen_weg: डॉक/टास्टरबार - developer: डेवलपर - specific_apps: विशिष्ट ऐप्स - seelen_bar: फैंसी टूलबार - shortcuts: शॉर्टकट - monitors: पर नज़र रखता है - info: जानकारी -start: - message_accent: शैली के साथ अपनी उत्पादकता का अनुकूलन करें! - message: >- - सेलेन यूआई में आपका स्वागत है, अपने विंडोज 11 अनुभव को बढ़ाने के लिए एक - निगमित टाइलिंग विंडोज मैनेजर के साथ अंतिम डेस्कटॉप वातावरण! हमारे सहज - इंटरफ़ेस और उन्नत सुविधाओं के साथ दक्षता और मल्टीटास्किंग के एक नए युग का - अन्वेषण करें। - title: स्वागत! -general: - theme: - added: थीम पहले से ही जोड़ा गया - enabled: सक्षम थीम - add: थीम जोड़ें - label: थीम सूचना - author: लेखक - tags: टैग - placeholder: चुनिंदा विषय - description: विवरण - available: उपलब्ध - selected: चयनित - startup: स्टार्टअप पर चलाएं? - language: भाषा - icon_pack: - label: आइकन पैक - accent_color: स्वरोंका रंग -toolbar: - placeholder: - author: लेखक - select: उपकरण -संरचना - description: विवरण - height: ऊंचाई - enable: फैंसी टूलबार सक्षम करें -wm: - border: - width: सीमा चौड़ाई - enable: विंडो की सीमा सक्षम करें - offset: सीमावर्ती ऑफसेट - space_between_containers: कंटेनरों के बीच की जगह - resize_delta: डेल्टा का आकार बदलें (%) - workspace_offset: कार्यक्षेत्र ऑफसेट (मार्जिन) - author: लेखक - description: विवरण - disabled_windows10: विंडोज 10 के लिए विंडो मैनेजर उपलब्ध नहीं है। - workspace_padding: कार्यक्षेत्र पैडिंग - layout: लेआउट - enable: विंडो मैनेजर सक्षम करें -weg: - items: - visible_separators: दृश्य विभाजक - size: आइटम आकार - zoom_size: ज़ूमेड आकार (विषयों के लिए उपयोग किया जाता है) - label: सामान - gap: वस्तुओं के बीच का स्थान - padding: गद्दी - width: चौड़ाई - label: डॉक/टास्टरबार - gap: अंतर - enable: डॉक/टास्कबार सक्षम करें - dock_side: डॉक साइड - auto_hide: खुद से छिपना - margin: अंतर -devtools: - install_folder: स्थापना फ़ोल्डर - load: भार - app_folders: ऐप फ़ोल्डर्स - settings_file: सेटिंग संचिका - custom_config_file: कस्टम कॉन्फ़िगर फ़ाइल लोड करें - data_folder: डेटा फ़ोल्डर - enable: डेवलपर टूल सक्षम करें -apps_configurations: - app: - options: - force: बल का प्रबंधन करना - pinned: पिन की गई - unmanage: अमानवीय - float: तैरना - title_create: '{{नाम}} बनाना' - ok_edit: अद्यतन - ok_readonly: नए के रूप में संपादित करें - workspace: कार्यस्थान - category_placeholder: कोई नहीं - monitor_placeholder: कोई नहीं - bindings: बाइंडिंग (ध्यान दें कि दोनों विकल्पों की आवश्यकता है) - title_edit: संपादन {{नाम}} - monitor: निगरानी करना - category: वर्ग - workspace_placeholder: कोई नहीं - options_label: अतिरिक्त विकल्प - name: नाम - ok_create: बनाएं - title_readonly: '{{नाम}} देखना' - identifier: - remove: ब्लॉक हटाएं - add_block: ब्लॉक जोड़ें - negation: नकारात्मक मिलान - kind: से पहचानना - id: पहचानकर्ता - matching_strategy: मिलान रणनीति - and: और - or: या - confirm_delete_title: हटाने की पुष्टि करें - bundled_msg: >- - ये बंडल किए गए कॉन्फ़िगरेशन संपादन योग्य नहीं हैं और आपको अनुकूलन के बिना - सबसे अच्छा अनुभव प्रदान करने के लिए डिज़ाइन किए गए हैं। वे स्वचालित रूप से - आपके लिए सबसे आम अनुप्रयोगों को कॉन्फ़िगर करते हैं। - confirm_delete: क्या आप सुनिश्चित हैं कि आप इस कॉन्फ़िगरेशन/एस को हटाना चाहते हैं? - export: निर्यात - new: नया - delete: मिटाना - bundled_title: ऐप कॉन्फ़िगरेशन सेलेन के साथ बंडल किया गया - swap: बदलना - import: आयात - search: खोज -extras: - discord: कलह - relaunch: 'पुन: लॉन्च' - links: आधिकारिक संबंध - exit: छोड़ देना/बाहर निकलना - github: GitHub - version: संस्करण -shortcuts: - labels: - switch_workspace_1: कार्यक्षेत्र 1 पर स्विच करें - reserve_right: आरक्षित अधिकार - move_to_workspace_1: कार्यक्षेत्र 1 पर जाएं - switch_workspace_2: कार्यक्षेत्र 2 पर स्विच करें - reserve_stack: आरक्षित स्टैक - decrease_height: ऊंचाई में कमी - reserve_left: आरक्षित आरक्षित - move_to_workspace_2: कार्यक्षेत्र 2 पर जाएं - move_to_workspace_9: कार्यक्षेत्र 9 पर जाएं - reserve_top: आरक्षित शीर्ष - send_to_workspace_4: कार्यक्षेत्र 4 पर भेजें - increase_width: चौड़ाई में वृद्धि - switch_workspace_5: कार्यक्षेत्र 5 पर स्विच करें - move_to_workspace_8: कार्यक्षेत्र 8 पर जाएं - send_to_workspace_2: कार्यक्षेत्र 2 को भेजें - focus_left: फोकस लेफ्ट - send_to_workspace_5: कार्यक्षेत्र 5 को भेजें - send_to_workspace_7: कार्यक्षेत्र 7 को भेजें - send_to_workspace_3: कार्यक्षेत्र 3 को भेजें - decrease_width: चौड़ाई में कमी - send_to_workspace_8: कार्यक्षेत्र 8 पर भेजें - move_to_workspace_6: कार्यक्षेत्र 6 पर जाएं - restore_sizes: आकारों को बहाल करें - focus_top: फोकस टॉप - switch_workspace_9: कार्यक्षेत्र 9 पर स्विच करें - move_to_workspace_4: कार्यक्षेत्र 4 पर जाएं - focus_bottom: फोकस बॉटम - switch_workspace_8: कार्यक्षेत्र 8 पर स्विच करें - switch_workspace_6: कार्यक्षेत्र 6 पर स्विच करें - reserve_bottom: रिजर्व - move_to_workspace_3: कार्यक्षेत्र 3 पर जाएं - move_to_workspace_0: कार्यक्षेत्र 0 पर जाएं - send_to_workspace_0: कार्यक्षेत्र 0 पर भेजें - focus_latest: नवीनतम ध्यान केंद्रित करें - increase_height: ऊंचाई बढ़ाना - focus_right: फोकस अधिकार - switch_workspace_4: कार्यक्षेत्र 4 पर स्विच करें - send_to_workspace_1: कार्यक्षेत्र 1 पर भेजें - send_to_workspace_6: कार्यक्षेत्र 6 को भेजें - move_to_workspace_5: कार्यक्षेत्र 5 पर जाएं - send_to_workspace_9: कार्यक्षेत्र 9 को भेजें - switch_workspace_0: कार्यक्षेत्र पर स्विच करें 0 - switch_workspace_7: कार्यक्षेत्र 7 पर स्विच करें - reserve_float: रिजर्व फ्लोट - switch_workspace_3: कार्यक्षेत्र 3 पर स्विच करें - move_to_workspace_7: कार्यक्षेत्र 7 पर जाएं - enable: एकीकृत शॉर्टकट (AHK) सक्षम करें - enable_tooltip: >- - अक्षम करें यदि आप सेलेन कोर एपीआई का उपयोग करके अपने स्वयं के शॉर्टकट को - लागू करेंगे -inProgress: प्रगति पर है... -save: बचाना -open: खुला -delete: मिटाना -cancel: रद्द करना -loading: लोड हो रहा है... -quit: छोड़ना +sides: + left: बाएं + top: शीर्ष + right: सही + bottom: तल +header: + labels: + seelen_wm: खिड़की प्रबंधक + general: सामान्य + seelen_weg: डॉक/टास्टरबार + developer: डेवलपर + specific_apps: विशिष्ट ऐप्स + seelen_bar: फैंसी टूलबार + shortcuts: शॉर्टकट + monitors: पर नज़र रखता है + info: जानकारी +start: + message_accent: शैली के साथ अपनी उत्पादकता का अनुकूलन करें! + message: >- + सेलेन यूआई में आपका स्वागत है, अपने विंडोज 11 अनुभव को बढ़ाने के लिए एक + निगमित टाइलिंग विंडोज मैनेजर के साथ अंतिम डेस्कटॉप वातावरण! हमारे सहज + इंटरफ़ेस और उन्नत सुविधाओं के साथ दक्षता और मल्टीटास्किंग के एक नए युग का + अन्वेषण करें। + title: स्वागत! +general: + theme: + added: थीम पहले से ही जोड़ा गया + enabled: सक्षम थीम + add: थीम जोड़ें + label: थीम सूचना + author: लेखक + tags: टैग + placeholder: चुनिंदा विषय + description: विवरण + available: उपलब्ध + selected: चयनित + startup: स्टार्टअप पर चलाएं? + language: भाषा + icon_pack: + label: आइकन पैक + accent_color: स्वरोंका रंग +toolbar: + placeholder: + author: लेखक + select: उपकरण -संरचना + description: विवरण + height: ऊंचाई + enable: फैंसी टूलबार सक्षम करें +wm: + border: + width: सीमा चौड़ाई + enable: विंडो की सीमा सक्षम करें + offset: सीमावर्ती ऑफसेट + space_between_containers: कंटेनरों के बीच की जगह + resize_delta: डेल्टा का आकार बदलें (%) + workspace_offset: कार्यक्षेत्र ऑफसेट (मार्जिन) + author: लेखक + description: विवरण + disabled_windows10: विंडोज 10 के लिए विंडो मैनेजर उपलब्ध नहीं है। + workspace_padding: कार्यक्षेत्र पैडिंग + layout: लेआउट + enable: विंडो मैनेजर सक्षम करें +weg: + items: + visible_separators: दृश्य विभाजक + size: आइटम आकार + zoom_size: ज़ूमेड आकार (विषयों के लिए उपयोग किया जाता है) + label: सामान + gap: वस्तुओं के बीच का स्थान + padding: गद्दी + width: चौड़ाई + label: डॉक/टास्टरबार + gap: अंतर + enable: डॉक/टास्कबार सक्षम करें + dock_side: डॉक साइड + auto_hide: खुद से छिपना + margin: अंतर +devtools: + install_folder: स्थापना फ़ोल्डर + load: भार + app_folders: ऐप फ़ोल्डर्स + settings_file: सेटिंग संचिका + custom_config_file: कस्टम कॉन्फ़िगर फ़ाइल लोड करें + data_folder: डेटा फ़ोल्डर + enable: डेवलपर टूल सक्षम करें +apps_configurations: + app: + options: + force: बल का प्रबंधन करना + pinned: पिन की गई + unmanage: अमानवीय + float: तैरना + title_create: '{{नाम}} बनाना' + ok_edit: अद्यतन + ok_readonly: नए के रूप में संपादित करें + workspace: कार्यस्थान + category_placeholder: कोई नहीं + monitor_placeholder: कोई नहीं + bindings: बाइंडिंग (ध्यान दें कि दोनों विकल्पों की आवश्यकता है) + title_edit: संपादन {{नाम}} + monitor: निगरानी करना + category: वर्ग + workspace_placeholder: कोई नहीं + options_label: अतिरिक्त विकल्प + name: नाम + ok_create: बनाएं + title_readonly: '{{नाम}} देखना' + identifier: + remove: ब्लॉक हटाएं + add_block: ब्लॉक जोड़ें + negation: नकारात्मक मिलान + kind: से पहचानना + id: पहचानकर्ता + matching_strategy: मिलान रणनीति + and: और + or: या + confirm_delete_title: हटाने की पुष्टि करें + bundled_msg: >- + ये बंडल किए गए कॉन्फ़िगरेशन संपादन योग्य नहीं हैं और आपको अनुकूलन के बिना + सबसे अच्छा अनुभव प्रदान करने के लिए डिज़ाइन किए गए हैं। वे स्वचालित रूप से + आपके लिए सबसे आम अनुप्रयोगों को कॉन्फ़िगर करते हैं। + confirm_delete: क्या आप सुनिश्चित हैं कि आप इस कॉन्फ़िगरेशन/एस को हटाना चाहते हैं? + export: निर्यात + new: नया + delete: मिटाना + bundled_title: ऐप कॉन्फ़िगरेशन सेलेन के साथ बंडल किया गया + swap: बदलना + import: आयात + search: खोज +extras: + discord: कलह + relaunch: 'पुन: लॉन्च' + links: आधिकारिक संबंध + exit: छोड़ देना/बाहर निकलना + github: GitHub + version: संस्करण +shortcuts: + labels: + switch_workspace_1: कार्यक्षेत्र 1 पर स्विच करें + reserve_right: आरक्षित अधिकार + move_to_workspace_1: कार्यक्षेत्र 1 पर जाएं + switch_workspace_2: कार्यक्षेत्र 2 पर स्विच करें + reserve_stack: आरक्षित स्टैक + decrease_height: ऊंचाई में कमी + reserve_left: आरक्षित आरक्षित + move_to_workspace_2: कार्यक्षेत्र 2 पर जाएं + move_to_workspace_9: कार्यक्षेत्र 9 पर जाएं + reserve_top: आरक्षित शीर्ष + send_to_workspace_4: कार्यक्षेत्र 4 पर भेजें + increase_width: चौड़ाई में वृद्धि + switch_workspace_5: कार्यक्षेत्र 5 पर स्विच करें + move_to_workspace_8: कार्यक्षेत्र 8 पर जाएं + send_to_workspace_2: कार्यक्षेत्र 2 को भेजें + focus_left: फोकस लेफ्ट + send_to_workspace_5: कार्यक्षेत्र 5 को भेजें + send_to_workspace_7: कार्यक्षेत्र 7 को भेजें + send_to_workspace_3: कार्यक्षेत्र 3 को भेजें + decrease_width: चौड़ाई में कमी + send_to_workspace_8: कार्यक्षेत्र 8 पर भेजें + move_to_workspace_6: कार्यक्षेत्र 6 पर जाएं + restore_sizes: आकारों को बहाल करें + focus_top: फोकस टॉप + switch_workspace_9: कार्यक्षेत्र 9 पर स्विच करें + move_to_workspace_4: कार्यक्षेत्र 4 पर जाएं + focus_bottom: फोकस बॉटम + switch_workspace_8: कार्यक्षेत्र 8 पर स्विच करें + switch_workspace_6: कार्यक्षेत्र 6 पर स्विच करें + reserve_bottom: रिजर्व + move_to_workspace_3: कार्यक्षेत्र 3 पर जाएं + move_to_workspace_0: कार्यक्षेत्र 0 पर जाएं + send_to_workspace_0: कार्यक्षेत्र 0 पर भेजें + focus_latest: नवीनतम ध्यान केंद्रित करें + increase_height: ऊंचाई बढ़ाना + focus_right: फोकस अधिकार + switch_workspace_4: कार्यक्षेत्र 4 पर स्विच करें + send_to_workspace_1: कार्यक्षेत्र 1 पर भेजें + send_to_workspace_6: कार्यक्षेत्र 6 को भेजें + move_to_workspace_5: कार्यक्षेत्र 5 पर जाएं + send_to_workspace_9: कार्यक्षेत्र 9 को भेजें + switch_workspace_0: कार्यक्षेत्र पर स्विच करें 0 + switch_workspace_7: कार्यक्षेत्र 7 पर स्विच करें + reserve_float: रिजर्व फ्लोट + switch_workspace_3: कार्यक्षेत्र 3 पर स्विच करें + move_to_workspace_7: कार्यक्षेत्र 7 पर जाएं + enable: एकीकृत शॉर्टकट (AHK) सक्षम करें + enable_tooltip: >- + अक्षम करें यदि आप सेलेन कोर एपीआई का उपयोग करके अपने स्वयं के शॉर्टकट को + लागू करेंगे +inProgress: प्रगति पर है... +save: बचाना +open: खुला +delete: मिटाना +cancel: रद्द करना +loading: लोड हो रहा है... +quit: छोड़ना diff --git a/src/apps/settings/i18n/translations/hr.yml b/src/apps/settings/i18n/translations/hr.yml index 2add6100..090ef5ad 100644 --- a/src/apps/settings/i18n/translations/hr.yml +++ b/src/apps/settings/i18n/translations/hr.yml @@ -1,195 +1,195 @@ -sides: - right: Pravo - left: Lijevo - top: Vrh - bottom: Dno -header: - labels: - info: Informacija - seelen_bar: Fantastična alatna traka - specific_apps: Određene aplikacije - seelen_weg: Pristanište/trag - general: Općenito - seelen_wm: Upravitelj prozora - monitors: Monitori - shortcuts: Prečac - developer: Programer -start: - message_accent: Optimizirajte svoju produktivnost stilom! - message: >- - Dobrodošli na Seelen UI, Ultimate Desktop okruženje s ugrađenim popločanim - Windows Managerom kako bi se poboljšalo vaše iskustvo Windows 11! Istražite - novu eru učinkovitosti i multitaskinga s našim intuitivnim sučeljem i - naprednim značajkama. - title: Dobrodošli! -general: - theme: - label: Informacije o temi - author: Autor - enabled: Omogućene teme - placeholder: Odaberite temu - added: Tema već dodana - description: Opis - add: Dodaj temu - tags: Oznake - selected: Odabran - available: Dostupno - language: Jezik - startup: Trčati na startup? - icon_pack: - label: Ikona pakiranja - accent_color: Akcentna boja -toolbar: - placeholder: - description: Opis - select: Struktura alatne trake - author: Autor - height: Visina - enable: Omogućite maštovitu alatnu traku -wm: - border: - offset: Offset - width: Širina granice - enable: Omogućite obrub prozora - description: Opis - enable: Omogući upravitelju prozora - disabled_windows10: Upravitelj prozora nije dostupan za Windows 10. - author: Autor - workspace_offset: Pomak radnog prostora (margine) - layout: Raspored - resize_delta: Promijenite veličinu delta (%) - space_between_containers: Prostor između spremnika - workspace_padding: Radni prostori jastučići -weg: - items: - visible_separators: Vidljivi separatori - label: Predmeti - size: Veličina predmeta - zoom_size: Zumirana veličina (koristi se za teme) - gap: Prostor između predmeta - width: Širina - auto_hide: Auto sakrij - padding: Jadnja - label: Pristanište/trag - gap: Jaz - margin: Margina - enable: Omogućite pristanište/zadaću - dock_side: Priključak -devtools: - custom_config_file: Učitajte prilagođenu konfiguracijsku datoteku - data_folder: Mapa podataka - enable: Omogućite alate za razvojne programere - settings_file: Datoteka postavki - app_folders: Mape aplikacija - install_folder: Mapa za instalaciju - load: Opterećenje -apps_configurations: - app: - options: - force: Sila upravljati - float: Plutati - unmanage: Razriješiti - pinned: Prikvačen - ok_edit: Ažuriraj - bindings: Vezivanje (napomena potrebne su obje opcije) - title_edit: Uređivanje {{name}} - category_placeholder: Nijedan - ok_create: Stvoriti - ok_readonly: Uredi kao novo - options_label: Dodatne opcije - title_readonly: Pregled {{name}} - title_create: Stvaranje {{name}} - category: Kategorija - workspace: Radni prostor - monitor_placeholder: Nijedan - workspace_placeholder: Nijedan - name: Ime - monitor: Monitor - identifier: - and: I - negation: Negiranje podudaranja - remove: Izbriši blok - id: Identifikator - kind: Identificirati - add_block: Dodajte blok - or: ILI - matching_strategy: Podudarna strategija - swap: Mijenjati - new: Novi - export: Izvoz - bundled_msg: >- - Ove paketne konfiguracije nisu moguće uređivati ​​i dizajnirane su tako da - vam pruže najbolje iskustvo bez prilagodbe. Oni automatski konfiguriraju - najčešće aplikacije za vas. - confirm_delete: Jeste li sigurni da želite izbrisati ovu konfiguraciju? - bundled_title: Aplikacija config sa Seelen - import: Uvoz - delete: Izbrisati - confirm_delete_title: Potvrdi Delete - search: traži -extras: - relaunch: Ponovno pokretanje - github: Ždrijeb - exit: Prestati/izaći - discord: Nesklad - links: Službene veze - version: Verzija -shortcuts: - labels: - send_to_workspace_8: Pošaljite u radni prostor 8 - focus_latest: Fokus najnovije - switch_workspace_5: Prebacite se na radni prostor 5 - focus_right: Usredotočite se u pravu - move_to_workspace_5: Pomaknite se u radni prostor 5 - reserve_float: Rezervirati plutaj - switch_workspace_4: Prebacite se na radni prostor 4 - move_to_workspace_4: Pomaknite se u radni prostor 4 - reserve_left: Rezerva - move_to_workspace_3: Pomaknite se u radni prostor 3 - focus_top: Fokus na vrhu - send_to_workspace_0: Pošaljite u radni prostor 0 - send_to_workspace_9: Pošaljite u radni prostor 9 - send_to_workspace_4: Pošaljite u radni prostor 4 - send_to_workspace_2: Pošaljite u radni prostor 2 - switch_workspace_2: Prebacite se na radni prostor 2 - switch_workspace_3: Prebacite se na radni prostor 3 - send_to_workspace_6: Pošaljite u radni prostor 6 - switch_workspace_1: Prebacite se na radni prostor 1 - move_to_workspace_7: Pomaknite se u radni prostor 7 - increase_width: Povećati širinu - move_to_workspace_8: Pomaknite se u radni prostor 8 - send_to_workspace_1: Pošaljite u radni prostor 1 - restore_sizes: Vrati veličine - increase_height: Povećati visinu - send_to_workspace_5: Pošaljite u radni prostor 5 - move_to_workspace_1: Pomaknite se u radni prostor 1 - focus_left: Usredotočite se lijevo - switch_workspace_7: Prebacite se na radni prostor 7 - move_to_workspace_6: Pomaknite se u radni prostor 6 - decrease_width: Širina smanjenja - decrease_height: Visina smanjenja - switch_workspace_6: Prebacite se na radni prostor 6 - move_to_workspace_2: Pomaknite se u radni prostor 2 - move_to_workspace_9: Pomaknite se u radni prostor 9 - reserve_right: Rezervirati - switch_workspace_9: Prebacite se na radni prostor 9 - switch_workspace_0: Prebacite se na radni prostor 0 - move_to_workspace_0: Pomaknite se u radni prostor 0 - focus_bottom: Fokus dna - reserve_stack: Rezerva - switch_workspace_8: Prebacite se na radni prostor 8 - reserve_top: Rezervirajte vrh - reserve_bottom: Rezervirati - send_to_workspace_7: Pošaljite u radni prostor 7 - send_to_workspace_3: Pošaljite u radni prostor 3 - enable_tooltip: >- - Onemogući ako ćete implementirati vlastite prečace pomoću Seelen Core API - -ja - enable: Omogućite integrirane prečace (AHK) -cancel: Otkazati -loading: Učitavam... -delete: Izbrisati -inProgress: U nastajanju... -save: Uštedjeti -quit: Prestati -open: Otvoren +sides: + right: Pravo + left: Lijevo + top: Vrh + bottom: Dno +header: + labels: + info: Informacija + seelen_bar: Fantastična alatna traka + specific_apps: Određene aplikacije + seelen_weg: Pristanište/trag + general: Općenito + seelen_wm: Upravitelj prozora + monitors: Monitori + shortcuts: Prečac + developer: Programer +start: + message_accent: Optimizirajte svoju produktivnost stilom! + message: >- + Dobrodošli na Seelen UI, Ultimate Desktop okruženje s ugrađenim popločanim + Windows Managerom kako bi se poboljšalo vaše iskustvo Windows 11! Istražite + novu eru učinkovitosti i multitaskinga s našim intuitivnim sučeljem i + naprednim značajkama. + title: Dobrodošli! +general: + theme: + label: Informacije o temi + author: Autor + enabled: Omogućene teme + placeholder: Odaberite temu + added: Tema već dodana + description: Opis + add: Dodaj temu + tags: Oznake + selected: Odabran + available: Dostupno + language: Jezik + startup: Trčati na startup? + icon_pack: + label: Ikona pakiranja + accent_color: Akcentna boja +toolbar: + placeholder: + description: Opis + select: Struktura alatne trake + author: Autor + height: Visina + enable: Omogućite maštovitu alatnu traku +wm: + border: + offset: Offset + width: Širina granice + enable: Omogućite obrub prozora + description: Opis + enable: Omogući upravitelju prozora + disabled_windows10: Upravitelj prozora nije dostupan za Windows 10. + author: Autor + workspace_offset: Pomak radnog prostora (margine) + layout: Raspored + resize_delta: Promijenite veličinu delta (%) + space_between_containers: Prostor između spremnika + workspace_padding: Radni prostori jastučići +weg: + items: + visible_separators: Vidljivi separatori + label: Predmeti + size: Veličina predmeta + zoom_size: Zumirana veličina (koristi se za teme) + gap: Prostor između predmeta + width: Širina + auto_hide: Auto sakrij + padding: Jadnja + label: Pristanište/trag + gap: Jaz + margin: Margina + enable: Omogućite pristanište/zadaću + dock_side: Priključak +devtools: + custom_config_file: Učitajte prilagođenu konfiguracijsku datoteku + data_folder: Mapa podataka + enable: Omogućite alate za razvojne programere + settings_file: Datoteka postavki + app_folders: Mape aplikacija + install_folder: Mapa za instalaciju + load: Opterećenje +apps_configurations: + app: + options: + force: Sila upravljati + float: Plutati + unmanage: Razriješiti + pinned: Prikvačen + ok_edit: Ažuriraj + bindings: Vezivanje (napomena potrebne su obje opcije) + title_edit: Uređivanje {{name}} + category_placeholder: Nijedan + ok_create: Stvoriti + ok_readonly: Uredi kao novo + options_label: Dodatne opcije + title_readonly: Pregled {{name}} + title_create: Stvaranje {{name}} + category: Kategorija + workspace: Radni prostor + monitor_placeholder: Nijedan + workspace_placeholder: Nijedan + name: Ime + monitor: Monitor + identifier: + and: I + negation: Negiranje podudaranja + remove: Izbriši blok + id: Identifikator + kind: Identificirati + add_block: Dodajte blok + or: ILI + matching_strategy: Podudarna strategija + swap: Mijenjati + new: Novi + export: Izvoz + bundled_msg: >- + Ove paketne konfiguracije nisu moguće uređivati ​​i dizajnirane su tako da + vam pruže najbolje iskustvo bez prilagodbe. Oni automatski konfiguriraju + najčešće aplikacije za vas. + confirm_delete: Jeste li sigurni da želite izbrisati ovu konfiguraciju? + bundled_title: Aplikacija config sa Seelen + import: Uvoz + delete: Izbrisati + confirm_delete_title: Potvrdi Delete + search: traži +extras: + relaunch: Ponovno pokretanje + github: Ždrijeb + exit: Prestati/izaći + discord: Nesklad + links: Službene veze + version: Verzija +shortcuts: + labels: + send_to_workspace_8: Pošaljite u radni prostor 8 + focus_latest: Fokus najnovije + switch_workspace_5: Prebacite se na radni prostor 5 + focus_right: Usredotočite se u pravu + move_to_workspace_5: Pomaknite se u radni prostor 5 + reserve_float: Rezervirati plutaj + switch_workspace_4: Prebacite se na radni prostor 4 + move_to_workspace_4: Pomaknite se u radni prostor 4 + reserve_left: Rezerva + move_to_workspace_3: Pomaknite se u radni prostor 3 + focus_top: Fokus na vrhu + send_to_workspace_0: Pošaljite u radni prostor 0 + send_to_workspace_9: Pošaljite u radni prostor 9 + send_to_workspace_4: Pošaljite u radni prostor 4 + send_to_workspace_2: Pošaljite u radni prostor 2 + switch_workspace_2: Prebacite se na radni prostor 2 + switch_workspace_3: Prebacite se na radni prostor 3 + send_to_workspace_6: Pošaljite u radni prostor 6 + switch_workspace_1: Prebacite se na radni prostor 1 + move_to_workspace_7: Pomaknite se u radni prostor 7 + increase_width: Povećati širinu + move_to_workspace_8: Pomaknite se u radni prostor 8 + send_to_workspace_1: Pošaljite u radni prostor 1 + restore_sizes: Vrati veličine + increase_height: Povećati visinu + send_to_workspace_5: Pošaljite u radni prostor 5 + move_to_workspace_1: Pomaknite se u radni prostor 1 + focus_left: Usredotočite se lijevo + switch_workspace_7: Prebacite se na radni prostor 7 + move_to_workspace_6: Pomaknite se u radni prostor 6 + decrease_width: Širina smanjenja + decrease_height: Visina smanjenja + switch_workspace_6: Prebacite se na radni prostor 6 + move_to_workspace_2: Pomaknite se u radni prostor 2 + move_to_workspace_9: Pomaknite se u radni prostor 9 + reserve_right: Rezervirati + switch_workspace_9: Prebacite se na radni prostor 9 + switch_workspace_0: Prebacite se na radni prostor 0 + move_to_workspace_0: Pomaknite se u radni prostor 0 + focus_bottom: Fokus dna + reserve_stack: Rezerva + switch_workspace_8: Prebacite se na radni prostor 8 + reserve_top: Rezervirajte vrh + reserve_bottom: Rezervirati + send_to_workspace_7: Pošaljite u radni prostor 7 + send_to_workspace_3: Pošaljite u radni prostor 3 + enable_tooltip: >- + Onemogući ako ćete implementirati vlastite prečace pomoću Seelen Core API + -ja + enable: Omogućite integrirane prečace (AHK) +cancel: Otkazati +loading: Učitavam... +delete: Izbrisati +inProgress: U nastajanju... +save: Uštedjeti +quit: Prestati +open: Otvoren diff --git a/src/apps/settings/i18n/translations/hu.yml b/src/apps/settings/i18n/translations/hu.yml index 8f3c3ce2..4705de94 100644 --- a/src/apps/settings/i18n/translations/hu.yml +++ b/src/apps/settings/i18n/translations/hu.yml @@ -1,195 +1,195 @@ -sides: - left: Bal - right: Jobb - bottom: Alsó - top: Felső -header: - labels: - developer: Fejlesztő - general: Tábornok - monitors: Monitorok - info: Információ - specific_apps: Konkrét alkalmazások - seelen_weg: Dokk/tálca - seelen_bar: Divatos eszköztár - shortcuts: Parancsikonok - seelen_wm: Ablakvezető -start: - title: Üdvözöljük! - message: >- - Üdvözöljük a Seelen UI -ban, az Ultimate Desktop környezetben egy beépített - burkolólap Windows Manager -rel, hogy javítsa a Windows 11 élményét! Fedezze - fel a hatékonyság és a multitasking új korszakát az intuitív felületünkkel - és a fejlett funkciókkal. - message_accent: Optimalizálja a termelékenységet stílusosan! -general: - theme: - author: Szerző - description: Leírás - placeholder: Válassz témát - label: Témainformációk - add: Téma hozzáadása - added: A téma már hozzáadott - enabled: Engedélyezve témák - tags: Címkék - available: Elérhető - selected: Kiválasztott - startup: Futtatni indításkor? - language: Nyelv - icon_pack: - label: Ikoncsomagok - accent_color: Akcentus szín -toolbar: - placeholder: - description: Leírás - author: Szerző - select: Eszköztár szerkezete - height: Magasság - enable: Engedélyezze a divatos eszköztárat -wm: - border: - enable: Engedélyezze az ablak szegélyét - offset: Határ eltolás - width: Határszélesség - author: Szerző - layout: Elrendezés - space_between_containers: Hely a konténerek között - description: Leírás - disabled_windows10: Az ablakkezelő nem érhető el a Windows 10 -hez. - enable: Engedélyezze az ablakkezelőt - workspace_padding: Munkaterületek párnázása - resize_delta: Átméretezze a DELTA -t (%) - workspace_offset: A munkaterületek eltolása (margók) -weg: - items: - zoom_size: Nagyított méret (a témákhoz használt) - size: Elemméret - visible_separators: Látható elválasztók - label: Tárgyak - gap: Hely az elemek között - padding: Párnázás - auto_hide: Automatikus elrejtés - width: Szélesség - gap: Rés - margin: Árrés - dock_side: Dokkoló oldal - label: Dokk/tálca - enable: Engedélyezze a dokkolót/tálcát -devtools: - load: Betöltés - app_folders: App mappák - enable: Engedélyezze a fejlesztői eszközöket - custom_config_file: Töltse be az egyéni konfigurációs fájlt - install_folder: Telepítési mappa - data_folder: Adatmappa - settings_file: Beállítási fájl -apps_configurations: - app: - options: - float: Úszó - force: Erőkezelés - unmanage: Menedzsment - pinned: Rögzített - ok_readonly: Szerkesztés újként - name: Név - ok_create: Teremt - workspace_placeholder: Egyik sem - workspace: Munkaterület - category: Kategória - monitor_placeholder: Egyik sem - category_placeholder: Egyik sem - bindings: Kötés (vegye figyelembe, hogy mindkét lehetőség szükséges) - title_readonly: '{{Név}} megtekintés' - title_edit: '{{Név}} szerkesztés' - title_create: '{{Név}} létrehozása' - monitor: Monitor - options_label: Extra lehetőségek - ok_edit: Frissít - identifier: - or: VAGY - add_block: Blokk hozzáadása - and: ÉS - id: Azonosító - matching_strategy: Megfelelő stratégia - remove: Blokk törlése - negation: Tagadás egyeztetés - kind: Azonosít - new: Új - delete: Töröl - bundled_msg: >- - Ezek a csomagolt konfigurációk nem szerkeszthetők, és úgy tervezték, hogy - testreszabás nélkül biztosítsa a legjobb élményt. Automatikusan - konfigurálják a leggyakoribb alkalmazásokat az Ön számára. - confirm_delete_title: Törlés jóváhagyása - swap: Csere - export: Export - search: Keresés - bundled_title: A Seelen -vel csomagolt alkalmazás konfigurációja - import: Behozatal - confirm_delete: Biztos benne, hogy törölni akarja ezt a konfigurációt/S -t? -extras: - relaunch: Újraindít - exit: Kilépés/kilépés - version: Változat - discord: Viszály - github: Github - links: Hivatalos linkek -shortcuts: - labels: - send_to_workspace_6: Küldje el a 6. munkaterületre - reserve_top: Tartalék - move_to_workspace_4: Költözni a Workspace 4 -re - reserve_right: Tartalékolási jog - focus_top: Fókusz teteje - move_to_workspace_9: Költözni a munkaterületre 9 - switch_workspace_4: Váltás a Workspace 4 -re - send_to_workspace_5: Küldje el az 5. munkaterületre - focus_latest: Fókuszban a legújabb - switch_workspace_8: Váltás a 8. munkaterületre - focus_left: Fókusz balra - reserve_stack: Tartalékköteg - move_to_workspace_5: Költözni az 5. munkaterületre - send_to_workspace_2: Küldje el a Workspace 2 -et - focus_bottom: Fókusz alsó - increase_width: Növelje a szélességet - send_to_workspace_3: Küldje el a Workspace 3 -ot - switch_workspace_0: Váltás a 0 munkaterületre - move_to_workspace_2: Költözni a 2. munkaterületre - send_to_workspace_1: Küldje el az 1. munkaterületre - move_to_workspace_3: Költözni a Munkaterületre 3 - switch_workspace_9: Váltás a munkaterületre 9 - switch_workspace_6: Váltás a 6 munkaterületre - reserve_left: Tartalék balra - decrease_height: Csökkenési magasság - increase_height: Növelje a magasságot - reserve_float: Tartalék úszó - focus_right: Fókuszál - switch_workspace_2: Váltás a 2. munkaterületre - move_to_workspace_1: Költözni az 1. munkaterületre - send_to_workspace_8: Küldje el a 8. munkaterületre - restore_sizes: Visszaállítani a méreteket - move_to_workspace_7: Költözni a Workspace 7 -re - switch_workspace_7: Váltás a 7. munkaterületre - move_to_workspace_0: Költözni a 0 munkaterületre - send_to_workspace_0: Küldje el a 0 munkaterületre - move_to_workspace_8: Költözni a 8. munkaterületre - send_to_workspace_4: Küldje el a Workspace 4 -et - switch_workspace_5: Váltás az 5. munkaterületre - switch_workspace_3: Váltás a 3. munkaterületre - switch_workspace_1: Váltás az 1. munkaterületre - reserve_bottom: Tartalék alsó rész - decrease_width: Csökken a szélesség - send_to_workspace_9: Küldje el a munkaterületre 9 - move_to_workspace_6: Költözni a 6. munkaterületre - send_to_workspace_7: Küldje el a Workspace 7 -et - enable_tooltip: >- - Tiltsa le, ha a Seelen Core API segítségével megvalósítja saját - parancsikonjait - enable: Engedélyezze az integrált parancsikonokat (AHK) -inProgress: Folyamatban... -quit: Kilépés -cancel: Megszünteti -save: Megment -delete: Töröl -loading: Betöltés... -open: Nyisd ki +sides: + left: Bal + right: Jobb + bottom: Alsó + top: Felső +header: + labels: + developer: Fejlesztő + general: Tábornok + monitors: Monitorok + info: Információ + specific_apps: Konkrét alkalmazások + seelen_weg: Dokk/tálca + seelen_bar: Divatos eszköztár + shortcuts: Parancsikonok + seelen_wm: Ablakvezető +start: + title: Üdvözöljük! + message: >- + Üdvözöljük a Seelen UI -ban, az Ultimate Desktop környezetben egy beépített + burkolólap Windows Manager -rel, hogy javítsa a Windows 11 élményét! Fedezze + fel a hatékonyság és a multitasking új korszakát az intuitív felületünkkel + és a fejlett funkciókkal. + message_accent: Optimalizálja a termelékenységet stílusosan! +general: + theme: + author: Szerző + description: Leírás + placeholder: Válassz témát + label: Témainformációk + add: Téma hozzáadása + added: A téma már hozzáadott + enabled: Engedélyezve témák + tags: Címkék + available: Elérhető + selected: Kiválasztott + startup: Futtatni indításkor? + language: Nyelv + icon_pack: + label: Ikoncsomagok + accent_color: Akcentus szín +toolbar: + placeholder: + description: Leírás + author: Szerző + select: Eszköztár szerkezete + height: Magasság + enable: Engedélyezze a divatos eszköztárat +wm: + border: + enable: Engedélyezze az ablak szegélyét + offset: Határ eltolás + width: Határszélesség + author: Szerző + layout: Elrendezés + space_between_containers: Hely a konténerek között + description: Leírás + disabled_windows10: Az ablakkezelő nem érhető el a Windows 10 -hez. + enable: Engedélyezze az ablakkezelőt + workspace_padding: Munkaterületek párnázása + resize_delta: Átméretezze a DELTA -t (%) + workspace_offset: A munkaterületek eltolása (margók) +weg: + items: + zoom_size: Nagyított méret (a témákhoz használt) + size: Elemméret + visible_separators: Látható elválasztók + label: Tárgyak + gap: Hely az elemek között + padding: Párnázás + auto_hide: Automatikus elrejtés + width: Szélesség + gap: Rés + margin: Árrés + dock_side: Dokkoló oldal + label: Dokk/tálca + enable: Engedélyezze a dokkolót/tálcát +devtools: + load: Betöltés + app_folders: App mappák + enable: Engedélyezze a fejlesztői eszközöket + custom_config_file: Töltse be az egyéni konfigurációs fájlt + install_folder: Telepítési mappa + data_folder: Adatmappa + settings_file: Beállítási fájl +apps_configurations: + app: + options: + float: Úszó + force: Erőkezelés + unmanage: Menedzsment + pinned: Rögzített + ok_readonly: Szerkesztés újként + name: Név + ok_create: Teremt + workspace_placeholder: Egyik sem + workspace: Munkaterület + category: Kategória + monitor_placeholder: Egyik sem + category_placeholder: Egyik sem + bindings: Kötés (vegye figyelembe, hogy mindkét lehetőség szükséges) + title_readonly: '{{Név}} megtekintés' + title_edit: '{{Név}} szerkesztés' + title_create: '{{Név}} létrehozása' + monitor: Monitor + options_label: Extra lehetőségek + ok_edit: Frissít + identifier: + or: VAGY + add_block: Blokk hozzáadása + and: ÉS + id: Azonosító + matching_strategy: Megfelelő stratégia + remove: Blokk törlése + negation: Tagadás egyeztetés + kind: Azonosít + new: Új + delete: Töröl + bundled_msg: >- + Ezek a csomagolt konfigurációk nem szerkeszthetők, és úgy tervezték, hogy + testreszabás nélkül biztosítsa a legjobb élményt. Automatikusan + konfigurálják a leggyakoribb alkalmazásokat az Ön számára. + confirm_delete_title: Törlés jóváhagyása + swap: Csere + export: Export + search: Keresés + bundled_title: A Seelen -vel csomagolt alkalmazás konfigurációja + import: Behozatal + confirm_delete: Biztos benne, hogy törölni akarja ezt a konfigurációt/S -t? +extras: + relaunch: Újraindít + exit: Kilépés/kilépés + version: Változat + discord: Viszály + github: Github + links: Hivatalos linkek +shortcuts: + labels: + send_to_workspace_6: Küldje el a 6. munkaterületre + reserve_top: Tartalék + move_to_workspace_4: Költözni a Workspace 4 -re + reserve_right: Tartalékolási jog + focus_top: Fókusz teteje + move_to_workspace_9: Költözni a munkaterületre 9 + switch_workspace_4: Váltás a Workspace 4 -re + send_to_workspace_5: Küldje el az 5. munkaterületre + focus_latest: Fókuszban a legújabb + switch_workspace_8: Váltás a 8. munkaterületre + focus_left: Fókusz balra + reserve_stack: Tartalékköteg + move_to_workspace_5: Költözni az 5. munkaterületre + send_to_workspace_2: Küldje el a Workspace 2 -et + focus_bottom: Fókusz alsó + increase_width: Növelje a szélességet + send_to_workspace_3: Küldje el a Workspace 3 -ot + switch_workspace_0: Váltás a 0 munkaterületre + move_to_workspace_2: Költözni a 2. munkaterületre + send_to_workspace_1: Küldje el az 1. munkaterületre + move_to_workspace_3: Költözni a Munkaterületre 3 + switch_workspace_9: Váltás a munkaterületre 9 + switch_workspace_6: Váltás a 6 munkaterületre + reserve_left: Tartalék balra + decrease_height: Csökkenési magasság + increase_height: Növelje a magasságot + reserve_float: Tartalék úszó + focus_right: Fókuszál + switch_workspace_2: Váltás a 2. munkaterületre + move_to_workspace_1: Költözni az 1. munkaterületre + send_to_workspace_8: Küldje el a 8. munkaterületre + restore_sizes: Visszaállítani a méreteket + move_to_workspace_7: Költözni a Workspace 7 -re + switch_workspace_7: Váltás a 7. munkaterületre + move_to_workspace_0: Költözni a 0 munkaterületre + send_to_workspace_0: Küldje el a 0 munkaterületre + move_to_workspace_8: Költözni a 8. munkaterületre + send_to_workspace_4: Küldje el a Workspace 4 -et + switch_workspace_5: Váltás az 5. munkaterületre + switch_workspace_3: Váltás a 3. munkaterületre + switch_workspace_1: Váltás az 1. munkaterületre + reserve_bottom: Tartalék alsó rész + decrease_width: Csökken a szélesség + send_to_workspace_9: Küldje el a munkaterületre 9 + move_to_workspace_6: Költözni a 6. munkaterületre + send_to_workspace_7: Küldje el a Workspace 7 -et + enable_tooltip: >- + Tiltsa le, ha a Seelen Core API segítségével megvalósítja saját + parancsikonjait + enable: Engedélyezze az integrált parancsikonokat (AHK) +inProgress: Folyamatban... +quit: Kilépés +cancel: Megszünteti +save: Megment +delete: Töröl +loading: Betöltés... +open: Nyisd ki diff --git a/src/apps/settings/i18n/translations/hy.yml b/src/apps/settings/i18n/translations/hy.yml index a08136b6..4619f283 100644 --- a/src/apps/settings/i18n/translations/hy.yml +++ b/src/apps/settings/i18n/translations/hy.yml @@ -1,195 +1,195 @@ -sides: - top: Գագաթ - right: Ճիշտ - left: Ձախ - bottom: Հատակից -header: - labels: - seelen_bar: Fancy Toolbar - developer: Մշակող - seelen_weg: Dock / Taskbar - specific_apps: Հատուկ ծրագրեր - general: Ընդհանուր - monitors: Մոնիտորներ - info: Տեղեկություն - shortcuts: Դյուրանցումներ - seelen_wm: Պատուհանների կառավարիչ -start: - title: Բարի գալուստ - message: >- - Բարի գալուստ SEELEN UI, Ultimate Desktop միջավայրը `ներառված սալիկապատման - մենեջեր` ձեր Windows 11 փորձը բարելավելու համար: Ուսումնասիրեք - արդյունավետության եւ բազմամշակման նոր դարաշրջան մեր ինտուիտիվ ինտերֆեյսով եւ - առաջադեմ հատկություններով: - message_accent: 'Օպտիմիզացրեք ձեր արտադրողականությունը ոճով:' -general: - theme: - label: Թեման տեղեկատվություն - add: Ավելացնել թեման - description: Նկարագրություն - placeholder: Ընտրեք թեման - enabled: Միացված թեմաներ - author: Հեղինակ - tags: Պիտակներ - added: Թեման արդեն ավելացրեց - available: Մատչելի - selected: Ընտրված - language: Լեզու - startup: 'Գործարկման վրա գործարկեք:' - icon_pack: - label: Սրբապատկերներ - accent_color: Շեշտադրիչ գույն -toolbar: - placeholder: - author: Հեղինակ - description: Նկարագրություն - select: Գործիքադարակի կառուցվածքը - enable: Միացնել Fancy Toolbar- ը - height: Բարձրություն -wm: - border: - enable: Միացնել պատուհանի սահմանը - width: Սահմանի լայնությունը - offset: Սահմանի օֆսեթ - description: Նկարագրություն - disabled_windows10: 'Պատուհանների կառավարիչը մատչելի չէ Windows 10-ի համար:' - resize_delta: Չափափոխել դելտան (%) - workspace_offset: Աշխատանքային տարածքների օֆսեթ (լուսանցքներ) - layout: Դասավորություն - space_between_containers: Տիեզերք բեռնարկղերի միջեւ - workspace_padding: Աշխատանքային տարածքների լիցքավորում - enable: Միացնել պատուհանի կառավարիչը - author: Հեղինակ -weg: - items: - size: Ապրանքի չափը - label: Իրերը - visible_separators: Տեսանելի տարանջատիչներ - gap: Տարածություն իրերի միջեւ - zoom_size: Խոշորացված չափը (օգտագործվում է թեմաների համար) - enable: Միացնել Dock / Taskbar - width: Լայնություն - dock_side: Նավահանգիստ - auto_hide: Ավտոմատ թաքցնել - margin: Լուսանցք - gap: Բացվածք - label: Dock / Taskbar - padding: Լիցք -devtools: - custom_config_file: Բեռնեք պատվերով կազմաձեւման ֆայլը - data_folder: Տվյալների պանակ - load: Բեռ - app_folders: Ծրագրի թղթապանակներ - install_folder: Տեղադրման պանակ - enable: Միացնել մշակողի գործիքները - settings_file: Կարգավորումներ ֆայլ -apps_configurations: - app: - options: - pinned: Փածսյա - unmanage: Անօդաչուր - force: Ուժի կառավարում - float: Լողացող - monitor_placeholder: Ոչ ոք - category_placeholder: Ոչ ոք - workspace_placeholder: Ոչ ոք - name: Անուն - bindings: Պարտադիր (նշում է, որ երկու տարբերակները պարտադիր են) - workspace: Աշխատատեղ - monitor: Մոնիտոր - category: Կատեգորիա - ok_create: Ստեղծել - title_readonly: Դիտում է {{Անունը} - options_label: Լրացուցիչ ընտրանքներ - title_edit: Խմբագրում {{Անվան} - ok_readonly: Խմբագրել որպես նոր - ok_edit: Թարմացում - title_create: Ստեղծելով {{name} - identifier: - or: ԿԱՄ - and: Մի քանազոր - kind: Նույնացնել ըստ - id: Նույնացնող - remove: Delete նջել բլոկը - negation: Ժխտել համապատասխանությունը - add_block: Ավելացնել բլոկ - matching_strategy: Համապատասխան ռազմավարություն - bundled_title: Ծրագրի կազմաձեւումը փաթեթավորված է Seelen- ի հետ - confirm_delete_title: Հաստատեք ջնջել - swap: Փոխանակել - import: Ներմուծում - export: Արտահանում - new: Նոր - confirm_delete: 'Համոզված եք, որ ցանկանում եք ջնջել այս կազմաձեւը:' - search: Որոնել - delete: Ջնջել - bundled_msg: >- - Այս փաթեթավորված կազմաձեւերը խմբագրելի չեն եւ նախագծված են `առանց - հարմարեցման լավագույն փորձը տրամադրելու: Նրանք ինքնաբերաբար կարգավորում են - ձեզ համար ամենատարածված դիմումները: -extras: - github: Գյուտ - discord: Տարաձայնություն - links: Պաշտոնական հղումներ - relaunch: Վերակառուցվել - exit: Հանգստացեք / Ելք - version: Տարբերակ -shortcuts: - labels: - move_to_workspace_5: Տեղափոխել Workpace 5 - focus_bottom: Կենտրոնացեք հատակին - send_to_workspace_8: Ուղարկել Workspace 8-ին - send_to_workspace_3: Ուղարկել Workspace 3-ին - move_to_workspace_9: Տեղափոխել Workspace 9 - reserve_left: Պահուստը մնացել է - send_to_workspace_2: Ուղարկել Workspace 2-ին - switch_workspace_5: Անցեք Workspace- ին 5 - focus_top: Կենտրոնանալ գագաթին - decrease_width: Լայնության նվազում - switch_workspace_2: Անցեք Workspace- ին 2 - reserve_stack: Պահեստավորված նյութեր - reserve_float: Ամրագրեք բոց - focus_latest: Կենտրոնացեք վերջին - reserve_bottom: Ամրագրեք հատակը - send_to_workspace_6: Ուղարկել Workspace 6-ին - send_to_workspace_5: Ուղարկել Workspace 5-ին - switch_workspace_3: Անցեք Workspace- ին 3 - move_to_workspace_6: Տեղափոխել Workspace 6 - switch_workspace_4: Անցեք Workspace- ին 4 - send_to_workspace_0: Ուղարկել Workspace- ին 0 - switch_workspace_6: Անցեք Workspace- ին 6 - focus_right: Կենտրոնանալ ճիշտ - send_to_workspace_9: Ուղարկել Workspace 9-ին - switch_workspace_1: Անցեք աշխատանքային տարածքին 1 - send_to_workspace_4: Ուղարկել Workspace 4-ին - move_to_workspace_2: Տեղափոխվել դեպի Workspace 2 - switch_workspace_9: Անցեք Workspace- ին 9 - move_to_workspace_8: Տեղափոխել Workpace 8 - switch_workspace_7: Անցեք Workspace- ին 7 - switch_workspace_0: Անցեք Workspace- ին 0 - send_to_workspace_7: Ուղարկել Workspace 7-ին - focus_left: Կենտրոնանալ ձախ - increase_height: Բարձրացնել բարձրությունը - reserve_right: Ամրագրեք աջ - move_to_workspace_0: Տեղափոխել Workspace 0 - move_to_workspace_1: Տեղափոխել Workspace 1 - move_to_workspace_3: Տեղափոխվել Workspace 3-ին - restore_sizes: Վերականգնել չափերը - decrease_height: Նվազեցնել բարձրությունը - increase_width: Բարձրացնել լայնությունը - send_to_workspace_1: Ուղարկել Workspace 1-ին - move_to_workspace_7: Տեղափոխվել Workpace 7-ին - move_to_workspace_4: Տեղափոխել Workpace 4-ին - reserve_top: Ամրագրեք վերեւ - switch_workspace_8: Անցեք Workspace- ին 8 - enable: Միացնել ինտեգրված դյուրանցումները (AHK) - enable_tooltip: >- - Անջատեք, եթե դուք կիրականացնեք ձեր սեփական դյուրանցումները `օգտագործելով - Seelen Core API- ն -inProgress: Ընթացքի մեջ է... -loading: Բեռնում ... -open: Բաց անել -save: Խնայել -cancel: Չեղարկել -delete: Ջնջել -quit: Թողնել +sides: + top: Գագաթ + right: Ճիշտ + left: Ձախ + bottom: Հատակից +header: + labels: + seelen_bar: Fancy Toolbar + developer: Մշակող + seelen_weg: Dock / Taskbar + specific_apps: Հատուկ ծրագրեր + general: Ընդհանուր + monitors: Մոնիտորներ + info: Տեղեկություն + shortcuts: Դյուրանցումներ + seelen_wm: Պատուհանների կառավարիչ +start: + title: Բարի գալուստ + message: >- + Բարի գալուստ SEELEN UI, Ultimate Desktop միջավայրը `ներառված սալիկապատման + մենեջեր` ձեր Windows 11 փորձը բարելավելու համար: Ուսումնասիրեք + արդյունավետության եւ բազմամշակման նոր դարաշրջան մեր ինտուիտիվ ինտերֆեյսով եւ + առաջադեմ հատկություններով: + message_accent: 'Օպտիմիզացրեք ձեր արտադրողականությունը ոճով:' +general: + theme: + label: Թեման տեղեկատվություն + add: Ավելացնել թեման + description: Նկարագրություն + placeholder: Ընտրեք թեման + enabled: Միացված թեմաներ + author: Հեղինակ + tags: Պիտակներ + added: Թեման արդեն ավելացրեց + available: Մատչելի + selected: Ընտրված + language: Լեզու + startup: 'Գործարկման վրա գործարկեք:' + icon_pack: + label: Սրբապատկերներ + accent_color: Շեշտադրիչ գույն +toolbar: + placeholder: + author: Հեղինակ + description: Նկարագրություն + select: Գործիքադարակի կառուցվածքը + enable: Միացնել Fancy Toolbar- ը + height: Բարձրություն +wm: + border: + enable: Միացնել պատուհանի սահմանը + width: Սահմանի լայնությունը + offset: Սահմանի օֆսեթ + description: Նկարագրություն + disabled_windows10: 'Պատուհանների կառավարիչը մատչելի չէ Windows 10-ի համար:' + resize_delta: Չափափոխել դելտան (%) + workspace_offset: Աշխատանքային տարածքների օֆսեթ (լուսանցքներ) + layout: Դասավորություն + space_between_containers: Տիեզերք բեռնարկղերի միջեւ + workspace_padding: Աշխատանքային տարածքների լիցքավորում + enable: Միացնել պատուհանի կառավարիչը + author: Հեղինակ +weg: + items: + size: Ապրանքի չափը + label: Իրերը + visible_separators: Տեսանելի տարանջատիչներ + gap: Տարածություն իրերի միջեւ + zoom_size: Խոշորացված չափը (օգտագործվում է թեմաների համար) + enable: Միացնել Dock / Taskbar + width: Լայնություն + dock_side: Նավահանգիստ + auto_hide: Ավտոմատ թաքցնել + margin: Լուսանցք + gap: Բացվածք + label: Dock / Taskbar + padding: Լիցք +devtools: + custom_config_file: Բեռնեք պատվերով կազմաձեւման ֆայլը + data_folder: Տվյալների պանակ + load: Բեռ + app_folders: Ծրագրի թղթապանակներ + install_folder: Տեղադրման պանակ + enable: Միացնել մշակողի գործիքները + settings_file: Կարգավորումներ ֆայլ +apps_configurations: + app: + options: + pinned: Փածսյա + unmanage: Անօդաչուր + force: Ուժի կառավարում + float: Լողացող + monitor_placeholder: Ոչ ոք + category_placeholder: Ոչ ոք + workspace_placeholder: Ոչ ոք + name: Անուն + bindings: Պարտադիր (նշում է, որ երկու տարբերակները պարտադիր են) + workspace: Աշխատատեղ + monitor: Մոնիտոր + category: Կատեգորիա + ok_create: Ստեղծել + title_readonly: Դիտում է {{Անունը} + options_label: Լրացուցիչ ընտրանքներ + title_edit: Խմբագրում {{Անվան} + ok_readonly: Խմբագրել որպես նոր + ok_edit: Թարմացում + title_create: Ստեղծելով {{name} + identifier: + or: ԿԱՄ + and: Մի քանազոր + kind: Նույնացնել ըստ + id: Նույնացնող + remove: Delete նջել բլոկը + negation: Ժխտել համապատասխանությունը + add_block: Ավելացնել բլոկ + matching_strategy: Համապատասխան ռազմավարություն + bundled_title: Ծրագրի կազմաձեւումը փաթեթավորված է Seelen- ի հետ + confirm_delete_title: Հաստատեք ջնջել + swap: Փոխանակել + import: Ներմուծում + export: Արտահանում + new: Նոր + confirm_delete: 'Համոզված եք, որ ցանկանում եք ջնջել այս կազմաձեւը:' + search: Որոնել + delete: Ջնջել + bundled_msg: >- + Այս փաթեթավորված կազմաձեւերը խմբագրելի չեն եւ նախագծված են `առանց + հարմարեցման լավագույն փորձը տրամադրելու: Նրանք ինքնաբերաբար կարգավորում են + ձեզ համար ամենատարածված դիմումները: +extras: + github: Գյուտ + discord: Տարաձայնություն + links: Պաշտոնական հղումներ + relaunch: Վերակառուցվել + exit: Հանգստացեք / Ելք + version: Տարբերակ +shortcuts: + labels: + move_to_workspace_5: Տեղափոխել Workpace 5 + focus_bottom: Կենտրոնացեք հատակին + send_to_workspace_8: Ուղարկել Workspace 8-ին + send_to_workspace_3: Ուղարկել Workspace 3-ին + move_to_workspace_9: Տեղափոխել Workspace 9 + reserve_left: Պահուստը մնացել է + send_to_workspace_2: Ուղարկել Workspace 2-ին + switch_workspace_5: Անցեք Workspace- ին 5 + focus_top: Կենտրոնանալ գագաթին + decrease_width: Լայնության նվազում + switch_workspace_2: Անցեք Workspace- ին 2 + reserve_stack: Պահեստավորված նյութեր + reserve_float: Ամրագրեք բոց + focus_latest: Կենտրոնացեք վերջին + reserve_bottom: Ամրագրեք հատակը + send_to_workspace_6: Ուղարկել Workspace 6-ին + send_to_workspace_5: Ուղարկել Workspace 5-ին + switch_workspace_3: Անցեք Workspace- ին 3 + move_to_workspace_6: Տեղափոխել Workspace 6 + switch_workspace_4: Անցեք Workspace- ին 4 + send_to_workspace_0: Ուղարկել Workspace- ին 0 + switch_workspace_6: Անցեք Workspace- ին 6 + focus_right: Կենտրոնանալ ճիշտ + send_to_workspace_9: Ուղարկել Workspace 9-ին + switch_workspace_1: Անցեք աշխատանքային տարածքին 1 + send_to_workspace_4: Ուղարկել Workspace 4-ին + move_to_workspace_2: Տեղափոխվել դեպի Workspace 2 + switch_workspace_9: Անցեք Workspace- ին 9 + move_to_workspace_8: Տեղափոխել Workpace 8 + switch_workspace_7: Անցեք Workspace- ին 7 + switch_workspace_0: Անցեք Workspace- ին 0 + send_to_workspace_7: Ուղարկել Workspace 7-ին + focus_left: Կենտրոնանալ ձախ + increase_height: Բարձրացնել բարձրությունը + reserve_right: Ամրագրեք աջ + move_to_workspace_0: Տեղափոխել Workspace 0 + move_to_workspace_1: Տեղափոխել Workspace 1 + move_to_workspace_3: Տեղափոխվել Workspace 3-ին + restore_sizes: Վերականգնել չափերը + decrease_height: Նվազեցնել բարձրությունը + increase_width: Բարձրացնել լայնությունը + send_to_workspace_1: Ուղարկել Workspace 1-ին + move_to_workspace_7: Տեղափոխվել Workpace 7-ին + move_to_workspace_4: Տեղափոխել Workpace 4-ին + reserve_top: Ամրագրեք վերեւ + switch_workspace_8: Անցեք Workspace- ին 8 + enable: Միացնել ինտեգրված դյուրանցումները (AHK) + enable_tooltip: >- + Անջատեք, եթե դուք կիրականացնեք ձեր սեփական դյուրանցումները `օգտագործելով + Seelen Core API- ն +inProgress: Ընթացքի մեջ է... +loading: Բեռնում ... +open: Բաց անել +save: Խնայել +cancel: Չեղարկել +delete: Ջնջել +quit: Թողնել diff --git a/src/apps/settings/i18n/translations/id.yml b/src/apps/settings/i18n/translations/id.yml index 3817e590..795cb059 100644 --- a/src/apps/settings/i18n/translations/id.yml +++ b/src/apps/settings/i18n/translations/id.yml @@ -1,195 +1,195 @@ -sides: - left: Kiri - bottom: Dasar - top: Atas - right: Benar -header: - labels: - general: Umum - seelen_bar: Toolbar mewah - developer: Pengembang - info: Informasi - monitors: Monitor - seelen_weg: Dock/Taskbar - seelen_wm: Manajer Jendela - specific_apps: Aplikasi tertentu - shortcuts: Pintasan -start: - message: >- - Selamat datang di Seelen UI, lingkungan Ultimate Desktop dengan Windows - Manager yang digabungkan untuk meningkatkan pengalaman Windows 11 Anda! - Jelajahi era baru efisiensi dan multitasking dengan antarmuka intuitif dan - fitur canggih kami. - message_accent: Optimalkan produktivitas Anda dengan gaya! - title: Selamat datang! -general: - theme: - placeholder: Pilih tema - label: Informasi tema - enabled: Tema yang diaktifkan - add: Tambahkan tema - author: Pengarang - added: Tema sudah ditambahkan - tags: Tag - description: Keterangan - selected: Terpilih - available: Tersedia - startup: Jalankan saat startup? - language: Bahasa - icon_pack: - label: Paket Ikon - accent_color: Aksen warna -toolbar: - placeholder: - select: Struktur bilah alat - description: Keterangan - author: Pengarang - enable: Aktifkan toolbar mewah - height: Tinggi -wm: - border: - offset: Offset perbatasan - width: Lebar perbatasan - enable: Aktifkan Perbatasan Jendela - space_between_containers: Ruang antar wadah - description: Keterangan - layout: Tata letak - enable: Aktifkan Window Manager - resize_delta: Ubah Ubah Delta (%) - author: Pengarang - disabled_windows10: Window Manager tidak tersedia untuk Windows 10. - workspace_offset: Offset ruang kerja (margin) - workspace_padding: Padding ruang kerja -weg: - items: - size: Ukuran item - zoom_size: Ukuran zoom (digunakan untuk tema) - label: Item - visible_separators: Pemisah yang terlihat - gap: Ruang antar item - margin: Batas - enable: Aktifkan Dock/Taskbar - auto_hide: Sembunyi otomatis - label: Dock/Taskbar - padding: Lapisan - width: Lebar - gap: Celah - dock_side: Sisi dermaga -devtools: - settings_file: File Pengaturan - install_folder: Folder Instalasi - enable: Aktifkan alat pengembang - custom_config_file: Muat file konfigurasi khusus - data_folder: Folder Data - load: Memuat - app_folders: Folder aplikasi -apps_configurations: - app: - options: - float: Mengambang - force: Memaksa mengelola - pinned: Disematkan - unmanage: Tidak mengelola - title_readonly: Melihat {{name}} - workspace: Ruang kerja - category_placeholder: Tidak ada - ok_edit: Memperbarui - monitor_placeholder: Tidak ada - name: Nama - options_label: Opsi tambahan - ok_create: Membuat - category: Kategori - title_edit: Editting {{name}} - title_create: Membuat {{name}} - workspace_placeholder: Tidak ada - ok_readonly: Edit sebagai baru - bindings: Mengikat (perhatikan kedua opsi itu diperlukan) - monitor: Monitor - identifier: - and: DAN - matching_strategy: Strategi pencocokan - kind: Identifikasi oleh - or: ATAU - remove: Hapus blok - add_block: Tambahkan blok - id: Pengidentifikasi - negation: Meninggalkan pencocokan - delete: Menghapus - confirm_delete: Anda yakin ingin menghapus konfigurasi ini? - bundled_msg: >- - Konfigurasi yang dibundel ini tidak dapat diedit dan dirancang untuk memberi - Anda pengalaman terbaik tanpa kustomisasi. Mereka secara otomatis - mengonfigurasi aplikasi yang paling umum untuk Anda. - export: Ekspor - bundled_title: Aplikasi Config dibundel dengan Seelen - confirm_delete_title: Konfirmasi hapus - search: Mencari - swap: Menukar - import: Impor - new: Baru -extras: - github: GitHub - relaunch: Peluncuran kembali - discord: Perselisihan - exit: Berhenti/keluar - links: Tautan resmi - version: 'Versi: kapan' -shortcuts: - labels: - move_to_workspace_7: Pindah ke ruang kerja 7 - move_to_workspace_9: Pindah ke ruang kerja 9 - focus_bottom: Fokus dasar - focus_left: Fokus kiri - decrease_height: Tinggi penurunan - reserve_right: Cadangan hak - reserve_left: Cadangan kiri - focus_right: Fokus benar - reserve_stack: Tumpukan Cadangan - reserve_bottom: Cadangan Bawah - switch_workspace_1: Beralih ke ruang kerja 1 - switch_workspace_9: Beralih ke ruang kerja 9 - reserve_float: Cadangan float - increase_height: Tingkatkan tinggi - switch_workspace_3: Beralih ke ruang kerja 3 - restore_sizes: Kembalikan ukuran - switch_workspace_5: Beralih ke ruang kerja 5 - send_to_workspace_1: Kirim ke ruang kerja 1 - switch_workspace_7: Beralih ke ruang kerja 7 - send_to_workspace_8: Kirim ke Workspace 8 - reserve_top: Cadangan atasan - send_to_workspace_9: Kirim ke ruang kerja 9 - send_to_workspace_6: Kirim ke Workspace 6 - switch_workspace_4: Beralih ke ruang kerja 4 - move_to_workspace_1: Pindah ke ruang kerja 1 - send_to_workspace_5: Kirim ke Workspace 5 - send_to_workspace_0: Kirim ke ruang kerja 0 - focus_latest: Fokus Terbaru - switch_workspace_0: Beralih ke ruang kerja 0 - move_to_workspace_8: Pindah ke ruang kerja 8 - move_to_workspace_5: Pindah ke ruang kerja 5 - move_to_workspace_6: Pindah ke ruang kerja 6 - switch_workspace_8: Beralih ke ruang kerja 8 - move_to_workspace_3: Pindah ke ruang kerja 3 - switch_workspace_2: Beralih ke ruang kerja 2 - move_to_workspace_2: Pindah ke ruang kerja 2 - move_to_workspace_4: Pindah ke ruang kerja 4 - send_to_workspace_2: Kirim ke Workspace 2 - increase_width: Meningkatkan lebar - switch_workspace_6: Beralih ke ruang kerja 6 - focus_top: Fokus atas - send_to_workspace_4: Kirim ke Workspace 4 - move_to_workspace_0: Pindah ke ruang kerja 0 - decrease_width: Penurunan lebar - send_to_workspace_7: Kirim ke Workspace 7 - send_to_workspace_3: Kirim ke Workspace 3 - enable: Aktifkan pintasan terintegrasi (AHK) - enable_tooltip: >- - Nonaktifkan jika Anda akan mengimplementasikan jalan pintas Anda sendiri - menggunakan API Inti Seelen -open: Membuka -cancel: Membatalkan -save: Menyimpan -inProgress: Sedang berlangsung... -quit: Berhenti -delete: Menghapus -loading: Memuat... +sides: + left: Kiri + bottom: Dasar + top: Atas + right: Benar +header: + labels: + general: Umum + seelen_bar: Toolbar mewah + developer: Pengembang + info: Informasi + monitors: Monitor + seelen_weg: Dock/Taskbar + seelen_wm: Manajer Jendela + specific_apps: Aplikasi tertentu + shortcuts: Pintasan +start: + message: >- + Selamat datang di Seelen UI, lingkungan Ultimate Desktop dengan Windows + Manager yang digabungkan untuk meningkatkan pengalaman Windows 11 Anda! + Jelajahi era baru efisiensi dan multitasking dengan antarmuka intuitif dan + fitur canggih kami. + message_accent: Optimalkan produktivitas Anda dengan gaya! + title: Selamat datang! +general: + theme: + placeholder: Pilih tema + label: Informasi tema + enabled: Tema yang diaktifkan + add: Tambahkan tema + author: Pengarang + added: Tema sudah ditambahkan + tags: Tag + description: Keterangan + selected: Terpilih + available: Tersedia + startup: Jalankan saat startup? + language: Bahasa + icon_pack: + label: Paket Ikon + accent_color: Aksen warna +toolbar: + placeholder: + select: Struktur bilah alat + description: Keterangan + author: Pengarang + enable: Aktifkan toolbar mewah + height: Tinggi +wm: + border: + offset: Offset perbatasan + width: Lebar perbatasan + enable: Aktifkan Perbatasan Jendela + space_between_containers: Ruang antar wadah + description: Keterangan + layout: Tata letak + enable: Aktifkan Window Manager + resize_delta: Ubah Ubah Delta (%) + author: Pengarang + disabled_windows10: Window Manager tidak tersedia untuk Windows 10. + workspace_offset: Offset ruang kerja (margin) + workspace_padding: Padding ruang kerja +weg: + items: + size: Ukuran item + zoom_size: Ukuran zoom (digunakan untuk tema) + label: Item + visible_separators: Pemisah yang terlihat + gap: Ruang antar item + margin: Batas + enable: Aktifkan Dock/Taskbar + auto_hide: Sembunyi otomatis + label: Dock/Taskbar + padding: Lapisan + width: Lebar + gap: Celah + dock_side: Sisi dermaga +devtools: + settings_file: File Pengaturan + install_folder: Folder Instalasi + enable: Aktifkan alat pengembang + custom_config_file: Muat file konfigurasi khusus + data_folder: Folder Data + load: Memuat + app_folders: Folder aplikasi +apps_configurations: + app: + options: + float: Mengambang + force: Memaksa mengelola + pinned: Disematkan + unmanage: Tidak mengelola + title_readonly: Melihat {{name}} + workspace: Ruang kerja + category_placeholder: Tidak ada + ok_edit: Memperbarui + monitor_placeholder: Tidak ada + name: Nama + options_label: Opsi tambahan + ok_create: Membuat + category: Kategori + title_edit: Editting {{name}} + title_create: Membuat {{name}} + workspace_placeholder: Tidak ada + ok_readonly: Edit sebagai baru + bindings: Mengikat (perhatikan kedua opsi itu diperlukan) + monitor: Monitor + identifier: + and: DAN + matching_strategy: Strategi pencocokan + kind: Identifikasi oleh + or: ATAU + remove: Hapus blok + add_block: Tambahkan blok + id: Pengidentifikasi + negation: Meninggalkan pencocokan + delete: Menghapus + confirm_delete: Anda yakin ingin menghapus konfigurasi ini? + bundled_msg: >- + Konfigurasi yang dibundel ini tidak dapat diedit dan dirancang untuk memberi + Anda pengalaman terbaik tanpa kustomisasi. Mereka secara otomatis + mengonfigurasi aplikasi yang paling umum untuk Anda. + export: Ekspor + bundled_title: Aplikasi Config dibundel dengan Seelen + confirm_delete_title: Konfirmasi hapus + search: Mencari + swap: Menukar + import: Impor + new: Baru +extras: + github: GitHub + relaunch: Peluncuran kembali + discord: Perselisihan + exit: Berhenti/keluar + links: Tautan resmi + version: 'Versi: kapan' +shortcuts: + labels: + move_to_workspace_7: Pindah ke ruang kerja 7 + move_to_workspace_9: Pindah ke ruang kerja 9 + focus_bottom: Fokus dasar + focus_left: Fokus kiri + decrease_height: Tinggi penurunan + reserve_right: Cadangan hak + reserve_left: Cadangan kiri + focus_right: Fokus benar + reserve_stack: Tumpukan Cadangan + reserve_bottom: Cadangan Bawah + switch_workspace_1: Beralih ke ruang kerja 1 + switch_workspace_9: Beralih ke ruang kerja 9 + reserve_float: Cadangan float + increase_height: Tingkatkan tinggi + switch_workspace_3: Beralih ke ruang kerja 3 + restore_sizes: Kembalikan ukuran + switch_workspace_5: Beralih ke ruang kerja 5 + send_to_workspace_1: Kirim ke ruang kerja 1 + switch_workspace_7: Beralih ke ruang kerja 7 + send_to_workspace_8: Kirim ke Workspace 8 + reserve_top: Cadangan atasan + send_to_workspace_9: Kirim ke ruang kerja 9 + send_to_workspace_6: Kirim ke Workspace 6 + switch_workspace_4: Beralih ke ruang kerja 4 + move_to_workspace_1: Pindah ke ruang kerja 1 + send_to_workspace_5: Kirim ke Workspace 5 + send_to_workspace_0: Kirim ke ruang kerja 0 + focus_latest: Fokus Terbaru + switch_workspace_0: Beralih ke ruang kerja 0 + move_to_workspace_8: Pindah ke ruang kerja 8 + move_to_workspace_5: Pindah ke ruang kerja 5 + move_to_workspace_6: Pindah ke ruang kerja 6 + switch_workspace_8: Beralih ke ruang kerja 8 + move_to_workspace_3: Pindah ke ruang kerja 3 + switch_workspace_2: Beralih ke ruang kerja 2 + move_to_workspace_2: Pindah ke ruang kerja 2 + move_to_workspace_4: Pindah ke ruang kerja 4 + send_to_workspace_2: Kirim ke Workspace 2 + increase_width: Meningkatkan lebar + switch_workspace_6: Beralih ke ruang kerja 6 + focus_top: Fokus atas + send_to_workspace_4: Kirim ke Workspace 4 + move_to_workspace_0: Pindah ke ruang kerja 0 + decrease_width: Penurunan lebar + send_to_workspace_7: Kirim ke Workspace 7 + send_to_workspace_3: Kirim ke Workspace 3 + enable: Aktifkan pintasan terintegrasi (AHK) + enable_tooltip: >- + Nonaktifkan jika Anda akan mengimplementasikan jalan pintas Anda sendiri + menggunakan API Inti Seelen +open: Membuka +cancel: Membatalkan +save: Menyimpan +inProgress: Sedang berlangsung... +quit: Berhenti +delete: Menghapus +loading: Memuat... diff --git a/src/apps/settings/i18n/translations/is.yml b/src/apps/settings/i18n/translations/is.yml index 61191d66..e4af7083 100644 --- a/src/apps/settings/i18n/translations/is.yml +++ b/src/apps/settings/i18n/translations/is.yml @@ -1,193 +1,193 @@ -sides: - top: Efst - left: Vinstri - right: Ekki satt - bottom: Botn -header: - labels: - seelen_wm: Gluggastjóri - info: Upplýsingar - seelen_bar: Fancy tækjastikan - monitors: Fylgist með - shortcuts: Flýtileiðir - general: Almennt - specific_apps: Sérstök forrit - developer: Hönnuður - seelen_weg: Bryggju/verkefnabar -start: - title: Velkominn! - message_accent: Fínstilltu framleiðni þína með stæl! - message: >- - Verið velkomin í Seelen HÍ, fullkominn skrifborðsumhverfi með innbyggðan - flísar Windows Manager til að auka Windows 11 upplifun þína! Kannaðu nýtt - tímabil skilvirkni og fjölverkavinnslu með leiðandi viðmóti okkar og - háþróaðri eiginleika. -general: - theme: - description: Lýsing - label: Þemaupplýsingar - added: Þema þegar bætt við - author: Höfundur - add: Bæta við þema - placeholder: Veldu þema - enabled: Virkt þemu - tags: Merkimiðar - available: Laus - selected: Valinn - startup: Hlaupa í gangsetningu? - language: Tungumál - icon_pack: - label: Táknpakkar - accent_color: Hreim litur -toolbar: - placeholder: - description: Lýsing - author: Höfundur - select: Uppbygging tækjastiku - enable: Virkja Fancy tækjastiku - height: Hæð -wm: - border: - enable: Virkja landamæri glugga - width: Breidd landamæra - offset: Landamæri offset - description: Lýsing - workspace_offset: Vinnusvæði offset (framlegð) - disabled_windows10: Gluggastjórinn er ekki í boði fyrir Windows 10. - layout: Skipulag - space_between_containers: Rými milli gáma - resize_delta: Breyta stærð delta (%) - author: Höfundur - enable: Virkja gluggastjóra - workspace_padding: Vinnusvæði padding -weg: - items: - label: Hlutir - size: Stærð hlutar - gap: Rými milli atriða - zoom_size: Aðdráttarstærð (notuð fyrir þemu) - visible_separators: Sýnilegir skilju - width: Breidd - label: Bryggju/verkefnabar - dock_side: Bryggjuhlið - enable: Virkja bryggju/verkefnastiku - gap: Bil - auto_hide: Sjálfvirk fela - margin: Framlegð - padding: Padding -devtools: - load: Hlaða - app_folders: App möppur - settings_file: Stillingarskrá - custom_config_file: Hlaða sérsniðna config skrá - enable: Virkja verktaki verktaki - install_folder: Uppsetningarmöppu - data_folder: Gagnamappa -apps_configurations: - app: - options: - unmanage: Unanmanage - float: Fljóta - pinned: Fest - force: Valdastjórnun - monitor_placeholder: Enginn - workspace_placeholder: Enginn - name: Nafn - category_placeholder: Enginn - options_label: Auka valkostir - title_create: Búa til {{nafn}} - ok_readonly: Breyta sem nýjum - title_readonly: Skoða {{nafn}} - category: Flokkur - workspace: Vinnusvæði - monitor: Fylgstu með - bindings: Binding (athugaðu að báðir valkostirnir eru nauðsynlegir) - ok_edit: UPDATE - ok_create: Búa til - title_edit: Breyta {{name}} - identifier: - matching_strategy: Samsvarandi stefna - add_block: Bæta við blokk - or: Eða - and: Og - kind: Þekkja með - remove: Eyða blokk - negation: Afneitar samsvörun - id: Auðkenni - delete: Eyða - import: Flytja inn - confirm_delete: Ertu viss um að þú viljir eyða þessari stillingu/s? - export: Flytja út - confirm_delete_title: Staðfestu að eyða - search: Leitaðu - bundled_title: App stillt saman með Seelen - bundled_msg: >- - Þessar búnt stillingar eru ekki breytanlegar og eru hannaðar til að veita - þér bestu upplifunina án aðlögunar. Þeir stilla sjálfkrafa algengustu - forritin fyrir þig. - new: Nýtt - swap: Skiptu um -extras: - github: GitHub - links: Opinberir hlekkir - discord: Ósamræmi - version: Útgáfa - relaunch: Fylgdu aftur - exit: Hætta/hætta -shortcuts: - labels: - increase_height: Auka hæð - move_to_workspace_4: Farðu á Workspace 4 - focus_latest: Fókus síðast - reserve_bottom: Panta botn - decrease_width: Minnka breidd - reserve_left: Pantaðu til vinstri - switch_workspace_5: Skiptu yfir í vinnusvæði 5 - increase_width: Auka breidd - reserve_top: Panta topp - focus_right: Einbeittu þér rétt - move_to_workspace_5: Fara í Workspace 5 - switch_workspace_7: Skiptu yfir í vinnusvæði 7 - move_to_workspace_0: Fara á vinnusvæði 0 - send_to_workspace_8: Sendu á Workspace 8 - switch_workspace_9: Skiptu yfir í vinnusvæði 9 - send_to_workspace_1: Sendu á vinnusvæði 1 - move_to_workspace_2: Farðu í Workspace 2 - focus_left: Einbeittu til vinstri - send_to_workspace_6: Sendu á Workspace 6 - send_to_workspace_9: Sendu á Workspace 9 - decrease_height: Minnka hæð - reserve_right: Pantaðu rétt - restore_sizes: Endurheimta stærðir - reserve_stack: Panta stafla - switch_workspace_2: Skiptu yfir í vinnusvæði 2 - move_to_workspace_8: Farðu á vinnusvæði 8 - send_to_workspace_4: Sendu á Workspace 4 - move_to_workspace_1: Fara á vinnusvæði 1 - move_to_workspace_7: Farðu í vinnusvæði 7 - send_to_workspace_7: Sendu á Workspace 7 - switch_workspace_6: Skiptu yfir í vinnusvæði 6 - move_to_workspace_6: Fara á vinnusvæði 6 - move_to_workspace_9: Fara á vinnusvæði 9 - focus_bottom: Fókus botn - switch_workspace_3: Skiptu yfir í vinnusvæði 3 - focus_top: Fókus toppur - send_to_workspace_3: Senda á Workspace 3 - switch_workspace_0: Skiptu yfir í vinnusvæði 0 - reserve_float: Varasjóður flot - switch_workspace_1: Skiptu yfir í vinnusvæði 1 - send_to_workspace_2: Sendu á Workspace 2 - switch_workspace_8: Skiptu yfir í vinnusvæði 8 - move_to_workspace_3: Farðu í vinnusvæði 3 - send_to_workspace_5: Sendu á Workspace 5 - send_to_workspace_0: Sendu á Workspace 0 - switch_workspace_4: Skiptu yfir í vinnusvæði 4 - enable: Virkja samþætta flýtileiðir (AHK) - enable_tooltip: Slökktu á ef þú munt innleiða eigin flýtileiðir með Seelen Core API -delete: Eyða -loading: Hleðsla ... -inProgress: Í vinnslu... -quit: Hættu -open: Opið -save: Vista -cancel: Hætta við +sides: + top: Efst + left: Vinstri + right: Ekki satt + bottom: Botn +header: + labels: + seelen_wm: Gluggastjóri + info: Upplýsingar + seelen_bar: Fancy tækjastikan + monitors: Fylgist með + shortcuts: Flýtileiðir + general: Almennt + specific_apps: Sérstök forrit + developer: Hönnuður + seelen_weg: Bryggju/verkefnabar +start: + title: Velkominn! + message_accent: Fínstilltu framleiðni þína með stæl! + message: >- + Verið velkomin í Seelen HÍ, fullkominn skrifborðsumhverfi með innbyggðan + flísar Windows Manager til að auka Windows 11 upplifun þína! Kannaðu nýtt + tímabil skilvirkni og fjölverkavinnslu með leiðandi viðmóti okkar og + háþróaðri eiginleika. +general: + theme: + description: Lýsing + label: Þemaupplýsingar + added: Þema þegar bætt við + author: Höfundur + add: Bæta við þema + placeholder: Veldu þema + enabled: Virkt þemu + tags: Merkimiðar + available: Laus + selected: Valinn + startup: Hlaupa í gangsetningu? + language: Tungumál + icon_pack: + label: Táknpakkar + accent_color: Hreim litur +toolbar: + placeholder: + description: Lýsing + author: Höfundur + select: Uppbygging tækjastiku + enable: Virkja Fancy tækjastiku + height: Hæð +wm: + border: + enable: Virkja landamæri glugga + width: Breidd landamæra + offset: Landamæri offset + description: Lýsing + workspace_offset: Vinnusvæði offset (framlegð) + disabled_windows10: Gluggastjórinn er ekki í boði fyrir Windows 10. + layout: Skipulag + space_between_containers: Rými milli gáma + resize_delta: Breyta stærð delta (%) + author: Höfundur + enable: Virkja gluggastjóra + workspace_padding: Vinnusvæði padding +weg: + items: + label: Hlutir + size: Stærð hlutar + gap: Rými milli atriða + zoom_size: Aðdráttarstærð (notuð fyrir þemu) + visible_separators: Sýnilegir skilju + width: Breidd + label: Bryggju/verkefnabar + dock_side: Bryggjuhlið + enable: Virkja bryggju/verkefnastiku + gap: Bil + auto_hide: Sjálfvirk fela + margin: Framlegð + padding: Padding +devtools: + load: Hlaða + app_folders: App möppur + settings_file: Stillingarskrá + custom_config_file: Hlaða sérsniðna config skrá + enable: Virkja verktaki verktaki + install_folder: Uppsetningarmöppu + data_folder: Gagnamappa +apps_configurations: + app: + options: + unmanage: Unanmanage + float: Fljóta + pinned: Fest + force: Valdastjórnun + monitor_placeholder: Enginn + workspace_placeholder: Enginn + name: Nafn + category_placeholder: Enginn + options_label: Auka valkostir + title_create: Búa til {{nafn}} + ok_readonly: Breyta sem nýjum + title_readonly: Skoða {{nafn}} + category: Flokkur + workspace: Vinnusvæði + monitor: Fylgstu með + bindings: Binding (athugaðu að báðir valkostirnir eru nauðsynlegir) + ok_edit: UPDATE + ok_create: Búa til + title_edit: Breyta {{name}} + identifier: + matching_strategy: Samsvarandi stefna + add_block: Bæta við blokk + or: Eða + and: Og + kind: Þekkja með + remove: Eyða blokk + negation: Afneitar samsvörun + id: Auðkenni + delete: Eyða + import: Flytja inn + confirm_delete: Ertu viss um að þú viljir eyða þessari stillingu/s? + export: Flytja út + confirm_delete_title: Staðfestu að eyða + search: Leitaðu + bundled_title: App stillt saman með Seelen + bundled_msg: >- + Þessar búnt stillingar eru ekki breytanlegar og eru hannaðar til að veita + þér bestu upplifunina án aðlögunar. Þeir stilla sjálfkrafa algengustu + forritin fyrir þig. + new: Nýtt + swap: Skiptu um +extras: + github: GitHub + links: Opinberir hlekkir + discord: Ósamræmi + version: Útgáfa + relaunch: Fylgdu aftur + exit: Hætta/hætta +shortcuts: + labels: + increase_height: Auka hæð + move_to_workspace_4: Farðu á Workspace 4 + focus_latest: Fókus síðast + reserve_bottom: Panta botn + decrease_width: Minnka breidd + reserve_left: Pantaðu til vinstri + switch_workspace_5: Skiptu yfir í vinnusvæði 5 + increase_width: Auka breidd + reserve_top: Panta topp + focus_right: Einbeittu þér rétt + move_to_workspace_5: Fara í Workspace 5 + switch_workspace_7: Skiptu yfir í vinnusvæði 7 + move_to_workspace_0: Fara á vinnusvæði 0 + send_to_workspace_8: Sendu á Workspace 8 + switch_workspace_9: Skiptu yfir í vinnusvæði 9 + send_to_workspace_1: Sendu á vinnusvæði 1 + move_to_workspace_2: Farðu í Workspace 2 + focus_left: Einbeittu til vinstri + send_to_workspace_6: Sendu á Workspace 6 + send_to_workspace_9: Sendu á Workspace 9 + decrease_height: Minnka hæð + reserve_right: Pantaðu rétt + restore_sizes: Endurheimta stærðir + reserve_stack: Panta stafla + switch_workspace_2: Skiptu yfir í vinnusvæði 2 + move_to_workspace_8: Farðu á vinnusvæði 8 + send_to_workspace_4: Sendu á Workspace 4 + move_to_workspace_1: Fara á vinnusvæði 1 + move_to_workspace_7: Farðu í vinnusvæði 7 + send_to_workspace_7: Sendu á Workspace 7 + switch_workspace_6: Skiptu yfir í vinnusvæði 6 + move_to_workspace_6: Fara á vinnusvæði 6 + move_to_workspace_9: Fara á vinnusvæði 9 + focus_bottom: Fókus botn + switch_workspace_3: Skiptu yfir í vinnusvæði 3 + focus_top: Fókus toppur + send_to_workspace_3: Senda á Workspace 3 + switch_workspace_0: Skiptu yfir í vinnusvæði 0 + reserve_float: Varasjóður flot + switch_workspace_1: Skiptu yfir í vinnusvæði 1 + send_to_workspace_2: Sendu á Workspace 2 + switch_workspace_8: Skiptu yfir í vinnusvæði 8 + move_to_workspace_3: Farðu í vinnusvæði 3 + send_to_workspace_5: Sendu á Workspace 5 + send_to_workspace_0: Sendu á Workspace 0 + switch_workspace_4: Skiptu yfir í vinnusvæði 4 + enable: Virkja samþætta flýtileiðir (AHK) + enable_tooltip: Slökktu á ef þú munt innleiða eigin flýtileiðir með Seelen Core API +delete: Eyða +loading: Hleðsla ... +inProgress: Í vinnslu... +quit: Hættu +open: Opið +save: Vista +cancel: Hætta við diff --git a/src/apps/settings/i18n/translations/it.yml b/src/apps/settings/i18n/translations/it.yml index 8c4e8e56..a15f86ed 100644 --- a/src/apps/settings/i18n/translations/it.yml +++ b/src/apps/settings/i18n/translations/it.yml @@ -1,195 +1,195 @@ -sides: - top: Superiore - left: Sinistra - bottom: Metter il fondo a - right: Destra -header: - labels: - developer: Sviluppatrice - info: Informazione - general: Generale - shortcuts: Scorciatoie - seelen_weg: Dock/TaskBar - monitors: Monitor - seelen_bar: Barra degli strumenti di fantasia - seelen_wm: Gestore delle finestre - specific_apps: App specifiche -start: - title: Benvenuta! - message: >- - Benvenuti a Seelen UI, l'ambiente desktop finale con un gestore Windows - incorporato per migliorare la tua esperienza di Windows 11! Esplora una - nuova era di efficienza e multitasking con la nostra interfaccia intuitiva e - funzionalità avanzate. - message_accent: Ottimizza la tua produttività con stile! -general: - theme: - author: Autrice - placeholder: Seleziona il tema - description: Descrizione - enabled: Temi abilitati - add: Aggiungi tema - added: Tema già aggiunto - tags: Tag - label: Informazioni sul tema - selected: Selezionata - available: Disponibile - language: Lingua - startup: Eseguire all'avvio? - icon_pack: - label: Icon pacchetti - accent_color: Colore accento -toolbar: - placeholder: - author: Autrice - description: Descrizione - select: Struttura della barra degli strumenti - height: Altezza - enable: Abilita barra degli strumenti di fantasia -wm: - border: - width: Larghezza del bordo - offset: Offset del confine - enable: Abilita il bordo della finestra - layout: Disposizione - description: Descrizione - author: Autrice - resize_delta: Ridimensiona Delta (%) - disabled_windows10: Il gestore delle finestre non è disponibile per Windows 10. - enable: Abilita il gestore delle finestre - space_between_containers: Spazio tra contenitori - workspace_offset: Offset degli spazi di lavoro (margini) - workspace_padding: Padding degli spazi di lavoro -weg: - items: - label: Elementi - zoom_size: Dimensione ingrandita (usata per temi) - visible_separators: Separatori visibili - size: Dimensione dell'oggetto - gap: Spazio tra gli oggetti - padding: Imbottitura - auto_hide: Nascondi automaticamente - margin: Margine - width: Larghezza - gap: Spacco - label: Dock/TaskBar - enable: Abilita dock/barra delle applicazioni - dock_side: Lato dock -devtools: - load: Carico - custom_config_file: Carica il file di configurazione personalizzato - data_folder: Cartella dati - enable: Abilita strumenti per sviluppatori - app_folders: Cartelle di app - install_folder: Cartella di installazione - settings_file: File Impostazioni -apps_configurations: - app: - options: - float: Galleggiante - force: Force Manage - pinned: Appuntato - unmanage: Unmanage - monitor_placeholder: Nessuno - ok_create: Creare - workspace_placeholder: Nessuno - ok_edit: Aggiornamento - category: Categoria - name: Nome - category_placeholder: Nessuno - title_readonly: Visualizzazione {{name}} - title_edit: Moditing {{name}} - workspace: Spazio di lavoro - bindings: Binding (Nota che sono richieste entrambe le opzioni) - title_create: Creazione di {{name}} - ok_readonly: Modifica come nuovo - monitor: Tenere sotto controllo - options_label: Opzioni extra - identifier: - and: E - or: O - add_block: Aggiungi blocco - id: Identificatrice - negation: Negare la corrispondenza - remove: Elimina il blocco - matching_strategy: Strategia di abbinamento - kind: Identifica da - delete: Eliminare - export: Esportare - search: Ricerca - confirm_delete_title: Conferma cancellazione - swap: Scambio - new: Nuova - import: Importare - confirm_delete: Sei sicuro di voler eliminare questa configurazione/e? - bundled_title: APP Configta in bundle con Seelen - bundled_msg: >- - Queste configurazioni in bundle non sono modificabili e sono progettate per - offrirti la migliore esperienza senza personalizzazione. Configurano - automaticamente le applicazioni più comuni per te. -extras: - relaunch: Rilancio - discord: Discordia - version: Versione - github: Github - links: Collegamenti ufficiali - exit: ESCIO/USCI -shortcuts: - labels: - reserve_float: Float di riserva - move_to_workspace_5: Passa all'area di lavoro 5 - move_to_workspace_2: Passa all'area di lavoro 2 - switch_workspace_1: Passa all'area di lavoro 1 - move_to_workspace_4: Passa all'area di lavoro 4 - focus_bottom: Focus Bottom - focus_top: Focus top - move_to_workspace_9: Passa all'area di lavoro 9 - switch_workspace_7: Passa all'area di lavoro 7 - move_to_workspace_1: Passa all'area di lavoro 1 - send_to_workspace_0: Invia a Workspace 0 - switch_workspace_4: Passa all'area di lavoro 4 - increase_width: Aumentare la larghezza - send_to_workspace_6: Invia a Workspace 6 - move_to_workspace_0: Passa all'area di lavoro 0 - send_to_workspace_2: Invia a Workspace 2 - send_to_workspace_8: Invia a Workspace 8 - restore_sizes: Ripristinare le dimensioni - reserve_bottom: Riserva Bottom - move_to_workspace_6: Passa all'area di lavoro 6 - send_to_workspace_9: Invia a Workspace 9 - increase_height: Aumenta l'altezza - send_to_workspace_3: Invia a Workspace 3 - send_to_workspace_4: Invia a Workspace 4 - focus_right: Concentrati bene - reserve_left: Riserva a sinistra - decrease_height: Diminuire l'altezza - switch_workspace_8: Passa all'area di lavoro 8 - switch_workspace_9: Passa all'area di lavoro 9 - switch_workspace_2: Passa all'area di lavoro 2 - focus_latest: Focus Ultime - send_to_workspace_1: Invia a Workspace 1 - switch_workspace_0: Passa all'area di lavoro 0 - focus_left: Focus a sinistra - switch_workspace_6: Passa all'area di lavoro 6 - move_to_workspace_8: Passa all'area di lavoro 8 - move_to_workspace_3: Passa all'area di lavoro 3 - reserve_top: Riserva Top - decrease_width: Diminuire la larghezza - reserve_right: Riserva a destra - send_to_workspace_7: Invia a Workspace 7 - reserve_stack: Stack di riserva - send_to_workspace_5: Invia a Workspace 5 - switch_workspace_5: Passa all'area di lavoro 5 - switch_workspace_3: Passa all'area di lavoro 3 - move_to_workspace_7: Passa all'area di lavoro 7 - enable: Abilita scorciatoie integrate (AHK) - enable_tooltip: >- - Disabilita se implementerai i tuoi collegamenti utilizzando l'API Core - Seelen -delete: Eliminare -inProgress: In corso... -open: Aprire -quit: Esentata -save: Salva -loading: Caricamento... -cancel: Annulla +sides: + top: Superiore + left: Sinistra + bottom: Metter il fondo a + right: Destra +header: + labels: + developer: Sviluppatrice + info: Informazione + general: Generale + shortcuts: Scorciatoie + seelen_weg: Dock/TaskBar + monitors: Monitor + seelen_bar: Barra degli strumenti di fantasia + seelen_wm: Gestore delle finestre + specific_apps: App specifiche +start: + title: Benvenuta! + message: >- + Benvenuti a Seelen UI, l'ambiente desktop finale con un gestore Windows + incorporato per migliorare la tua esperienza di Windows 11! Esplora una + nuova era di efficienza e multitasking con la nostra interfaccia intuitiva e + funzionalità avanzate. + message_accent: Ottimizza la tua produttività con stile! +general: + theme: + author: Autrice + placeholder: Seleziona il tema + description: Descrizione + enabled: Temi abilitati + add: Aggiungi tema + added: Tema già aggiunto + tags: Tag + label: Informazioni sul tema + selected: Selezionata + available: Disponibile + language: Lingua + startup: Eseguire all'avvio? + icon_pack: + label: Icon pacchetti + accent_color: Colore accento +toolbar: + placeholder: + author: Autrice + description: Descrizione + select: Struttura della barra degli strumenti + height: Altezza + enable: Abilita barra degli strumenti di fantasia +wm: + border: + width: Larghezza del bordo + offset: Offset del confine + enable: Abilita il bordo della finestra + layout: Disposizione + description: Descrizione + author: Autrice + resize_delta: Ridimensiona Delta (%) + disabled_windows10: Il gestore delle finestre non è disponibile per Windows 10. + enable: Abilita il gestore delle finestre + space_between_containers: Spazio tra contenitori + workspace_offset: Offset degli spazi di lavoro (margini) + workspace_padding: Padding degli spazi di lavoro +weg: + items: + label: Elementi + zoom_size: Dimensione ingrandita (usata per temi) + visible_separators: Separatori visibili + size: Dimensione dell'oggetto + gap: Spazio tra gli oggetti + padding: Imbottitura + auto_hide: Nascondi automaticamente + margin: Margine + width: Larghezza + gap: Spacco + label: Dock/TaskBar + enable: Abilita dock/barra delle applicazioni + dock_side: Lato dock +devtools: + load: Carico + custom_config_file: Carica il file di configurazione personalizzato + data_folder: Cartella dati + enable: Abilita strumenti per sviluppatori + app_folders: Cartelle di app + install_folder: Cartella di installazione + settings_file: File Impostazioni +apps_configurations: + app: + options: + float: Galleggiante + force: Force Manage + pinned: Appuntato + unmanage: Unmanage + monitor_placeholder: Nessuno + ok_create: Creare + workspace_placeholder: Nessuno + ok_edit: Aggiornamento + category: Categoria + name: Nome + category_placeholder: Nessuno + title_readonly: Visualizzazione {{name}} + title_edit: Moditing {{name}} + workspace: Spazio di lavoro + bindings: Binding (Nota che sono richieste entrambe le opzioni) + title_create: Creazione di {{name}} + ok_readonly: Modifica come nuovo + monitor: Tenere sotto controllo + options_label: Opzioni extra + identifier: + and: E + or: O + add_block: Aggiungi blocco + id: Identificatrice + negation: Negare la corrispondenza + remove: Elimina il blocco + matching_strategy: Strategia di abbinamento + kind: Identifica da + delete: Eliminare + export: Esportare + search: Ricerca + confirm_delete_title: Conferma cancellazione + swap: Scambio + new: Nuova + import: Importare + confirm_delete: Sei sicuro di voler eliminare questa configurazione/e? + bundled_title: APP Configta in bundle con Seelen + bundled_msg: >- + Queste configurazioni in bundle non sono modificabili e sono progettate per + offrirti la migliore esperienza senza personalizzazione. Configurano + automaticamente le applicazioni più comuni per te. +extras: + relaunch: Rilancio + discord: Discordia + version: Versione + github: Github + links: Collegamenti ufficiali + exit: ESCIO/USCI +shortcuts: + labels: + reserve_float: Float di riserva + move_to_workspace_5: Passa all'area di lavoro 5 + move_to_workspace_2: Passa all'area di lavoro 2 + switch_workspace_1: Passa all'area di lavoro 1 + move_to_workspace_4: Passa all'area di lavoro 4 + focus_bottom: Focus Bottom + focus_top: Focus top + move_to_workspace_9: Passa all'area di lavoro 9 + switch_workspace_7: Passa all'area di lavoro 7 + move_to_workspace_1: Passa all'area di lavoro 1 + send_to_workspace_0: Invia a Workspace 0 + switch_workspace_4: Passa all'area di lavoro 4 + increase_width: Aumentare la larghezza + send_to_workspace_6: Invia a Workspace 6 + move_to_workspace_0: Passa all'area di lavoro 0 + send_to_workspace_2: Invia a Workspace 2 + send_to_workspace_8: Invia a Workspace 8 + restore_sizes: Ripristinare le dimensioni + reserve_bottom: Riserva Bottom + move_to_workspace_6: Passa all'area di lavoro 6 + send_to_workspace_9: Invia a Workspace 9 + increase_height: Aumenta l'altezza + send_to_workspace_3: Invia a Workspace 3 + send_to_workspace_4: Invia a Workspace 4 + focus_right: Concentrati bene + reserve_left: Riserva a sinistra + decrease_height: Diminuire l'altezza + switch_workspace_8: Passa all'area di lavoro 8 + switch_workspace_9: Passa all'area di lavoro 9 + switch_workspace_2: Passa all'area di lavoro 2 + focus_latest: Focus Ultime + send_to_workspace_1: Invia a Workspace 1 + switch_workspace_0: Passa all'area di lavoro 0 + focus_left: Focus a sinistra + switch_workspace_6: Passa all'area di lavoro 6 + move_to_workspace_8: Passa all'area di lavoro 8 + move_to_workspace_3: Passa all'area di lavoro 3 + reserve_top: Riserva Top + decrease_width: Diminuire la larghezza + reserve_right: Riserva a destra + send_to_workspace_7: Invia a Workspace 7 + reserve_stack: Stack di riserva + send_to_workspace_5: Invia a Workspace 5 + switch_workspace_5: Passa all'area di lavoro 5 + switch_workspace_3: Passa all'area di lavoro 3 + move_to_workspace_7: Passa all'area di lavoro 7 + enable: Abilita scorciatoie integrate (AHK) + enable_tooltip: >- + Disabilita se implementerai i tuoi collegamenti utilizzando l'API Core + Seelen +delete: Eliminare +inProgress: In corso... +open: Aprire +quit: Esentata +save: Salva +loading: Caricamento... +cancel: Annulla diff --git a/src/apps/settings/i18n/translations/ja.yml b/src/apps/settings/i18n/translations/ja.yml index 3d63df2c..b2d34131 100644 --- a/src/apps/settings/i18n/translations/ja.yml +++ b/src/apps/settings/i18n/translations/ja.yml @@ -1,193 +1,193 @@ -sides: - left: 左 - right: 右 - top: 上 - bottom: 下 -header: - labels: - developer: 開発者向け - info: このアプリについて - general: 全般 - shortcuts: ショートカットキー - seelen_wm: ウィンドウマネージャー - specific_apps: アプリごとの設定 - monitors: モニター - seelen_weg: ドック(タスクバー) - seelen_bar: ツールバー -start: - title: ようこそ! - message: >- - SeelenUIにようこそ! - 組み込みのタイル型ウィンドウマネージャーを備えた究極のデスクトップ環境で、あなたのWindows 11での体験を向上させます! - 直感的なインターフェースと高度な機能で効率的なマルチタスクの新時代を探求しましょう。 - message_accent: あなた好みのスタイリングで生産性を最適化! -general: - theme: - author: 製作者 - description: 説明 - add: テーマを追加 - tags: タグ - added: テーマはすでに追加されています - enabled: テーマが有効になっています - label: テーマ情報 - placeholder: テーマを選択 - available: 利用可能 - selected: 選択済み - startup: 起動時に実行する - language: 言語 - icon_pack: - label: アイコンパック - wallpaper: - select: 壁紙を選択 - accent_color: アクセントカラー -toolbar: - placeholder: - description: 説明 - author: 製作者 - select: ツールバーのテーマ - height: 高さ - enable: ツールバーを有効にする -wm: - border: - offset: 境界線の余白 - enable: ウィンドウの境界線を描画する - width: 線幅 - author: 製作者 - layout: レイアウト - description: 説明 - enable: ウィンドウマネージャーを有効にする - workspace_offset: ワークスペース全体の間隔(マージン) - disabled_windows10: ウィンドウマネージャーはWindows 10では利用できません。 - space_between_containers: ウィンドウ間の間隔 - resize_delta: リサイズ時の変化率(%) - workspace_padding: ワークスペースの全体の間隔 -weg: - items: - size: アイテムのサイズ - zoom_size: ズームされたときのサイズ(一部のテーマで使用) - visible_separators: セパレーターを表示する - label: アイテム - gap: アイテム間のスペース - width: ドックの幅 - margin: ドックの隙間 - gap: ずれ - padding: 余白 - label: ドック(タスクバー) - auto_hide: 自動的に隠す - dock_side: ドックの位置 - enable: ドック(タスクバー)を有効にする -devtools: - load: ロード - data_folder: データフォルダー - app_folders: アプリフォルダー - enable: 開発者ツールを有効にする - settings_file: 設定ファイル - install_folder: インストールフォルダー - custom_config_file: カスタム構成ファイルをロードする -apps_configurations: - app: - options: - float: フロート - force: 強制 - pinned: ピン留め - unmanage: 管理しない - category_placeholder: なし - monitor_placeholder: なし - workspace: ワークスペース - ok_edit: 適用 - category: カテゴリー - monitor: モニター - ok_create: 作成 - bindings: バインディング(両方のオプションが必要です) - ok_readonly: 新規設定を作成 - workspace_placeholder: なし - title_edit: 「{{name}}」を編集する - title_readonly: 「{{name}}」を表示しています - name: 名前 - title_create: '{{name}}を作成する' - options_label: オプション - identifier: - id: 識別子 - and: かつ - or: または - negation: マッチングを否定する - remove: ブロックを削除 - matching_strategy: マッチングの方法 - add_block: ブロックを追加 - kind: 識別方法 - search: 検索 - export: エクスポート - delete: 消去 - import: インポート - new: 新規 - swap: 入れ替え - confirm_delete: この構成を削除したいですか? - confirm_delete_title: 削除の確認 - bundled_msg: >- - これらのバンドルされた構成は編集可能ではなく、カスタマイズなしで最高の体験を提供するように設計されています。 - 最も一般的なアプリケーションを自動的に構成します。 - bundled_title: Seelenにバンドルされたアプリの構成 -extras: - discord: Discord - version: バージョン - github: GitHub - relaunch: 再起動 - links: リンク - exit: 終了 -shortcuts: - labels: - reserve_left: 左側を予約 - switch_workspace_5: ワークスペース5に切り替え - send_to_workspace_1: ワークスペース1に送信 - restore_sizes: サイズを復元 - send_to_workspace_3: ワークスペース3に送信 - move_to_workspace_2: ワークスペース2に移動 - send_to_workspace_2: ワークスペース2に送信 - reserve_stack: スタックを予約 - move_to_workspace_0: ワークスペース0に移動 - switch_workspace_2: ワークスペース2に切り替え - increase_height: 高さを増やす - switch_workspace_3: ワークスペース3に切り替え - focus_top: 上にフォーカス - send_to_workspace_9: ワークスペース9に送信 - send_to_workspace_0: ワークスペース0に送信 - move_to_workspace_4: ワークスペース4に移動 - send_to_workspace_5: ワークスペース5に送信 - move_to_workspace_6: ワークスペース6に移動 - decrease_height: 高さを減らす - switch_workspace_7: ワークスペース7に切り替え - reserve_bottom: 下側を予約 - focus_right: 右にフォーカス - switch_workspace_1: ワークスペース1に切り替え - reserve_right: 右側を予約 - switch_workspace_8: ワークスペース8に切り替え - switch_workspace_0: ワークスペース0に切り替え - send_to_workspace_8: ワークスペース8に送信 - move_to_workspace_8: ワークスペース8に移動 - switch_workspace_6: ワークスペース6に切り替え - send_to_workspace_4: ワークスペース4に送信 - reserve_float: フロートを予約 - focus_latest: 最新のウィンドウにフォーカス - decrease_width: 幅を減らす - reserve_top: 上側を予約 - move_to_workspace_1: ワークスペース1に移動 - switch_workspace_4: ワークスペース4に切り替え - move_to_workspace_7: ワークスペース7に移動 - switch_workspace_9: ワークスペース9に切り替え - focus_bottom: 下にフォーカス - move_to_workspace_9: ワークスペース9に移動 - move_to_workspace_3: ワークスペース3に移動 - send_to_workspace_6: ワークスペース6に送信 - increase_width: 幅を増やす - move_to_workspace_5: ワークスペース5に移動 - focus_left: 左にフォーカス - send_to_workspace_7: ワークスペース7に送信 - enable: AutoHotkeyを使用した統合ショートカットを有効にする - enable_tooltip: Seelen Core APIを使用して独自のショートカットを実装する場合は無効にしてください -delete: 消去 -loading: 読み込み中... -inProgress: 近日実装予定... -quit: 終了 -open: 開く -save: 保存 -cancel: キャンセル +sides: + left: 左 + right: 右 + top: 上 + bottom: 下 +header: + labels: + developer: 開発者向け + info: このアプリについて + general: 全般 + shortcuts: ショートカットキー + seelen_wm: ウィンドウマネージャー + specific_apps: アプリごとの設定 + monitors: モニター + seelen_weg: ドック(タスクバー) + seelen_bar: ツールバー +start: + title: ようこそ! + message: >- + SeelenUIにようこそ! + 組み込みのタイル型ウィンドウマネージャーを備えた究極のデスクトップ環境で、あなたのWindows 11での体験を向上させます! + 直感的なインターフェースと高度な機能で効率的なマルチタスクの新時代を探求しましょう。 + message_accent: あなた好みのスタイリングで生産性を最適化! +general: + theme: + author: 製作者 + description: 説明 + add: テーマを追加 + tags: タグ + added: テーマはすでに追加されています + enabled: テーマが有効になっています + label: テーマ情報 + placeholder: テーマを選択 + available: 利用可能 + selected: 選択済み + startup: 起動時に実行する + language: 言語 + icon_pack: + label: アイコンパック + wallpaper: + select: 壁紙を選択 + accent_color: アクセントカラー +toolbar: + placeholder: + description: 説明 + author: 製作者 + select: ツールバーのテーマ + height: 高さ + enable: ツールバーを有効にする +wm: + border: + offset: 境界線の余白 + enable: ウィンドウの境界線を描画する + width: 線幅 + author: 製作者 + layout: レイアウト + description: 説明 + enable: ウィンドウマネージャーを有効にする + workspace_offset: ワークスペース全体の間隔(マージン) + disabled_windows10: ウィンドウマネージャーはWindows 10では利用できません。 + space_between_containers: ウィンドウ間の間隔 + resize_delta: リサイズ時の変化率(%) + workspace_padding: ワークスペースの全体の間隔 +weg: + items: + size: アイテムのサイズ + zoom_size: ズームされたときのサイズ(一部のテーマで使用) + visible_separators: セパレーターを表示する + label: アイテム + gap: アイテム間のスペース + width: ドックの幅 + margin: ドックの隙間 + gap: ずれ + padding: 余白 + label: ドック(タスクバー) + auto_hide: 自動的に隠す + dock_side: ドックの位置 + enable: ドック(タスクバー)を有効にする +devtools: + load: ロード + data_folder: データフォルダー + app_folders: アプリフォルダー + enable: 開発者ツールを有効にする + settings_file: 設定ファイル + install_folder: インストールフォルダー + custom_config_file: カスタム構成ファイルをロードする +apps_configurations: + app: + options: + float: フロート + force: 強制 + pinned: ピン留め + unmanage: 管理しない + category_placeholder: なし + monitor_placeholder: なし + workspace: ワークスペース + ok_edit: 適用 + category: カテゴリー + monitor: モニター + ok_create: 作成 + bindings: バインディング(両方のオプションが必要です) + ok_readonly: 新規設定を作成 + workspace_placeholder: なし + title_edit: 「{{name}}」を編集する + title_readonly: 「{{name}}」を表示しています + name: 名前 + title_create: '{{name}}を作成する' + options_label: オプション + identifier: + id: 識別子 + and: かつ + or: または + negation: マッチングを否定する + remove: ブロックを削除 + matching_strategy: マッチングの方法 + add_block: ブロックを追加 + kind: 識別方法 + search: 検索 + export: エクスポート + delete: 消去 + import: インポート + new: 新規 + swap: 入れ替え + confirm_delete: この構成を削除したいですか? + confirm_delete_title: 削除の確認 + bundled_msg: >- + これらのバンドルされた構成は編集可能ではなく、カスタマイズなしで最高の体験を提供するように設計されています。 + 最も一般的なアプリケーションを自動的に構成します。 + bundled_title: Seelenにバンドルされたアプリの構成 +extras: + discord: Discord + version: バージョン + github: GitHub + relaunch: 再起動 + links: リンク + exit: 終了 +shortcuts: + labels: + reserve_left: 左側を予約 + switch_workspace_5: ワークスペース5に切り替え + send_to_workspace_1: ワークスペース1に送信 + restore_sizes: サイズを復元 + send_to_workspace_3: ワークスペース3に送信 + move_to_workspace_2: ワークスペース2に移動 + send_to_workspace_2: ワークスペース2に送信 + reserve_stack: スタックを予約 + move_to_workspace_0: ワークスペース0に移動 + switch_workspace_2: ワークスペース2に切り替え + increase_height: 高さを増やす + switch_workspace_3: ワークスペース3に切り替え + focus_top: 上にフォーカス + send_to_workspace_9: ワークスペース9に送信 + send_to_workspace_0: ワークスペース0に送信 + move_to_workspace_4: ワークスペース4に移動 + send_to_workspace_5: ワークスペース5に送信 + move_to_workspace_6: ワークスペース6に移動 + decrease_height: 高さを減らす + switch_workspace_7: ワークスペース7に切り替え + reserve_bottom: 下側を予約 + focus_right: 右にフォーカス + switch_workspace_1: ワークスペース1に切り替え + reserve_right: 右側を予約 + switch_workspace_8: ワークスペース8に切り替え + switch_workspace_0: ワークスペース0に切り替え + send_to_workspace_8: ワークスペース8に送信 + move_to_workspace_8: ワークスペース8に移動 + switch_workspace_6: ワークスペース6に切り替え + send_to_workspace_4: ワークスペース4に送信 + reserve_float: フロートを予約 + focus_latest: 最新のウィンドウにフォーカス + decrease_width: 幅を減らす + reserve_top: 上側を予約 + move_to_workspace_1: ワークスペース1に移動 + switch_workspace_4: ワークスペース4に切り替え + move_to_workspace_7: ワークスペース7に移動 + switch_workspace_9: ワークスペース9に切り替え + focus_bottom: 下にフォーカス + move_to_workspace_9: ワークスペース9に移動 + move_to_workspace_3: ワークスペース3に移動 + send_to_workspace_6: ワークスペース6に送信 + increase_width: 幅を増やす + move_to_workspace_5: ワークスペース5に移動 + focus_left: 左にフォーカス + send_to_workspace_7: ワークスペース7に送信 + enable: AutoHotkeyを使用した統合ショートカットを有効にする + enable_tooltip: Seelen Core APIを使用して独自のショートカットを実装する場合は無効にしてください +delete: 消去 +loading: 読み込み中... +inProgress: 近日実装予定... +quit: 終了 +open: 開く +save: 保存 +cancel: キャンセル diff --git a/src/apps/settings/i18n/translations/ka.yml b/src/apps/settings/i18n/translations/ka.yml index fb3cc082..b0c3411f 100644 --- a/src/apps/settings/i18n/translations/ka.yml +++ b/src/apps/settings/i18n/translations/ka.yml @@ -1,195 +1,195 @@ -sides: - left: მარცხენა - top: თავი - right: სწორი - bottom: ძირი -header: - labels: - general: გენერალი - monitors: მონიტორები - info: ინფორმაცია - developer: დეველოპერი ქალი - seelen_bar: ლამაზი პანელი - seelen_weg: დოკ/დავალების ზოლი - shortcuts: მალსახმობები - seelen_wm: ფანჯრის მენეჯერი - specific_apps: კონკრეტული პროგრამები -start: - message_accent: თქვენი პროდუქტიულობის ოპტიმიზაცია სტილით! - title: კეთილი იყოს თქვენი მობრძანება! - message: >- - კეთილი იყოს თქვენი მობრძანება Seelen UI- ში, საბოლოო დესკტოპის გარემოში, - რომელშიც შედის Windows Windows- ის მენეჯერი, თქვენი Windows 11 გამოცდილების - გასაუმჯობესებლად! გამოიკვლიეთ ეფექტურობისა და მრავალმხრივი ახალი ეპოქა ჩვენი - ინტუიციური ინტერფეისით და მოწინავე მახასიათებლებით. -general: - theme: - description: აღწერილობა - label: თემის ინფორმაცია - add: თემის დამატება - added: თემა უკვე დამატებულია - tags: საკვანძო ნიშნები - placeholder: აირჩიეთ თემა - enabled: ჩართულია თემები - author: ავტორი - selected: არჩეული - available: არსებული - language: Ენა - startup: გაშვებით გაშვებით? - icon_pack: - label: ხატის პაკეტები - accent_color: აქცენტის ფერი -toolbar: - placeholder: - description: აღწერილობა - author: ავტორი - select: ინსტრუმენტთა პანელის სტრუქტურა - height: სიმაღლე - enable: ჩართეთ ლამაზი პანელი -wm: - border: - enable: ფანჯრის საზღვრის ჩართვა - offset: სასაზღვრო ოფსეტური - width: საზღვრის სიგანე - description: აღწერილობა - author: ავტორი - enable: ფანჯრის მენეჯერის ჩართვა - disabled_windows10: ფანჯრის მენეჯერი არ არის ხელმისაწვდომი Windows 10 -ისთვის. - resize_delta: დელტას ზომის შეცვლა (%) - space_between_containers: სივრცე კონტეინერებს შორის - workspace_offset: სამუშაო ადგილები ოფსეტური (ზღვარი) - workspace_padding: სამუშაო ადგილები padding - layout: გამოფენა -weg: - items: - label: ნივთები - zoom_size: მასშტაბური ზომა (გამოიყენება თემებისთვის) - size: ნივთის ზომა - visible_separators: ხილული გამყოფი - gap: სივრცე ნივთებს შორის - auto_hide: Ავტომატური დამალვა - width: სიგანე - label: დოკ/დავალების ზოლი - padding: ბადება - margin: ზღვარი - gap: ხარპი - dock_side: დოკის მხარე - enable: ჩართეთ dock/taskbar -devtools: - enable: ჩართეთ დეველოპერის ინსტრუმენტები - app_folders: აპლიკაციის საქაღალდეები - custom_config_file: ჩატვირთეთ პერსონალური კონფიგურაციის ფაილი - settings_file: პარამეტრების ფაილი - install_folder: ინსტალაციის საქაღალდე - data_folder: მონაცემთა საქაღალდე - load: დატვირთვა -apps_configurations: - app: - options: - unmanage: გაუგებრობა - pinned: დადგენილება - force: ძალის მართვა - float: ტივტივი - category: კატეგორია - ok_create: Შექმნა - bindings: სავალდებულო (შენიშვნა საჭიროა ორივე ვარიანტი) - category_placeholder: არაფერი - workspace_placeholder: არაფერი - options_label: დამატებითი პარამეტრები - ok_edit: განახლება - title_edit: რედაქტირება {{სახელი}} - workspace: სამუშაო ადგილი - ok_readonly: რედაქტირება როგორც ახალი - title_create: '{{სახელის შექმნა}}' - name: სახელი - title_readonly: ნახვა {{სახელი}} - monitor_placeholder: არაფერი - monitor: შემოწმება - identifier: - and: და - id: პირადობა - add_block: ბლოკის დამატება - negation: უარყოფითი შესატყვისი - kind: იდენტიფიცირება - matching_strategy: შესაბამისი სტრატეგია - remove: წაშალეთ ბლოკი - or: ან - import: იმპორტი - export: ექსპორტი - confirm_delete: დარწმუნებული ხართ, რომ გსურთ ამ კონფიგურაციის წაშლა? - search: ძებნა - confirm_delete_title: დაადასტურეთ წაშლა - bundled_msg: >- - ეს შეფუთული კონფიგურაციები არ არის რედაქტირებული და შექმნილია იმისთვის, რომ - საუკეთესო გამოცდილება მოგაწოდოთ პერსონალიზაციის გარეშე. ისინი ავტომატურად - კონფიგურაციას უკეთებენ თქვენთვის ყველაზე გავრცელებულ პროგრამებს. - bundled_title: აპლიკაციის კონფიგურაცია შეფუთულია Seelen- ით - swap: გაცვლა - delete: წაშლა - new: ახალი -extras: - version: ვერსია - exit: დატოვება/გასვლა - discord: უთანასწორობა - github: გითუბ - relaunch: გაუქმება - links: ოფიციალური ბმულები -shortcuts: - labels: - move_to_workspace_3: გადავიდეთ სამუშაო ადგილებზე 3 - increase_width: სიგანის გაზრდა - send_to_workspace_1: გაგზავნეთ სამუშაო სივრცეში 1 - reserve_bottom: სარეზერვო ქვედა - reserve_left: ნაკრძალი დარჩა - move_to_workspace_4: გადავიდეთ სამუშაო ადგილებზე 4 - reserve_stack: სარეზერვო დასტა - focus_right: ფოკუსირება სწორად - move_to_workspace_8: გადავიდეთ სამუშაო ადგილებზე 8 - switch_workspace_0: გადადით სამუშაო ადგილებზე 0 - switch_workspace_2: გადადით სამუშაო ადგილებზე 2 - switch_workspace_9: გადადით სამუშაო ადგილებზე 9 - focus_latest: ფოკუსირება უახლესი - move_to_workspace_1: გადავიდეთ სამუშაო სივრცეში 1 - send_to_workspace_2: გაგზავნეთ სამუშაო ადგილებზე 2 - focus_top: ფოკუსირება - restore_sizes: აღადგინეთ ზომები - send_to_workspace_6: გაგზავნეთ სამუშაო სივრცეში 6 - decrease_width: სიგანის შემცირება - send_to_workspace_3: გაგზავნეთ სამუშაო ადგილებზე 3 - switch_workspace_3: გადადით სამუშაო ადგილებზე 3 - move_to_workspace_6: გადადით სამუშაო ადგილებზე 6 - send_to_workspace_4: გაგზავნეთ სამუშაო სივრცეში 4 - switch_workspace_6: გადადით სამუშაო ადგილებზე 6 - reserve_top: სარეზერვო ზედა - reserve_right: უფლება - send_to_workspace_7: გაგზავნეთ სამუშაო ადგილებზე 7 - focus_bottom: ფოკუსირება - switch_workspace_4: გადადით სამუშაო ადგილებზე 4 - focus_left: ფოკუსირება მარცხნივ - switch_workspace_1: გადადით სამუშაო ადგილებზე 1 - move_to_workspace_2: გადავიდეთ სამუშაო ადგილებზე 2 - send_to_workspace_9: გაგზავნეთ სამუშაო სივრცეში 9 - move_to_workspace_0: გადადით სამუშაო ადგილებზე 0 - decrease_height: სიმაღლის შემცირება - send_to_workspace_5: გაგზავნეთ სამუშაო სივრცეში 5 - move_to_workspace_5: გადადით სამუშაო ადგილებზე 5 - switch_workspace_8: გადადით სამუშაო ადგილებზე 8 - switch_workspace_7: გადადით სამუშაო ადგილებზე 7 - send_to_workspace_0: გაგზავნეთ სამუშაო სივრცეში 0 - move_to_workspace_7: გადადით სამუშაო ადგილებზე 7 - increase_height: სიმაღლის გაზრდა - move_to_workspace_9: გადავიდეთ სამუშაო სივრცეში 9 - send_to_workspace_8: გაგზავნეთ სამუშაო სივრცეში 8 - switch_workspace_5: გადადით სამუშაო ადგილებზე 5 - reserve_float: სარეზერვო float - enable: ინტეგრირებული მალსახმობების ჩართვა (AHK) - enable_tooltip: >- - გამორთეთ, თუ თქვენ განახორციელებთ საკუთარ მალსახმობებს Seelen Core API– ს - გამოყენებით -save: Გადარჩენა -inProgress: Პროგრესირებს... -loading: Ჩატვირთვა... -quit: მიტოვება -delete: წაშლა -open: გახსნა -cancel: გაუქმება +sides: + left: მარცხენა + top: თავი + right: სწორი + bottom: ძირი +header: + labels: + general: გენერალი + monitors: მონიტორები + info: ინფორმაცია + developer: დეველოპერი ქალი + seelen_bar: ლამაზი პანელი + seelen_weg: დოკ/დავალების ზოლი + shortcuts: მალსახმობები + seelen_wm: ფანჯრის მენეჯერი + specific_apps: კონკრეტული პროგრამები +start: + message_accent: თქვენი პროდუქტიულობის ოპტიმიზაცია სტილით! + title: კეთილი იყოს თქვენი მობრძანება! + message: >- + კეთილი იყოს თქვენი მობრძანება Seelen UI- ში, საბოლოო დესკტოპის გარემოში, + რომელშიც შედის Windows Windows- ის მენეჯერი, თქვენი Windows 11 გამოცდილების + გასაუმჯობესებლად! გამოიკვლიეთ ეფექტურობისა და მრავალმხრივი ახალი ეპოქა ჩვენი + ინტუიციური ინტერფეისით და მოწინავე მახასიათებლებით. +general: + theme: + description: აღწერილობა + label: თემის ინფორმაცია + add: თემის დამატება + added: თემა უკვე დამატებულია + tags: საკვანძო ნიშნები + placeholder: აირჩიეთ თემა + enabled: ჩართულია თემები + author: ავტორი + selected: არჩეული + available: არსებული + language: Ენა + startup: გაშვებით გაშვებით? + icon_pack: + label: ხატის პაკეტები + accent_color: აქცენტის ფერი +toolbar: + placeholder: + description: აღწერილობა + author: ავტორი + select: ინსტრუმენტთა პანელის სტრუქტურა + height: სიმაღლე + enable: ჩართეთ ლამაზი პანელი +wm: + border: + enable: ფანჯრის საზღვრის ჩართვა + offset: სასაზღვრო ოფსეტური + width: საზღვრის სიგანე + description: აღწერილობა + author: ავტორი + enable: ფანჯრის მენეჯერის ჩართვა + disabled_windows10: ფანჯრის მენეჯერი არ არის ხელმისაწვდომი Windows 10 -ისთვის. + resize_delta: დელტას ზომის შეცვლა (%) + space_between_containers: სივრცე კონტეინერებს შორის + workspace_offset: სამუშაო ადგილები ოფსეტური (ზღვარი) + workspace_padding: სამუშაო ადგილები padding + layout: გამოფენა +weg: + items: + label: ნივთები + zoom_size: მასშტაბური ზომა (გამოიყენება თემებისთვის) + size: ნივთის ზომა + visible_separators: ხილული გამყოფი + gap: სივრცე ნივთებს შორის + auto_hide: Ავტომატური დამალვა + width: სიგანე + label: დოკ/დავალების ზოლი + padding: ბადება + margin: ზღვარი + gap: ხარპი + dock_side: დოკის მხარე + enable: ჩართეთ dock/taskbar +devtools: + enable: ჩართეთ დეველოპერის ინსტრუმენტები + app_folders: აპლიკაციის საქაღალდეები + custom_config_file: ჩატვირთეთ პერსონალური კონფიგურაციის ფაილი + settings_file: პარამეტრების ფაილი + install_folder: ინსტალაციის საქაღალდე + data_folder: მონაცემთა საქაღალდე + load: დატვირთვა +apps_configurations: + app: + options: + unmanage: გაუგებრობა + pinned: დადგენილება + force: ძალის მართვა + float: ტივტივი + category: კატეგორია + ok_create: Შექმნა + bindings: სავალდებულო (შენიშვნა საჭიროა ორივე ვარიანტი) + category_placeholder: არაფერი + workspace_placeholder: არაფერი + options_label: დამატებითი პარამეტრები + ok_edit: განახლება + title_edit: რედაქტირება {{სახელი}} + workspace: სამუშაო ადგილი + ok_readonly: რედაქტირება როგორც ახალი + title_create: '{{სახელის შექმნა}}' + name: სახელი + title_readonly: ნახვა {{სახელი}} + monitor_placeholder: არაფერი + monitor: შემოწმება + identifier: + and: და + id: პირადობა + add_block: ბლოკის დამატება + negation: უარყოფითი შესატყვისი + kind: იდენტიფიცირება + matching_strategy: შესაბამისი სტრატეგია + remove: წაშალეთ ბლოკი + or: ან + import: იმპორტი + export: ექსპორტი + confirm_delete: დარწმუნებული ხართ, რომ გსურთ ამ კონფიგურაციის წაშლა? + search: ძებნა + confirm_delete_title: დაადასტურეთ წაშლა + bundled_msg: >- + ეს შეფუთული კონფიგურაციები არ არის რედაქტირებული და შექმნილია იმისთვის, რომ + საუკეთესო გამოცდილება მოგაწოდოთ პერსონალიზაციის გარეშე. ისინი ავტომატურად + კონფიგურაციას უკეთებენ თქვენთვის ყველაზე გავრცელებულ პროგრამებს. + bundled_title: აპლიკაციის კონფიგურაცია შეფუთულია Seelen- ით + swap: გაცვლა + delete: წაშლა + new: ახალი +extras: + version: ვერსია + exit: დატოვება/გასვლა + discord: უთანასწორობა + github: გითუბ + relaunch: გაუქმება + links: ოფიციალური ბმულები +shortcuts: + labels: + move_to_workspace_3: გადავიდეთ სამუშაო ადგილებზე 3 + increase_width: სიგანის გაზრდა + send_to_workspace_1: გაგზავნეთ სამუშაო სივრცეში 1 + reserve_bottom: სარეზერვო ქვედა + reserve_left: ნაკრძალი დარჩა + move_to_workspace_4: გადავიდეთ სამუშაო ადგილებზე 4 + reserve_stack: სარეზერვო დასტა + focus_right: ფოკუსირება სწორად + move_to_workspace_8: გადავიდეთ სამუშაო ადგილებზე 8 + switch_workspace_0: გადადით სამუშაო ადგილებზე 0 + switch_workspace_2: გადადით სამუშაო ადგილებზე 2 + switch_workspace_9: გადადით სამუშაო ადგილებზე 9 + focus_latest: ფოკუსირება უახლესი + move_to_workspace_1: გადავიდეთ სამუშაო სივრცეში 1 + send_to_workspace_2: გაგზავნეთ სამუშაო ადგილებზე 2 + focus_top: ფოკუსირება + restore_sizes: აღადგინეთ ზომები + send_to_workspace_6: გაგზავნეთ სამუშაო სივრცეში 6 + decrease_width: სიგანის შემცირება + send_to_workspace_3: გაგზავნეთ სამუშაო ადგილებზე 3 + switch_workspace_3: გადადით სამუშაო ადგილებზე 3 + move_to_workspace_6: გადადით სამუშაო ადგილებზე 6 + send_to_workspace_4: გაგზავნეთ სამუშაო სივრცეში 4 + switch_workspace_6: გადადით სამუშაო ადგილებზე 6 + reserve_top: სარეზერვო ზედა + reserve_right: უფლება + send_to_workspace_7: გაგზავნეთ სამუშაო ადგილებზე 7 + focus_bottom: ფოკუსირება + switch_workspace_4: გადადით სამუშაო ადგილებზე 4 + focus_left: ფოკუსირება მარცხნივ + switch_workspace_1: გადადით სამუშაო ადგილებზე 1 + move_to_workspace_2: გადავიდეთ სამუშაო ადგილებზე 2 + send_to_workspace_9: გაგზავნეთ სამუშაო სივრცეში 9 + move_to_workspace_0: გადადით სამუშაო ადგილებზე 0 + decrease_height: სიმაღლის შემცირება + send_to_workspace_5: გაგზავნეთ სამუშაო სივრცეში 5 + move_to_workspace_5: გადადით სამუშაო ადგილებზე 5 + switch_workspace_8: გადადით სამუშაო ადგილებზე 8 + switch_workspace_7: გადადით სამუშაო ადგილებზე 7 + send_to_workspace_0: გაგზავნეთ სამუშაო სივრცეში 0 + move_to_workspace_7: გადადით სამუშაო ადგილებზე 7 + increase_height: სიმაღლის გაზრდა + move_to_workspace_9: გადავიდეთ სამუშაო სივრცეში 9 + send_to_workspace_8: გაგზავნეთ სამუშაო სივრცეში 8 + switch_workspace_5: გადადით სამუშაო ადგილებზე 5 + reserve_float: სარეზერვო float + enable: ინტეგრირებული მალსახმობების ჩართვა (AHK) + enable_tooltip: >- + გამორთეთ, თუ თქვენ განახორციელებთ საკუთარ მალსახმობებს Seelen Core API– ს + გამოყენებით +save: Გადარჩენა +inProgress: Პროგრესირებს... +loading: Ჩატვირთვა... +quit: მიტოვება +delete: წაშლა +open: გახსნა +cancel: გაუქმება diff --git a/src/apps/settings/i18n/translations/km.yml b/src/apps/settings/i18n/translations/km.yml index ca2475ee..00e844d7 100644 --- a/src/apps/settings/i18n/translations/km.yml +++ b/src/apps/settings/i18n/translations/km.yml @@ -1,193 +1,193 @@ -sides: - bottom: បាត - right: ត្រូវហើយ។ - top: កំពូល - left: ឆ្វេង -header: - labels: - general: ទូទៅ - monitors: ម៉ូនីទ័រ - shortcuts: ផ្លូវកាត់ - info: ព័ត៌មាន - developer: អ្នកអភិវឌ្ឍន៍ - seelen_wm: កម្មវិធីគ្រប់គ្រងបង្អួច - seelen_weg: ចត/របារភារកិច្ច - seelen_bar: របារឧបករណ៍ពុម្ពអក្សរក្បូរក្បាច់ - specific_apps: កម្មវិធីជាក់លាក់ -start: - title: សូមស្វាគមន៍! - message_accent: បង្កើនផលិតភាពរបស់អ្នកជាមួយនឹងរចនាប័ទ្ម! - message: >- - សូមស្វាគមន៍មកកាន់ Seelen UI - ដែលជាបរិស្ថានផ្ទៃតុចុងក្រោយដែលមានកម្មវិធីគ្រប់គ្រងបង្អួចដាក់បញ្ចូល - ដើម្បីបង្កើនបទពិសោធន៍ Windows 11 របស់អ្នក! ស្វែងរកយុគសម័យថ្មីនៃប្រសិទ្ធភាព - និងកិច្ចការច្រើនជាមួយនឹងចំណុចប្រទាក់វិចារណញាណរបស់យើង និងមុខងារកម្រិតខ្ពស់។ -general: - theme: - description: ការពិពណ៌នា - placeholder: ជ្រើសរើសប្រធានបទ - tags: ស្លាក - author: អ្នកនិពន្ធ - add: បន្ថែមប្រធានបទ - label: ព័ត៌មានអំពីប្រធានបទ - enabled: ស្បែកដែលបានបើក - added: ប្រធានបទត្រូវបានបន្ថែមរួចហើយ - selected: បានជ្រើស - available: មានរបយោចន៍ - language: ភាសា - startup: ដំណើរការនៅពេលចាប់ផ្ដើម? - icon_pack: - label: រូបតំណាងកញ្ចប់ - accent_color: ពណ៌សង្កត់សំឡេង -toolbar: - placeholder: - description: ការពិពណ៌នា - select: រចនាសម្ព័ន្ធរបារឧបករណ៍ - author: អ្នកនិពន្ធ - height: កម្ពស់ - enable: បើករបារឧបករណ៍ពុម្ពអក្សរក្បូរក្បាច់ -wm: - border: - enable: បើកស៊ុមបង្អួច - offset: ព្រំដែនអុហ្វសិត - width: ទទឹងព្រំដែន - description: ការពិពណ៌នា - workspace_padding: ចន្លោះកន្លែងធ្វើការ - disabled_windows10: កម្មវិធីគ្រប់គ្រងបង្អួចមិនមានសម្រាប់ Windows 10 ទេ។ - layout: ប្លង់ - author: អ្នកនិពន្ធ - space_between_containers: ចន្លោះរវាងកុងតឺន័រ - enable: បើកកម្មវិធីគ្រប់គ្រងបង្អួច - workspace_offset: កន្លែងធ្វើការអុហ្វសិត (រឹម) - resize_delta: ប្តូរទំហំដីសណ្តរ (%) -weg: - items: - label: ធាតុ - visible_separators: សញ្ញាបំបែកដែលអាចមើលឃើញ - gap: ចន្លោះរវាងធាតុ - size: ទំហំធាតុ - zoom_size: ទំហំពង្រីក (ប្រើសម្រាប់ស្បែក) - width: ទទឹង - padding: ទ្រនាប់ - label: ចត/របារភារកិច្ច - auto_hide: លាក់ដោយស្វ័យប្រវត្តិ - gap: គម្លាត - margin: រឹម - enable: បើកដំណើរការ Dock/Taskbar - dock_side: ចំហៀងចត -devtools: - install_folder: ថតឯកសារដំឡើង - enable: បើកឧបករណ៍អ្នកអភិវឌ្ឍន៍ - custom_config_file: ផ្ទុកឯកសារកំណត់រចនាសម្ព័ន្ធផ្ទាល់ខ្លួន - app_folders: ថតកម្មវិធី - load: ផ្ទុក - settings_file: ឯកសារការកំណត់ - data_folder: ថតទិន្នន័យ -apps_configurations: - app: - options: - pinned: ខ្ទាស់ - float: អណ្តែត - force: គ្រប់គ្រងដោយបង្ខំ - unmanage: មិនគ្រប់គ្រង - workspace_placeholder: គ្មាន - workspace: កន្លែងធ្វើការ - monitor_placeholder: គ្មាន - category_placeholder: គ្មាន - category: ប្រភេទ - name: ឈ្មោះ - options_label: ជម្រើសបន្ថែម - title_create: ការបង្កើត {{name}} - title_readonly: កំពុងមើល {{name}} - title_edit: ការកែសម្រួល {{name}} - ok_edit: ធ្វើបច្ចុប្បន្នភាព - monitor: ម៉ូនីទ័រ - ok_create: បង្កើត - bindings: ការចង (ចំណាំជម្រើសទាំងពីរត្រូវបានទាមទារ) - ok_readonly: កែសម្រួលដូចថ្មី។ - identifier: - and: និង - remove: លុបប្លុក - add_block: បន្ថែមប្លុក - negation: ការផ្គូផ្គងអវិជ្ជមាន - or: ឬ - matching_strategy: យុទ្ធសាស្ត្រផ្គូផ្គង - kind: កំណត់អត្តសញ្ញាណដោយ - id: អ្នកកំណត់អត្តសញ្ញាណ - import: នាំចូល - search: ស្វែងរក - new: ថ្មី។ - swap: ប្តូរ - export: នាំចេញ - delete: លុប - bundled_title: កម្មវិធីកំណត់រចនាសម្ព័ន្ធបានរួមបញ្ចូលជាមួយ Seelen - confirm_delete_title: បញ្ជាក់ការលុប - bundled_msg: >- - ការ​កំណត់​រចនាសម្ព័ន្ធ​ជា​កញ្ចប់​ទាំង​នេះ​មិន​អាច​កែ​សម្រួល​បាន​ទេ - ហើយ​ត្រូវ​បាន​រចនា​ឡើង​ដើម្បី​ផ្ដល់​ឱ្យ​អ្នក​នូវ​បទ​ពិសោធ​ដ៏​ល្អ​បំផុត​ដោយ​មិន​ចាំបាច់​ប្ដូរ​តាម​បំណង។ - ពួកគេកំណត់រចនាសម្ព័ន្ធកម្មវិធីធម្មតាបំផុតសម្រាប់អ្នកដោយស្វ័យប្រវត្តិ។ - confirm_delete: តើអ្នកប្រាកដថាចង់លុបការកំណត់រចនាសម្ព័ន្ធនេះទេ? -extras: - version: កំណែ - github: GitHub - discord: ការមិនចុះសម្រុងគ្នា។ - exit: ចេញ/ចេញ - relaunch: បើកដំណើរការឡើងវិញ - links: តំណភ្ជាប់ផ្លូវការ -shortcuts: - labels: - reserve_float: បម្រុងអណ្តែត - move_to_workspace_4: ផ្លាស់ទីទៅកន្លែងធ្វើការ 4 - restore_sizes: ស្ដារទំហំ - move_to_workspace_7: ផ្លាស់ទីទៅកន្លែងធ្វើការ ៧ - increase_height: បង្កើនកម្ពស់ - focus_latest: ផ្តោតចុងក្រោយ - send_to_workspace_5: ផ្ញើទៅកន្លែងធ្វើការ ៥ - send_to_workspace_1: ផ្ញើទៅកាន់កន្លែងធ្វើការ 1 - send_to_workspace_3: ផ្ញើទៅកន្លែងធ្វើការ ៣ - send_to_workspace_4: ផ្ញើទៅកន្លែងធ្វើការ ៤ - move_to_workspace_5: ផ្លាស់ទីទៅកន្លែងធ្វើការ 5 - send_to_workspace_7: ផ្ញើទៅកន្លែងធ្វើការ ៧ - send_to_workspace_2: ផ្ញើទៅកន្លែងធ្វើការ ២ - focus_left: ផ្តោតទៅឆ្វេង - reserve_right: រក្សាសិទ្ធិ - send_to_workspace_9: ផ្ញើទៅកន្លែងធ្វើការ ៩ - send_to_workspace_0: ផ្ញើទៅកន្លែងធ្វើការ 0 - move_to_workspace_2: ផ្លាស់ទីទៅកន្លែងធ្វើការ 2 - reserve_top: បម្រុងទុកកំពូល - reserve_stack: ស្តុកទុក - decrease_height: បន្ថយកម្ពស់ - focus_top: ផ្តោតកំពូល - switch_workspace_2: ប្តូរទៅកន្លែងធ្វើការ 2 - switch_workspace_3: ប្តូរទៅកន្លែងធ្វើការ 3 - decrease_width: បន្ថយទទឹង - reserve_bottom: បាតបម្រុង - switch_workspace_8: ប្តូរទៅកន្លែងធ្វើការ 8 - switch_workspace_4: ប្តូរទៅកន្លែងធ្វើការ 4 - move_to_workspace_3: ផ្លាស់ទីទៅកន្លែងធ្វើការ 3 - increase_width: បង្កើនទទឹង - switch_workspace_0: ប្តូរទៅកន្លែងធ្វើការ 0 - switch_workspace_5: ប្តូរទៅកន្លែងធ្វើការ 5 - reserve_left: កក់ទុកខាងឆ្វេង - move_to_workspace_6: ផ្លាស់ទីទៅកន្លែងធ្វើការ ៦ - focus_right: ផ្តោតលើស្តាំ - move_to_workspace_0: ផ្លាស់ទីទៅកន្លែងធ្វើការ 0 - move_to_workspace_8: ផ្លាស់ទីទៅកន្លែងធ្វើការ ៨ - send_to_workspace_8: ផ្ញើទៅកន្លែងធ្វើការ ៨ - send_to_workspace_6: ផ្ញើទៅកន្លែងធ្វើការ ៦ - switch_workspace_1: ប្តូរទៅកន្លែងធ្វើការ 1 - switch_workspace_9: ប្តូរទៅកន្លែងធ្វើការ 9 - switch_workspace_6: ប្តូរទៅកន្លែងធ្វើការ 6 - move_to_workspace_9: ផ្លាស់ទីទៅកន្លែងធ្វើការ ៩ - move_to_workspace_1: ផ្លាស់ទីទៅកន្លែងធ្វើការ 1 - switch_workspace_7: ប្តូរទៅកន្លែងធ្វើការ 7 - focus_bottom: ផ្ដោតបាត - enable_tooltip: បិទប្រសិនបើអ្នកនឹងអនុវត្តផ្លូវកាត់ផ្ទាល់ខ្លួនរបស់អ្នកដោយប្រើ Seelen Core Api - enable: បើកផ្លូវកាត់រួមបញ្ចូលគ្នា (ahk) -cancel: បោះបង់ -inProgress: កំពុង​ដំណើរការ... -delete: លុប -loading: កំពុង​ផ្ទុក... -save: រក្សាទុក -quit: ឈប់ -open: បើក +sides: + bottom: បាត + right: ត្រូវហើយ។ + top: កំពូល + left: ឆ្វេង +header: + labels: + general: ទូទៅ + monitors: ម៉ូនីទ័រ + shortcuts: ផ្លូវកាត់ + info: ព័ត៌មាន + developer: អ្នកអភិវឌ្ឍន៍ + seelen_wm: កម្មវិធីគ្រប់គ្រងបង្អួច + seelen_weg: ចត/របារភារកិច្ច + seelen_bar: របារឧបករណ៍ពុម្ពអក្សរក្បូរក្បាច់ + specific_apps: កម្មវិធីជាក់លាក់ +start: + title: សូមស្វាគមន៍! + message_accent: បង្កើនផលិតភាពរបស់អ្នកជាមួយនឹងរចនាប័ទ្ម! + message: >- + សូមស្វាគមន៍មកកាន់ Seelen UI + ដែលជាបរិស្ថានផ្ទៃតុចុងក្រោយដែលមានកម្មវិធីគ្រប់គ្រងបង្អួចដាក់បញ្ចូល + ដើម្បីបង្កើនបទពិសោធន៍ Windows 11 របស់អ្នក! ស្វែងរកយុគសម័យថ្មីនៃប្រសិទ្ធភាព + និងកិច្ចការច្រើនជាមួយនឹងចំណុចប្រទាក់វិចារណញាណរបស់យើង និងមុខងារកម្រិតខ្ពស់។ +general: + theme: + description: ការពិពណ៌នា + placeholder: ជ្រើសរើសប្រធានបទ + tags: ស្លាក + author: អ្នកនិពន្ធ + add: បន្ថែមប្រធានបទ + label: ព័ត៌មានអំពីប្រធានបទ + enabled: ស្បែកដែលបានបើក + added: ប្រធានបទត្រូវបានបន្ថែមរួចហើយ + selected: បានជ្រើស + available: មានរបយោចន៍ + language: ភាសា + startup: ដំណើរការនៅពេលចាប់ផ្ដើម? + icon_pack: + label: រូបតំណាងកញ្ចប់ + accent_color: ពណ៌សង្កត់សំឡេង +toolbar: + placeholder: + description: ការពិពណ៌នា + select: រចនាសម្ព័ន្ធរបារឧបករណ៍ + author: អ្នកនិពន្ធ + height: កម្ពស់ + enable: បើករបារឧបករណ៍ពុម្ពអក្សរក្បូរក្បាច់ +wm: + border: + enable: បើកស៊ុមបង្អួច + offset: ព្រំដែនអុហ្វសិត + width: ទទឹងព្រំដែន + description: ការពិពណ៌នា + workspace_padding: ចន្លោះកន្លែងធ្វើការ + disabled_windows10: កម្មវិធីគ្រប់គ្រងបង្អួចមិនមានសម្រាប់ Windows 10 ទេ។ + layout: ប្លង់ + author: អ្នកនិពន្ធ + space_between_containers: ចន្លោះរវាងកុងតឺន័រ + enable: បើកកម្មវិធីគ្រប់គ្រងបង្អួច + workspace_offset: កន្លែងធ្វើការអុហ្វសិត (រឹម) + resize_delta: ប្តូរទំហំដីសណ្តរ (%) +weg: + items: + label: ធាតុ + visible_separators: សញ្ញាបំបែកដែលអាចមើលឃើញ + gap: ចន្លោះរវាងធាតុ + size: ទំហំធាតុ + zoom_size: ទំហំពង្រីក (ប្រើសម្រាប់ស្បែក) + width: ទទឹង + padding: ទ្រនាប់ + label: ចត/របារភារកិច្ច + auto_hide: លាក់ដោយស្វ័យប្រវត្តិ + gap: គម្លាត + margin: រឹម + enable: បើកដំណើរការ Dock/Taskbar + dock_side: ចំហៀងចត +devtools: + install_folder: ថតឯកសារដំឡើង + enable: បើកឧបករណ៍អ្នកអភិវឌ្ឍន៍ + custom_config_file: ផ្ទុកឯកសារកំណត់រចនាសម្ព័ន្ធផ្ទាល់ខ្លួន + app_folders: ថតកម្មវិធី + load: ផ្ទុក + settings_file: ឯកសារការកំណត់ + data_folder: ថតទិន្នន័យ +apps_configurations: + app: + options: + pinned: ខ្ទាស់ + float: អណ្តែត + force: គ្រប់គ្រងដោយបង្ខំ + unmanage: មិនគ្រប់គ្រង + workspace_placeholder: គ្មាន + workspace: កន្លែងធ្វើការ + monitor_placeholder: គ្មាន + category_placeholder: គ្មាន + category: ប្រភេទ + name: ឈ្មោះ + options_label: ជម្រើសបន្ថែម + title_create: ការបង្កើត {{name}} + title_readonly: កំពុងមើល {{name}} + title_edit: ការកែសម្រួល {{name}} + ok_edit: ធ្វើបច្ចុប្បន្នភាព + monitor: ម៉ូនីទ័រ + ok_create: បង្កើត + bindings: ការចង (ចំណាំជម្រើសទាំងពីរត្រូវបានទាមទារ) + ok_readonly: កែសម្រួលដូចថ្មី។ + identifier: + and: និង + remove: លុបប្លុក + add_block: បន្ថែមប្លុក + negation: ការផ្គូផ្គងអវិជ្ជមាន + or: ឬ + matching_strategy: យុទ្ធសាស្ត្រផ្គូផ្គង + kind: កំណត់អត្តសញ្ញាណដោយ + id: អ្នកកំណត់អត្តសញ្ញាណ + import: នាំចូល + search: ស្វែងរក + new: ថ្មី។ + swap: ប្តូរ + export: នាំចេញ + delete: លុប + bundled_title: កម្មវិធីកំណត់រចនាសម្ព័ន្ធបានរួមបញ្ចូលជាមួយ Seelen + confirm_delete_title: បញ្ជាក់ការលុប + bundled_msg: >- + ការ​កំណត់​រចនាសម្ព័ន្ធ​ជា​កញ្ចប់​ទាំង​នេះ​មិន​អាច​កែ​សម្រួល​បាន​ទេ + ហើយ​ត្រូវ​បាន​រចនា​ឡើង​ដើម្បី​ផ្ដល់​ឱ្យ​អ្នក​នូវ​បទ​ពិសោធ​ដ៏​ល្អ​បំផុត​ដោយ​មិន​ចាំបាច់​ប្ដូរ​តាម​បំណង។ + ពួកគេកំណត់រចនាសម្ព័ន្ធកម្មវិធីធម្មតាបំផុតសម្រាប់អ្នកដោយស្វ័យប្រវត្តិ។ + confirm_delete: តើអ្នកប្រាកដថាចង់លុបការកំណត់រចនាសម្ព័ន្ធនេះទេ? +extras: + version: កំណែ + github: GitHub + discord: ការមិនចុះសម្រុងគ្នា។ + exit: ចេញ/ចេញ + relaunch: បើកដំណើរការឡើងវិញ + links: តំណភ្ជាប់ផ្លូវការ +shortcuts: + labels: + reserve_float: បម្រុងអណ្តែត + move_to_workspace_4: ផ្លាស់ទីទៅកន្លែងធ្វើការ 4 + restore_sizes: ស្ដារទំហំ + move_to_workspace_7: ផ្លាស់ទីទៅកន្លែងធ្វើការ ៧ + increase_height: បង្កើនកម្ពស់ + focus_latest: ផ្តោតចុងក្រោយ + send_to_workspace_5: ផ្ញើទៅកន្លែងធ្វើការ ៥ + send_to_workspace_1: ផ្ញើទៅកាន់កន្លែងធ្វើការ 1 + send_to_workspace_3: ផ្ញើទៅកន្លែងធ្វើការ ៣ + send_to_workspace_4: ផ្ញើទៅកន្លែងធ្វើការ ៤ + move_to_workspace_5: ផ្លាស់ទីទៅកន្លែងធ្វើការ 5 + send_to_workspace_7: ផ្ញើទៅកន្លែងធ្វើការ ៧ + send_to_workspace_2: ផ្ញើទៅកន្លែងធ្វើការ ២ + focus_left: ផ្តោតទៅឆ្វេង + reserve_right: រក្សាសិទ្ធិ + send_to_workspace_9: ផ្ញើទៅកន្លែងធ្វើការ ៩ + send_to_workspace_0: ផ្ញើទៅកន្លែងធ្វើការ 0 + move_to_workspace_2: ផ្លាស់ទីទៅកន្លែងធ្វើការ 2 + reserve_top: បម្រុងទុកកំពូល + reserve_stack: ស្តុកទុក + decrease_height: បន្ថយកម្ពស់ + focus_top: ផ្តោតកំពូល + switch_workspace_2: ប្តូរទៅកន្លែងធ្វើការ 2 + switch_workspace_3: ប្តូរទៅកន្លែងធ្វើការ 3 + decrease_width: បន្ថយទទឹង + reserve_bottom: បាតបម្រុង + switch_workspace_8: ប្តូរទៅកន្លែងធ្វើការ 8 + switch_workspace_4: ប្តូរទៅកន្លែងធ្វើការ 4 + move_to_workspace_3: ផ្លាស់ទីទៅកន្លែងធ្វើការ 3 + increase_width: បង្កើនទទឹង + switch_workspace_0: ប្តូរទៅកន្លែងធ្វើការ 0 + switch_workspace_5: ប្តូរទៅកន្លែងធ្វើការ 5 + reserve_left: កក់ទុកខាងឆ្វេង + move_to_workspace_6: ផ្លាស់ទីទៅកន្លែងធ្វើការ ៦ + focus_right: ផ្តោតលើស្តាំ + move_to_workspace_0: ផ្លាស់ទីទៅកន្លែងធ្វើការ 0 + move_to_workspace_8: ផ្លាស់ទីទៅកន្លែងធ្វើការ ៨ + send_to_workspace_8: ផ្ញើទៅកន្លែងធ្វើការ ៨ + send_to_workspace_6: ផ្ញើទៅកន្លែងធ្វើការ ៦ + switch_workspace_1: ប្តូរទៅកន្លែងធ្វើការ 1 + switch_workspace_9: ប្តូរទៅកន្លែងធ្វើការ 9 + switch_workspace_6: ប្តូរទៅកន្លែងធ្វើការ 6 + move_to_workspace_9: ផ្លាស់ទីទៅកន្លែងធ្វើការ ៩ + move_to_workspace_1: ផ្លាស់ទីទៅកន្លែងធ្វើការ 1 + switch_workspace_7: ប្តូរទៅកន្លែងធ្វើការ 7 + focus_bottom: ផ្ដោតបាត + enable_tooltip: បិទប្រសិនបើអ្នកនឹងអនុវត្តផ្លូវកាត់ផ្ទាល់ខ្លួនរបស់អ្នកដោយប្រើ Seelen Core Api + enable: បើកផ្លូវកាត់រួមបញ្ចូលគ្នា (ahk) +cancel: បោះបង់ +inProgress: កំពុង​ដំណើរការ... +delete: លុប +loading: កំពុង​ផ្ទុក... +save: រក្សាទុក +quit: ឈប់ +open: បើក diff --git a/src/apps/settings/i18n/translations/ko.yml b/src/apps/settings/i18n/translations/ko.yml index d6521eae..318abe3e 100644 --- a/src/apps/settings/i18n/translations/ko.yml +++ b/src/apps/settings/i18n/translations/ko.yml @@ -1,190 +1,190 @@ -loading: 로딩 중... -inProgress: 진행 중... -cancel: 취소 -save: 저장 -quit: 종료 -open: 열기 -delete: 삭제 -sides: - left: 왼쪽 - right: 오른쪽 - top: 위 - bottom: 아래 -header: - labels: - general: 일반 - seelen_bar: 화려한 툴바 - seelen_wm: 윈도우 매니저 - seelen_weg: 독/작업 표시줄 - monitors: 모니터 - specific_apps: 특정 앱 - shortcuts: 단축키 - developer: 개발자 - info: 정보 -start: - title: 환영합니다! - message: >- - Seelen UI에 오신 것을 환영합니다. Windows 11 경험을 향상시키기 위해 타일링 윈도우 매니저가 포함된 궁극의 데스크탑 - 환경입니다! 직관적인 인터페이스와 고급 기능을 통해 효율성과 멀티태스킹의 새로운 시대를 탐험해 보세요. - message_accent: 스타일로 생산성을 최적화하세요! -general: - startup: 시작 시 실행하시겠습니까? - language: 언어 - theme: - label: 테마 정보 - placeholder: 테마 선택 - author: 작성자 - description: 설명 - add: 테마 추가 - added: 테마가 이미 추가됨 - enabled: 활성화된 테마 - tags: 태그 - available: 사용 가능 - selected: 선택된 - icon_pack: - label: 아이콘 팩 - accent_color: 악센트 색상 -toolbar: - enable: 화려한 툴바 활성화 - placeholder: - select: 툴바 구조 - author: 작성자 - description: 설명 - height: 높이 -wm: - enable: 윈도우 매니저 활성화 - disabled_windows10: 윈도우 매니저는 Windows 10에서 사용할 수 없습니다. - layout: 레이아웃 - author: 작성자 - description: 설명 - space_between_containers: 컨테이너 간 간격 - workspace_padding: 작업 공간 패딩 - workspace_offset: 작업 공간 오프셋 (여백) - resize_delta: 크기 조정 델타 (%) - border: - enable: 창 테두리 활성화 - width: 테두리 너비 - offset: 테두리 오프셋 -weg: - label: 독/작업 표시줄 - enable: 독/작업 표시줄 활성화 - width: 너비 - auto_hide: 자동 숨기기 - dock_side: 독 측면 - padding: 패딩 - margin: 여백 - gap: 간격 - items: - label: 항목 - size: 항목 크기 - zoom_size: 확대된 크기 (테마에 사용됨) - gap: 항목 간 간격 - visible_separators: 보이는 구분선 -devtools: - enable: 개발자 도구 활성화 - app_folders: 앱 폴더 - install_folder: 설치 폴더 - data_folder: 데이터 폴더 - settings_file: 설정 파일 - custom_config_file: 사용자 정의 구성 파일 로드 - load: 로드 -apps_configurations: - import: 가져오기 - export: 내보내기 - delete: 삭제 - swap: 교환 - new: 새로 만들기 - bundled_title: Seelen과 함께 제공되는 앱 구성 - bundled_msg: >- - 이러한 번들 구성은 편집할 수 없으며 맞춤화 없이 최상의 경험을 제공하도록 설계되었습니다. 가장 일반적인 응용 프로그램을 자동으로 - 구성합니다. - confirm_delete_title: 삭제 확인 - confirm_delete: 이 구성을 삭제하시겠습니까? - search: 검색 - app: - name: 이름 - category: 카테고리 - category_placeholder: 없음 - bindings: 바인딩 (두 옵션 모두 필요) - monitor: 모니터 - monitor_placeholder: 없음 - workspace: 작업 공간 - workspace_placeholder: 없음 - title_edit: '{{name}} 편집 중' - title_create: '{{name}} 생성 중' - title_readonly: '{{name}} 보기' - ok_edit: 업데이트 - ok_create: 생성 - ok_readonly: 새로 편집 - options_label: 추가 옵션 - options: - float: 부유 - unmanage: 관리 안 함 - force: 강제 관리 - pinned: 고정됨 - identifier: - remove: 블록 삭제 - id: 식별자 - kind: 식별 기준 - matching_strategy: 매칭 전략 - negation: 매칭 부정 - and: 그리고 - or: 또는 - add_block: 블록 추가 -extras: - version: 버전 - links: 공식 링크 - github: 깃허브 - discord: 디스코드 - relaunch: 다시 시작 - exit: 종료/나가기 -shortcuts: - enable: 통합 단축키 (ahk) 활성화 - enable_tooltip: Seelen Core API를 사용하여 자체 단축키를 구현할 경우 비활성화하세요 - labels: - reserve_top: 상단 예약 - reserve_bottom: 하단 예약 - reserve_left: 왼쪽 예약 - reserve_right: 오른쪽 예약 - reserve_float: 부유 예약 - reserve_stack: 스택 예약 - focus_top: 상단 집중 - focus_bottom: 하단 집중 - focus_left: 왼쪽 집중 - focus_right: 오른쪽 집중 - focus_latest: 최신 집중 - increase_width: 너비 증가 - decrease_width: 너비 감소 - increase_height: 높이 증가 - decrease_height: 높이 감소 - restore_sizes: 크기 복원 - switch_workspace_0: 작업 공간 0으로 전환 - switch_workspace_1: 작업 공간 1으로 전환 - switch_workspace_2: 작업 공간 2로 전환 - switch_workspace_3: 작업 공간 3으로 전환 - switch_workspace_4: 작업 공간 4로 전환 - switch_workspace_5: 작업 공간 5로 전환 - switch_workspace_6: 작업 공간 6으로 전환 - switch_workspace_7: 작업 공간 7로 전환 - switch_workspace_8: 작업 공간 8로 전환 - switch_workspace_9: 작업 공간 9로 전환 - move_to_workspace_0: 작업 공간 0으로 이동 - move_to_workspace_1: 작업 공간 1으로 이동 - move_to_workspace_2: 작업 공간 2로 이동 - move_to_workspace_3: 작업 공간 3으로 이동 - move_to_workspace_4: 작업 공간 4로 이동 - move_to_workspace_5: 작업 공간 5로 이동 - move_to_workspace_6: 작업 공간 6으로 이동 - move_to_workspace_7: 작업 공간 7로 이동 - move_to_workspace_8: 작업 공간 8으로 이동 - move_to_workspace_9: 작업 공간 9으로 이동 - send_to_workspace_0: 작업 공간 0으로 보내기 - send_to_workspace_1: 작업 공간 1으로 보내기 - send_to_workspace_2: 작업 공간 2로 보내기 - send_to_workspace_3: 작업 공간 3으로 보내기 - send_to_workspace_4: 작업 공간 4로 보내기 - send_to_workspace_5: 작업 공간 5로 보내기 - send_to_workspace_6: 작업 공간 6으로 보내기 - send_to_workspace_7: 작업 공간 7으로 보내기 - send_to_workspace_8: 작업 공간 8으로 보내기 - send_to_workspace_9: 작업 공간 9으로 보내기 +loading: 로딩 중... +inProgress: 진행 중... +cancel: 취소 +save: 저장 +quit: 종료 +open: 열기 +delete: 삭제 +sides: + left: 왼쪽 + right: 오른쪽 + top: 위 + bottom: 아래 +header: + labels: + general: 일반 + seelen_bar: 화려한 툴바 + seelen_wm: 윈도우 매니저 + seelen_weg: 독/작업 표시줄 + monitors: 모니터 + specific_apps: 특정 앱 + shortcuts: 단축키 + developer: 개발자 + info: 정보 +start: + title: 환영합니다! + message: >- + Seelen UI에 오신 것을 환영합니다. Windows 11 경험을 향상시키기 위해 타일링 윈도우 매니저가 포함된 궁극의 데스크탑 + 환경입니다! 직관적인 인터페이스와 고급 기능을 통해 효율성과 멀티태스킹의 새로운 시대를 탐험해 보세요. + message_accent: 스타일로 생산성을 최적화하세요! +general: + startup: 시작 시 실행하시겠습니까? + language: 언어 + theme: + label: 테마 정보 + placeholder: 테마 선택 + author: 작성자 + description: 설명 + add: 테마 추가 + added: 테마가 이미 추가됨 + enabled: 활성화된 테마 + tags: 태그 + available: 사용 가능 + selected: 선택된 + icon_pack: + label: 아이콘 팩 + accent_color: 악센트 색상 +toolbar: + enable: 화려한 툴바 활성화 + placeholder: + select: 툴바 구조 + author: 작성자 + description: 설명 + height: 높이 +wm: + enable: 윈도우 매니저 활성화 + disabled_windows10: 윈도우 매니저는 Windows 10에서 사용할 수 없습니다. + layout: 레이아웃 + author: 작성자 + description: 설명 + space_between_containers: 컨테이너 간 간격 + workspace_padding: 작업 공간 패딩 + workspace_offset: 작업 공간 오프셋 (여백) + resize_delta: 크기 조정 델타 (%) + border: + enable: 창 테두리 활성화 + width: 테두리 너비 + offset: 테두리 오프셋 +weg: + label: 독/작업 표시줄 + enable: 독/작업 표시줄 활성화 + width: 너비 + auto_hide: 자동 숨기기 + dock_side: 독 측면 + padding: 패딩 + margin: 여백 + gap: 간격 + items: + label: 항목 + size: 항목 크기 + zoom_size: 확대된 크기 (테마에 사용됨) + gap: 항목 간 간격 + visible_separators: 보이는 구분선 +devtools: + enable: 개발자 도구 활성화 + app_folders: 앱 폴더 + install_folder: 설치 폴더 + data_folder: 데이터 폴더 + settings_file: 설정 파일 + custom_config_file: 사용자 정의 구성 파일 로드 + load: 로드 +apps_configurations: + import: 가져오기 + export: 내보내기 + delete: 삭제 + swap: 교환 + new: 새로 만들기 + bundled_title: Seelen과 함께 제공되는 앱 구성 + bundled_msg: >- + 이러한 번들 구성은 편집할 수 없으며 맞춤화 없이 최상의 경험을 제공하도록 설계되었습니다. 가장 일반적인 응용 프로그램을 자동으로 + 구성합니다. + confirm_delete_title: 삭제 확인 + confirm_delete: 이 구성을 삭제하시겠습니까? + search: 검색 + app: + name: 이름 + category: 카테고리 + category_placeholder: 없음 + bindings: 바인딩 (두 옵션 모두 필요) + monitor: 모니터 + monitor_placeholder: 없음 + workspace: 작업 공간 + workspace_placeholder: 없음 + title_edit: '{{name}} 편집 중' + title_create: '{{name}} 생성 중' + title_readonly: '{{name}} 보기' + ok_edit: 업데이트 + ok_create: 생성 + ok_readonly: 새로 편집 + options_label: 추가 옵션 + options: + float: 부유 + unmanage: 관리 안 함 + force: 강제 관리 + pinned: 고정됨 + identifier: + remove: 블록 삭제 + id: 식별자 + kind: 식별 기준 + matching_strategy: 매칭 전략 + negation: 매칭 부정 + and: 그리고 + or: 또는 + add_block: 블록 추가 +extras: + version: 버전 + links: 공식 링크 + github: 깃허브 + discord: 디스코드 + relaunch: 다시 시작 + exit: 종료/나가기 +shortcuts: + enable: 통합 단축키 (ahk) 활성화 + enable_tooltip: Seelen Core API를 사용하여 자체 단축키를 구현할 경우 비활성화하세요 + labels: + reserve_top: 상단 예약 + reserve_bottom: 하단 예약 + reserve_left: 왼쪽 예약 + reserve_right: 오른쪽 예약 + reserve_float: 부유 예약 + reserve_stack: 스택 예약 + focus_top: 상단 집중 + focus_bottom: 하단 집중 + focus_left: 왼쪽 집중 + focus_right: 오른쪽 집중 + focus_latest: 최신 집중 + increase_width: 너비 증가 + decrease_width: 너비 감소 + increase_height: 높이 증가 + decrease_height: 높이 감소 + restore_sizes: 크기 복원 + switch_workspace_0: 작업 공간 0으로 전환 + switch_workspace_1: 작업 공간 1으로 전환 + switch_workspace_2: 작업 공간 2로 전환 + switch_workspace_3: 작업 공간 3으로 전환 + switch_workspace_4: 작업 공간 4로 전환 + switch_workspace_5: 작업 공간 5로 전환 + switch_workspace_6: 작업 공간 6으로 전환 + switch_workspace_7: 작업 공간 7로 전환 + switch_workspace_8: 작업 공간 8로 전환 + switch_workspace_9: 작업 공간 9로 전환 + move_to_workspace_0: 작업 공간 0으로 이동 + move_to_workspace_1: 작업 공간 1으로 이동 + move_to_workspace_2: 작업 공간 2로 이동 + move_to_workspace_3: 작업 공간 3으로 이동 + move_to_workspace_4: 작업 공간 4로 이동 + move_to_workspace_5: 작업 공간 5로 이동 + move_to_workspace_6: 작업 공간 6으로 이동 + move_to_workspace_7: 작업 공간 7로 이동 + move_to_workspace_8: 작업 공간 8으로 이동 + move_to_workspace_9: 작업 공간 9으로 이동 + send_to_workspace_0: 작업 공간 0으로 보내기 + send_to_workspace_1: 작업 공간 1으로 보내기 + send_to_workspace_2: 작업 공간 2로 보내기 + send_to_workspace_3: 작업 공간 3으로 보내기 + send_to_workspace_4: 작업 공간 4로 보내기 + send_to_workspace_5: 작업 공간 5로 보내기 + send_to_workspace_6: 작업 공간 6으로 보내기 + send_to_workspace_7: 작업 공간 7으로 보내기 + send_to_workspace_8: 작업 공간 8으로 보내기 + send_to_workspace_9: 작업 공간 9으로 보내기 diff --git a/src/apps/settings/i18n/translations/ku.yml b/src/apps/settings/i18n/translations/ku.yml index bf43aebf..7174e85f 100644 --- a/src/apps/settings/i18n/translations/ku.yml +++ b/src/apps/settings/i18n/translations/ku.yml @@ -1,194 +1,194 @@ -sides: - left: Çep - bottom: Erd - top: Kop - right: Rast -header: - labels: - info: Agahî - general: Giştî - seelen_wm: Rêvebirê pencereyê - seelen_weg: Dock / Taskbar - developer: Pêşvebirin - seelen_bar: Fancy Toolbar - shortcuts: Kurtefîlm - specific_apps: Serlêdanên taybetî - monitors: Çavdêr -start: - title: Bi xêr hatî! - message_accent: Hilberîna xwe bi şêwazê xweştir bikin! - message: >- - Welcome to Seelen Ui, hawîrdora desktopê ya paşîn a bi navgînek pencereya bi - navgîniya Windows-ê re ku ezmûna Windows 11 zêde bike! Li ser serdemek nû û - pirrjimar bi navbeynkariya intuitive û taybetmendiyên pêşkeftî vekolînin. -general: - theme: - description: Terîf - author: Nivîskar - label: Agahdariya Mijarê - add: Mijar zêde bikin - added: Mijar berê lê zêde kir - tags: Tags - placeholder: Mijar hilbijêrin - enabled: Mijarên çalak kirin - available: Berdeste - selected: Hilbijartin - language: Ziman - startup: Li ser destpêka bisekinin? - icon_pack: - label: Packon icon - accent_color: Rengê Accent -toolbar: - placeholder: - author: Nivîskar - description: Terîf - select: Struktura Toolbar - height: Bilindî - enable: Vebijêrkek Fancy Vebijêrin -wm: - border: - width: Berfirehiya sînor - offset: Berdewamiya sînor - enable: Sînorê pencereyê çalak bike - description: Terîf - author: Nivîskar - layout: Rêz - disabled_windows10: Rêvebirê pencereyê ji bo Windows 10-ê nabe. - workspace_offset: Karûbarên Workspan (Margins) - space_between_containers: Cîhê di navbera konteyneran de - enable: Gerînendeyê Windeyê çalak bike - workspace_padding: Karên xebitandinê - resize_delta: Delta Resize (%) -weg: - items: - size: Mezinahiya tiştê - label: Hevokên - zoom_size: Mezinahiya zoomed (ji bo mijaran tê bikar anîn) - visible_separators: Dabeşên Visible - gap: Cîh di navbera tiştan de - gap: Qelîştok - width: Berî - enable: Dock / Taskbar çalak bikin - margin: Radihêj - dock_side: Dock aliyê - auto_hide: Auto Hide - label: Dock / Taskbar - padding: Padding -devtools: - load: Dawetkirin - app_folders: Pelên App - settings_file: Pelê Mîhengan - data_folder: Peldanka daneyê - custom_config_file: Pelê Config-ê ya xwerû barkirin - enable: Amûrên Pêşdebir çalak bikin - install_folder: Peldanka sazkirinê -apps_configurations: - app: - options: - float: Avbazîn - force: Hêza birêvebirin - pinned: Pinned - unmanage: Nedar - monitor: Lê gûhdarkirin - monitor_placeholder: Netû - category_placeholder: Netû - category: Liq - name: Nav - title_create: Afirandina {NAME} - ok_edit: UDÛDEPATE - title_readonly: Dîtin {{NAVEN} - bindings: Binding (Nîşe her du vebijark hewce ne) - workspace: Workspace - options_label: Vebijarkên zêde - ok_create: Xûliqandin - workspace_placeholder: Netû - ok_readonly: Wekî nû biguherînin - title_edit: Editting {name}} - identifier: - and: Û - or: AN - remove: Blokê jêbirin - kind: Ji hêla nas kirin - add_block: Blok zêde bikin - matching_strategy: Stratejiya hevberdanê - id: Nasî - negation: Lihevhatina negotî - export: Eksport - new: Nşh - import: Anîn - search: Gerr - bundled_msg: >- - Van konfigurasyonên bundled ne edîtor in û têne çêkirin ku ji we re ezmûna - çêtirîn bêyî adetbûnê peyda bikin. Ew bixweber ji bo we serlêdanên herî - gelemperî mîheng dikin. - confirm_delete_title: DELETE piştrast bikin - delete: Lûleêkirin - bundled_title: App Confic bi seelen - confirm_delete: Ma hûn guman dikin ku hûn dixwazin vê konfigurasyonê / s jêbirin? - swap: Sofet -extras: - version: Awa - links: Girêdanên fermî - relaunch: Berxwedêr - github: Github - exit: Qut / derketin - discord: Nakemala -shortcuts: - labels: - focus_right: Focus rast - switch_workspace_9: Switch to Workspace 9 - decrease_width: Width kêm bikin - focus_top: Focus Top - increase_height: Bilindbûnê zêde bikin - send_to_workspace_4: Ji Workspace 4 re bişînin - decrease_height: Dirêjbûn - switch_workspace_5: Switch to Workspace 5 - reserve_stack: Stack Reserve - focus_bottom: Focus Bottom - move_to_workspace_1: Move to Workspace 1 - move_to_workspace_9: Move to Workspace 9 - increase_width: Berfireh zêde bikin - switch_workspace_2: Switch to Workspace 2 - reserve_top: Top hilînin - send_to_workspace_1: Ji bo Workspace 1 bişînin - switch_workspace_6: Switch to Workspace 6 - restore_sizes: Mezinan sererast bikin - reserve_right: Rasterast rast bikin - switch_workspace_0: Switch to Workspace 0 - switch_workspace_7: Switch to Workspace 7 - reserve_left: Rezertê çepê - focus_left: Focus çep - send_to_workspace_2: Ji Workspace 2 re bişînin - switch_workspace_1: Switch to Workspace 1 - reserve_float: Float rezervan - move_to_workspace_0: Move to Workspace 0 - send_to_workspace_0: Ji Workspace 0 re bişînin - switch_workspace_4: Vegere Workspace 4 - move_to_workspace_5: Move to Workspace 5 - send_to_workspace_5: Ji Workspace 5 re bişînin - send_to_workspace_8: Ji bo Workspace 8 bişînin - send_to_workspace_9: Ji Workspace 9 re bişînin - send_to_workspace_3: Ji bo Workspace 3 bişînin - move_to_workspace_7: Move to Workspace 7 - move_to_workspace_3: Move to Workspace 3 - switch_workspace_3: Switch to Workspace 3 - move_to_workspace_8: Move to Workspace 8 - send_to_workspace_6: Ji bo Workspace 6 bişînin - focus_latest: FOCUS Latest - move_to_workspace_4: Move to Workspace 4 - send_to_workspace_7: Ji bo Workspace 7 bişînin - switch_workspace_8: Switch to Workspace 8 - move_to_workspace_2: Move to Workspace 2 - reserve_bottom: Binê binê - move_to_workspace_6: Move to Workspace 6 - enable: Kurtefîlmên entegre (AHK) çalak bikin - enable_tooltip: >- - Heke hûn ê kurteyên xwe bicîh bînin bi karanîna API ya Seelen Core bicîh - bikin -cancel: Bişûndekirin -inProgress: Ez teslîm nabim... -quit: Devjêberdan -open: Vekirî -save: Rizgarkirin -delete: Lûleêkirin -loading: Loading ... +sides: + left: Çep + bottom: Erd + top: Kop + right: Rast +header: + labels: + info: Agahî + general: Giştî + seelen_wm: Rêvebirê pencereyê + seelen_weg: Dock / Taskbar + developer: Pêşvebirin + seelen_bar: Fancy Toolbar + shortcuts: Kurtefîlm + specific_apps: Serlêdanên taybetî + monitors: Çavdêr +start: + title: Bi xêr hatî! + message_accent: Hilberîna xwe bi şêwazê xweştir bikin! + message: >- + Welcome to Seelen Ui, hawîrdora desktopê ya paşîn a bi navgînek pencereya bi + navgîniya Windows-ê re ku ezmûna Windows 11 zêde bike! Li ser serdemek nû û + pirrjimar bi navbeynkariya intuitive û taybetmendiyên pêşkeftî vekolînin. +general: + theme: + description: Terîf + author: Nivîskar + label: Agahdariya Mijarê + add: Mijar zêde bikin + added: Mijar berê lê zêde kir + tags: Tags + placeholder: Mijar hilbijêrin + enabled: Mijarên çalak kirin + available: Berdeste + selected: Hilbijartin + language: Ziman + startup: Li ser destpêka bisekinin? + icon_pack: + label: Packon icon + accent_color: Rengê Accent +toolbar: + placeholder: + author: Nivîskar + description: Terîf + select: Struktura Toolbar + height: Bilindî + enable: Vebijêrkek Fancy Vebijêrin +wm: + border: + width: Berfirehiya sînor + offset: Berdewamiya sînor + enable: Sînorê pencereyê çalak bike + description: Terîf + author: Nivîskar + layout: Rêz + disabled_windows10: Rêvebirê pencereyê ji bo Windows 10-ê nabe. + workspace_offset: Karûbarên Workspan (Margins) + space_between_containers: Cîhê di navbera konteyneran de + enable: Gerînendeyê Windeyê çalak bike + workspace_padding: Karên xebitandinê + resize_delta: Delta Resize (%) +weg: + items: + size: Mezinahiya tiştê + label: Hevokên + zoom_size: Mezinahiya zoomed (ji bo mijaran tê bikar anîn) + visible_separators: Dabeşên Visible + gap: Cîh di navbera tiştan de + gap: Qelîştok + width: Berî + enable: Dock / Taskbar çalak bikin + margin: Radihêj + dock_side: Dock aliyê + auto_hide: Auto Hide + label: Dock / Taskbar + padding: Padding +devtools: + load: Dawetkirin + app_folders: Pelên App + settings_file: Pelê Mîhengan + data_folder: Peldanka daneyê + custom_config_file: Pelê Config-ê ya xwerû barkirin + enable: Amûrên Pêşdebir çalak bikin + install_folder: Peldanka sazkirinê +apps_configurations: + app: + options: + float: Avbazîn + force: Hêza birêvebirin + pinned: Pinned + unmanage: Nedar + monitor: Lê gûhdarkirin + monitor_placeholder: Netû + category_placeholder: Netû + category: Liq + name: Nav + title_create: Afirandina {NAME} + ok_edit: UDÛDEPATE + title_readonly: Dîtin {{NAVEN} + bindings: Binding (Nîşe her du vebijark hewce ne) + workspace: Workspace + options_label: Vebijarkên zêde + ok_create: Xûliqandin + workspace_placeholder: Netû + ok_readonly: Wekî nû biguherînin + title_edit: Editting {name}} + identifier: + and: Û + or: AN + remove: Blokê jêbirin + kind: Ji hêla nas kirin + add_block: Blok zêde bikin + matching_strategy: Stratejiya hevberdanê + id: Nasî + negation: Lihevhatina negotî + export: Eksport + new: Nşh + import: Anîn + search: Gerr + bundled_msg: >- + Van konfigurasyonên bundled ne edîtor in û têne çêkirin ku ji we re ezmûna + çêtirîn bêyî adetbûnê peyda bikin. Ew bixweber ji bo we serlêdanên herî + gelemperî mîheng dikin. + confirm_delete_title: DELETE piştrast bikin + delete: Lûleêkirin + bundled_title: App Confic bi seelen + confirm_delete: Ma hûn guman dikin ku hûn dixwazin vê konfigurasyonê / s jêbirin? + swap: Sofet +extras: + version: Awa + links: Girêdanên fermî + relaunch: Berxwedêr + github: Github + exit: Qut / derketin + discord: Nakemala +shortcuts: + labels: + focus_right: Focus rast + switch_workspace_9: Switch to Workspace 9 + decrease_width: Width kêm bikin + focus_top: Focus Top + increase_height: Bilindbûnê zêde bikin + send_to_workspace_4: Ji Workspace 4 re bişînin + decrease_height: Dirêjbûn + switch_workspace_5: Switch to Workspace 5 + reserve_stack: Stack Reserve + focus_bottom: Focus Bottom + move_to_workspace_1: Move to Workspace 1 + move_to_workspace_9: Move to Workspace 9 + increase_width: Berfireh zêde bikin + switch_workspace_2: Switch to Workspace 2 + reserve_top: Top hilînin + send_to_workspace_1: Ji bo Workspace 1 bişînin + switch_workspace_6: Switch to Workspace 6 + restore_sizes: Mezinan sererast bikin + reserve_right: Rasterast rast bikin + switch_workspace_0: Switch to Workspace 0 + switch_workspace_7: Switch to Workspace 7 + reserve_left: Rezertê çepê + focus_left: Focus çep + send_to_workspace_2: Ji Workspace 2 re bişînin + switch_workspace_1: Switch to Workspace 1 + reserve_float: Float rezervan + move_to_workspace_0: Move to Workspace 0 + send_to_workspace_0: Ji Workspace 0 re bişînin + switch_workspace_4: Vegere Workspace 4 + move_to_workspace_5: Move to Workspace 5 + send_to_workspace_5: Ji Workspace 5 re bişînin + send_to_workspace_8: Ji bo Workspace 8 bişînin + send_to_workspace_9: Ji Workspace 9 re bişînin + send_to_workspace_3: Ji bo Workspace 3 bişînin + move_to_workspace_7: Move to Workspace 7 + move_to_workspace_3: Move to Workspace 3 + switch_workspace_3: Switch to Workspace 3 + move_to_workspace_8: Move to Workspace 8 + send_to_workspace_6: Ji bo Workspace 6 bişînin + focus_latest: FOCUS Latest + move_to_workspace_4: Move to Workspace 4 + send_to_workspace_7: Ji bo Workspace 7 bişînin + switch_workspace_8: Switch to Workspace 8 + move_to_workspace_2: Move to Workspace 2 + reserve_bottom: Binê binê + move_to_workspace_6: Move to Workspace 6 + enable: Kurtefîlmên entegre (AHK) çalak bikin + enable_tooltip: >- + Heke hûn ê kurteyên xwe bicîh bînin bi karanîna API ya Seelen Core bicîh + bikin +cancel: Bişûndekirin +inProgress: Ez teslîm nabim... +quit: Devjêberdan +open: Vekirî +save: Rizgarkirin +delete: Lûleêkirin +loading: Loading ... diff --git a/src/apps/settings/i18n/translations/lb.yml b/src/apps/settings/i18n/translations/lb.yml index 598345ed..52b862a7 100644 --- a/src/apps/settings/i18n/translations/lb.yml +++ b/src/apps/settings/i18n/translations/lb.yml @@ -1,193 +1,193 @@ -sides: - right: Riets - left: Lénks - top: Uewen - bottom: Siwenn -header: - labels: - seelen_bar: Fantastesch Toolbar - monitors: Iwwerschwannegkeeten - developer: Entwéckler - seelen_wm: Fënter Manager - specific_apps: Spezifesch Apps - general: Generol - info: Informatioun - shortcuts: Ofkierpsen - seelen_weg: Dock / Taskbar -start: - title: Wëllkomm! - message_accent: Optimiséiert Är Produktivitéit mam Stil! - message: >- - Wëllkomm fir ze gesinn Ui, den ultimativen Desktop Ëmfeld mat engem agebaute - Fournisseur Manager fir Är Windows 11 Erfarung ze verbesseren! Entdeckt eng - nei Ära vun Effizienz a Multits mat eisen intuitiven Interface a - fortgeschratgeschen Features. -general: - theme: - add: Füügt Thema - label: Thema Informatioun - added: Thema scho bäigefüügt - tags: Tasmmenzwierk - description: Broessdatsch - author: Auteur - enabled: Aktivéiert Themen - placeholder: Wielt Thema - available: Liwwerungen - selected: Allgemeng - startup: Run op Startup? - language: Sprooche - icon_pack: - label: ICON Tass - accent_color: Akzenter Faarf -toolbar: - placeholder: - select: Toolbar Struktur - author: Auteur - description: Broessdatsch - enable: Aktivéiert Fore Toolbar - height: Héicht -wm: - border: - width: Grenz Breet - enable: Aktivéiert Fenster Grenz - offset: Grenz Offäll - enable: Aktivéiert Fënstere Manager - resize_delta: Resize Delta (%) - disabled_windows10: Den Fenstermanager ass net verfügbar fir Windows 10. - description: Broessdatsch - space_between_containers: Raum tëscht Behälter - author: Auteur - layout: Lueden - workspace_offset: Workspaces Offset (Rand) - workspace_padding: Aarbechtsberäich padding -weg: - items: - size: Telefonsgrouss - zoom_size: Zoomed Gréisst (benotzt fir Themen) - gap: Raum tëscht Artikelen - label: Artikelen - visible_separators: Sechsi seichtbar Seperure - width: Breet - label: Dock / Taskbar - padding: Padding - dock_side: Dock Säit - auto_hide: Automatesch - margin: Den Jean-Margin - gap: Knënn - enable: Aktivéiert Dock / Taskbar -devtools: - app_folders: App Classeure - enable: Aktivéiert Entwéckler Tools - install_folder: Installatioun Dossier - custom_config_file: Luede personaliséiert Konfiguratiounsdatei - data_folder: Etabond Dossier - settings_file: Settytout-Datei - load: Lueden -apps_configurations: - app: - options: - float: Schwammen - pinned: Verbonnen - force: Kraaft managen - unmanage: Unmanage - title_readonly: '{{{Numm}}' - category_placeholder: Keen - name: Numm vum Numm - monitor_placeholder: Keen - ok_readonly: Ännert als nei - workspace_placeholder: Keen - monitor: Bonitor - category: Gemengen - ok_edit: Olaangs - bindings: Bindend (Notiz béid Optiounen sinn erfuerderlech) - workspace: Konschtpas - options_label: Extra Optiounen - title_edit: Ännerung {{Numm}} - title_create: Erstellen {{Numm}} - ok_create: Erreeiert eng kreéieren - identifier: - remove: Läschen Block - matching_strategy: Passende Strategie - kind: Identifizéieren duerch - negation: Negate passend - or: Oder - id: Identifizéierer - and: An an - add_block: Füügt Block - bundled_title: App con conflüchteg mat Seelen - delete: Läschen - confirm_delete_title: Confirméieren Leedung - search: Sichen - export: Export - new: Nei - confirm_delete: Sidd Dir sécher, datt Dir dës Configuratioun / s läscht braucht? - swap: Zort - import: Importéieren - bundled_msg: >- - Dës gebündelt Konfiguratiounen sinn net geännert a sinn entwéckelt fir Iech - déi bescht Erfahrung ouni Personnalisatioun ze ginn. Si konfiguréieren - automatesch déi heefegst Uwendungen fir Iech. -extras: - version: Erëm - links: Offiziell Linken - relaunch: Relatioun - github: Github - exit: Ophalen / erausfannen - discord: Diskord -shortcuts: - labels: - decrease_height: Reduzéiert Héicht - reserve_right: Reservéiert richteg - switch_workspace_5: Schalt op Aarbechtsberäich 5 - increase_width: Erhéijung vun der Breet - switch_workspace_6: Wiesselt op Workspace 6 - send_to_workspace_0: Schéckt e Aarbechtsberäich 0 - send_to_workspace_1: Schéckt op Aarbechtsberäich 1 - switch_workspace_7: Wiesselt op Aarbechtsberäich 7 - reserve_stack: Reserve Stack - move_to_workspace_4: Gitt op Workspace 4 - switch_workspace_9: Wiesselt op Workspace 9 - switch_workspace_3: Wiesselt op Workspace 3 - switch_workspace_8: Schalt op Workspace 8 - switch_workspace_0: Schalt op Aarbechtsberäich 0 - focus_latest: Fokusséieren dat lescht - focus_top: Fokusséieren Top - move_to_workspace_1: Gitt op Aarbechtsberäich 1 - reserve_left: Reserve lénks - decrease_width: Reduzéiert Breet - increase_height: Erhéijen Héicht - focus_bottom: Fokus ënnen - reserve_bottom: Reservéiert ënnen - focus_right: Fokusséiert richteg - restore_sizes: Restauréiert Gréissten - focus_left: Fokusséiert lénks - move_to_workspace_6: Plënnert op Workspace 6 - send_to_workspace_4: Schéckt op Aarbechtsberäich 4 - switch_workspace_2: Schalt op Aarbechtsberäich 2 - move_to_workspace_8: Plënnert op Workspace 8 - move_to_workspace_2: Plënnert op Aarbechtsberäich 2 - send_to_workspace_3: Schéckt op Aarbechtsberäich 3 - switch_workspace_1: Schalt op Aarbechtsberäich 1 - move_to_workspace_0: Plënnert op Workspace 0 - move_to_workspace_9: Plënnert op Workspace 9 - move_to_workspace_7: Plënnert op Workspace 7 - send_to_workspace_5: Schéckt op Aarbechtsberäich 5 - move_to_workspace_5: Plënnert op Aarbechtsberäich 5 - send_to_workspace_8: Schéckt e Aarbechtsberäich 8 - send_to_workspace_9: Schéckt an Aarbechtsbereedung 9 - send_to_workspace_7: Schéckt op Aarbechtsberäich 7 - switch_workspace_4: Schalt op Workspace 4 - move_to_workspace_3: Plënnert op Aarbechtsberäich 3 - send_to_workspace_6: Schéckt e Aarbechtsberäich 6 - reserve_top: Reserve Top - send_to_workspace_2: Schéckt op Aarbechtsberäich 2 - reserve_float: Reservéiert Float - enable: Aktivéiert integréiert Ofkiirzungen (AHK) - enable_tooltip: Desaktivéiert wann Dir Är eege Ofkiirzungen ëmsetzen mat dem Selen Core API -inProgress: A Beaarbechtung... -loading: Lueden ... -open: Ëmen e gratis -delete: Läschen -cancel: Ofbriechen -quit: Ness -save: Spuerwäit +sides: + right: Riets + left: Lénks + top: Uewen + bottom: Siwenn +header: + labels: + seelen_bar: Fantastesch Toolbar + monitors: Iwwerschwannegkeeten + developer: Entwéckler + seelen_wm: Fënter Manager + specific_apps: Spezifesch Apps + general: Generol + info: Informatioun + shortcuts: Ofkierpsen + seelen_weg: Dock / Taskbar +start: + title: Wëllkomm! + message_accent: Optimiséiert Är Produktivitéit mam Stil! + message: >- + Wëllkomm fir ze gesinn Ui, den ultimativen Desktop Ëmfeld mat engem agebaute + Fournisseur Manager fir Är Windows 11 Erfarung ze verbesseren! Entdeckt eng + nei Ära vun Effizienz a Multits mat eisen intuitiven Interface a + fortgeschratgeschen Features. +general: + theme: + add: Füügt Thema + label: Thema Informatioun + added: Thema scho bäigefüügt + tags: Tasmmenzwierk + description: Broessdatsch + author: Auteur + enabled: Aktivéiert Themen + placeholder: Wielt Thema + available: Liwwerungen + selected: Allgemeng + startup: Run op Startup? + language: Sprooche + icon_pack: + label: ICON Tass + accent_color: Akzenter Faarf +toolbar: + placeholder: + select: Toolbar Struktur + author: Auteur + description: Broessdatsch + enable: Aktivéiert Fore Toolbar + height: Héicht +wm: + border: + width: Grenz Breet + enable: Aktivéiert Fenster Grenz + offset: Grenz Offäll + enable: Aktivéiert Fënstere Manager + resize_delta: Resize Delta (%) + disabled_windows10: Den Fenstermanager ass net verfügbar fir Windows 10. + description: Broessdatsch + space_between_containers: Raum tëscht Behälter + author: Auteur + layout: Lueden + workspace_offset: Workspaces Offset (Rand) + workspace_padding: Aarbechtsberäich padding +weg: + items: + size: Telefonsgrouss + zoom_size: Zoomed Gréisst (benotzt fir Themen) + gap: Raum tëscht Artikelen + label: Artikelen + visible_separators: Sechsi seichtbar Seperure + width: Breet + label: Dock / Taskbar + padding: Padding + dock_side: Dock Säit + auto_hide: Automatesch + margin: Den Jean-Margin + gap: Knënn + enable: Aktivéiert Dock / Taskbar +devtools: + app_folders: App Classeure + enable: Aktivéiert Entwéckler Tools + install_folder: Installatioun Dossier + custom_config_file: Luede personaliséiert Konfiguratiounsdatei + data_folder: Etabond Dossier + settings_file: Settytout-Datei + load: Lueden +apps_configurations: + app: + options: + float: Schwammen + pinned: Verbonnen + force: Kraaft managen + unmanage: Unmanage + title_readonly: '{{{Numm}}' + category_placeholder: Keen + name: Numm vum Numm + monitor_placeholder: Keen + ok_readonly: Ännert als nei + workspace_placeholder: Keen + monitor: Bonitor + category: Gemengen + ok_edit: Olaangs + bindings: Bindend (Notiz béid Optiounen sinn erfuerderlech) + workspace: Konschtpas + options_label: Extra Optiounen + title_edit: Ännerung {{Numm}} + title_create: Erstellen {{Numm}} + ok_create: Erreeiert eng kreéieren + identifier: + remove: Läschen Block + matching_strategy: Passende Strategie + kind: Identifizéieren duerch + negation: Negate passend + or: Oder + id: Identifizéierer + and: An an + add_block: Füügt Block + bundled_title: App con conflüchteg mat Seelen + delete: Läschen + confirm_delete_title: Confirméieren Leedung + search: Sichen + export: Export + new: Nei + confirm_delete: Sidd Dir sécher, datt Dir dës Configuratioun / s läscht braucht? + swap: Zort + import: Importéieren + bundled_msg: >- + Dës gebündelt Konfiguratiounen sinn net geännert a sinn entwéckelt fir Iech + déi bescht Erfahrung ouni Personnalisatioun ze ginn. Si konfiguréieren + automatesch déi heefegst Uwendungen fir Iech. +extras: + version: Erëm + links: Offiziell Linken + relaunch: Relatioun + github: Github + exit: Ophalen / erausfannen + discord: Diskord +shortcuts: + labels: + decrease_height: Reduzéiert Héicht + reserve_right: Reservéiert richteg + switch_workspace_5: Schalt op Aarbechtsberäich 5 + increase_width: Erhéijung vun der Breet + switch_workspace_6: Wiesselt op Workspace 6 + send_to_workspace_0: Schéckt e Aarbechtsberäich 0 + send_to_workspace_1: Schéckt op Aarbechtsberäich 1 + switch_workspace_7: Wiesselt op Aarbechtsberäich 7 + reserve_stack: Reserve Stack + move_to_workspace_4: Gitt op Workspace 4 + switch_workspace_9: Wiesselt op Workspace 9 + switch_workspace_3: Wiesselt op Workspace 3 + switch_workspace_8: Schalt op Workspace 8 + switch_workspace_0: Schalt op Aarbechtsberäich 0 + focus_latest: Fokusséieren dat lescht + focus_top: Fokusséieren Top + move_to_workspace_1: Gitt op Aarbechtsberäich 1 + reserve_left: Reserve lénks + decrease_width: Reduzéiert Breet + increase_height: Erhéijen Héicht + focus_bottom: Fokus ënnen + reserve_bottom: Reservéiert ënnen + focus_right: Fokusséiert richteg + restore_sizes: Restauréiert Gréissten + focus_left: Fokusséiert lénks + move_to_workspace_6: Plënnert op Workspace 6 + send_to_workspace_4: Schéckt op Aarbechtsberäich 4 + switch_workspace_2: Schalt op Aarbechtsberäich 2 + move_to_workspace_8: Plënnert op Workspace 8 + move_to_workspace_2: Plënnert op Aarbechtsberäich 2 + send_to_workspace_3: Schéckt op Aarbechtsberäich 3 + switch_workspace_1: Schalt op Aarbechtsberäich 1 + move_to_workspace_0: Plënnert op Workspace 0 + move_to_workspace_9: Plënnert op Workspace 9 + move_to_workspace_7: Plënnert op Workspace 7 + send_to_workspace_5: Schéckt op Aarbechtsberäich 5 + move_to_workspace_5: Plënnert op Aarbechtsberäich 5 + send_to_workspace_8: Schéckt e Aarbechtsberäich 8 + send_to_workspace_9: Schéckt an Aarbechtsbereedung 9 + send_to_workspace_7: Schéckt op Aarbechtsberäich 7 + switch_workspace_4: Schalt op Workspace 4 + move_to_workspace_3: Plënnert op Aarbechtsberäich 3 + send_to_workspace_6: Schéckt e Aarbechtsberäich 6 + reserve_top: Reserve Top + send_to_workspace_2: Schéckt op Aarbechtsberäich 2 + reserve_float: Reservéiert Float + enable: Aktivéiert integréiert Ofkiirzungen (AHK) + enable_tooltip: Desaktivéiert wann Dir Är eege Ofkiirzungen ëmsetzen mat dem Selen Core API +inProgress: A Beaarbechtung... +loading: Lueden ... +open: Ëmen e gratis +delete: Läschen +cancel: Ofbriechen +quit: Ness +save: Spuerwäit diff --git a/src/apps/settings/i18n/translations/lo.yml b/src/apps/settings/i18n/translations/lo.yml index b7e0c157..6739b1cc 100644 --- a/src/apps/settings/i18n/translations/lo.yml +++ b/src/apps/settings/i18n/translations/lo.yml @@ -1,194 +1,194 @@ -sides: - bottom: ລຸ່ມ - top: ເທິງ - right: ສິດ - left: ຊ້າຍ -header: - labels: - general: ທົ່ວໄປ - shortcuts: ທາງລັດ - info: ຂໍ້ມູນ - seelen_weg: Dock/Taskbar - seelen_bar: ແຖບເຄື່ອງມືແຟນຊີ - specific_apps: ແອັບສະເພາະ - seelen_wm: ຜູ້ຈັດການປ່ອງຢ້ຽມ - monitors: ຈໍພາບ - developer: ນັກພັດທະນາ -start: - title: ຍິນດີຕ້ອນຮັບ! - message_accent: ເພີ່ມປະສິດທິພາບການຜະລິດຂອງເຈົ້າດ້ວຍຮູບແບບ! - message: >- - ຍິນ​ດີ​ຕ້ອນ​ຮັບ​ສູ່ Seelen UI, - ສິ່ງ​ແວດ​ລ້ອມ​ເດັສ​ທັອບ​ທີ່​ດີ​ທີ່​ສຸດ​ທີ່​ມີ​ຕົວ​ຈັດ​ການ​ໜ້າ​ຕ່າງ​ກະ​ເບື້ອງ​ທີ່​ປະ​ກອບ​ເຂົ້າ​ເພື່ອ​ເພີ່ມ​ປະ​ສົບ​ການ - Windows 11 ຂອງ​ທ່ານ! ສຳຫຼວດຍຸກໃໝ່ຂອງປະສິດທິພາບ - ແລະການເຮັດວຽກຫຼາຍໜ້າດ້ວຍການໂຕ້ຕອບທີ່ເຂົ້າໃຈງ່າຍ - ແລະຄຸນສົມບັດຂັ້ນສູງຂອງພວກເຮົາ. -general: - theme: - tags: ປ້າຍກຳກັບ - author: ຜູ້ຂຽນ - description: ລາຍລະອຽດ - enabled: ຮູບແບບສີສັນທີ່ເປີດໃຊ້ງານ - label: ຂໍ້ມູນຫົວຂໍ້ - placeholder: ເລືອກຫົວຂໍ້ - added: ເພີ່ມຮູບແບບສີສັນແລ້ວ - add: ເພີ່ມຫົວຂໍ້ - available: ມີໄວ້ - selected: ຄັດເລືອກ - language: ພາສາ - startup: ດໍາເນີນການກ່ຽວກັບການເລີ່ມຕົ້ນ? - icon_pack: - label: icon ຊອງ - accent_color: ສີສໍານຽງ -toolbar: - placeholder: - author: ຜູ້ຂຽນ - description: ລາຍລະອຽດ - select: ໂຄງສ້າງແຖບເຄື່ອງມື - enable: ເປີດໃຊ້ແຖບເຄື່ອງມື Fancy - height: ຄວາມສູງ -wm: - border: - enable: ເປີດໃຊ້ຂອບຂອງປ່ອງຢ້ຽມ - width: ຄວາມກວ້າງຊາຍແດນ - offset: Border Offset - author: ຜູ້ຂຽນ - description: ລາຍລະອຽດ - layout: ແຜນຜັງ - resize_delta: ປັບຂະໜາດ Delta (%) - space_between_containers: ຊ່ອງຫວ່າງລະຫວ່າງບັນຈຸ - enable: ເປີດໃຊ້ Window Manager - workspace_padding: ພື້ນທີ່ເຮັດວຽກ Padding - workspace_offset: ພື້ນທີ່ເຮັດວຽກຊົດເຊີຍ (ຂອບ) - disabled_windows10: Window Manager ບໍ່ສາມາດໃຊ້ໄດ້ສໍາລັບ Windows 10. -weg: - items: - label: ລາຍການ - visible_separators: ຕົວແຍກທີ່ເບິ່ງເຫັນໄດ້ - zoom_size: ຂະຫຍາຍຂະໜາດ (ໃຊ້ສຳລັບຮູບແບບສີສັນ) - gap: ຊ່ອງຫວ່າງລະຫວ່າງລາຍການ - size: ຂະໜາດລາຍການ - auto_hide: ເຊື່ອງອັດຕະໂນມັດ - width: ກວ້າງ - margin: ຂອບ - label: Dock/Taskbar - padding: padding - gap: ຊ່ອງຫວ່າງ - enable: ເປີດໃຊ້ Dock/Taskbar - dock_side: Dock Side -devtools: - custom_config_file: ໂຫຼດໄຟລ໌ການຕັ້ງຄ່າແບບກຳນົດເອງ - enable: ເປີດໃຊ້ເຄື່ອງມືນັກພັດທະນາ - load: ໂຫຼດ - app_folders: ໂຟນເດີ App - settings_file: ໄຟລ໌ການຕັ້ງຄ່າ - install_folder: ໂຟນເດີການຕິດຕັ້ງ - data_folder: ແຟ້ມຂໍ້ມູນ -apps_configurations: - app: - options: - float: ລອຍ - unmanage: ຍົກເລີກການຈັດການ - pinned: ປັກໝຸດ - force: ບັງຄັບໃຫ້ຈັດການ - monitor: ຕິດຕາມກວດກາ - title_create: ການສ້າງ {{name}} - options_label: ທາງເລືອກພິເສດ - monitor_placeholder: ບໍ່ມີ - workspace_placeholder: ບໍ່ມີ - name: ຊື່ - category_placeholder: ບໍ່ມີ - workspace: ພື້ນທີ່ເຮັດວຽກ - ok_edit: ອັບເດດ - category: ປະເພດ - title_readonly: ກຳລັງເບິ່ງ {{name}} - title_edit: ການແກ້ໄຂ {{name}} - ok_readonly: ແກ້ໄຂເປັນໃໝ່ - ok_create: ສ້າງ - bindings: ການຜູກມັດ (ຫມາຍເຫດທັງສອງທາງເລືອກແມ່ນຈໍາເປັນ) - identifier: - and: ແລະ - negation: Negate ການຈັບຄູ່ - add_block: ເພີ່ມ Block - remove: ລຶບ Block - or: ຫຼື - kind: ກໍານົດໂດຍ - matching_strategy: ຍຸດທະສາດການຈັບຄູ່ - id: ຕົວລະບຸ - search: ຊອກຫາ - export: ສົ່ງອອກ - new: ໃຫມ່ - swap: ແລກປ່ຽນ - import: ນໍາເຂົ້າ - delete: ລຶບ - bundled_title: App Config Bundled ກັບ Seelen - confirm_delete_title: ຢືນຢັນການລຶບ - bundled_msg: >- - ການຕັ້ງຄ່າຊຸດເຫຼົ່ານີ້ບໍ່ສາມາດແກ້ໄຂໄດ້ - ແລະຖືກອອກແບບມາເພື່ອໃຫ້ປະສົບການທີ່ດີທີ່ສຸດແກ່ເຈົ້າໂດຍບໍ່ມີການປັບແຕ່ງ. - ພວກເຂົາຕັ້ງຄ່າແອັບພລິເຄຊັນທົ່ວໄປທີ່ສຸດສໍາລັບທ່ານໂດຍອັດຕະໂນມັດ. - confirm_delete: ທ່ານແນ່ໃຈບໍ່ວ່າຕ້ອງການລຶບການຕັ້ງຄ່ານີ້? -extras: - version: ຮຸ່ນ - github: GitHub - discord: ຄວາມຂັດແຍ້ງ - links: ການເຊື່ອມຕໍ່ຢ່າງເປັນທາງການ - relaunch: ເປີດຄືນໃໝ່ - exit: ອອກ/ອອກ -shortcuts: - labels: - send_to_workspace_3: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 3 - send_to_workspace_4: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 4 - restore_sizes: ຟື້ນຟູຂະໜາດ - move_to_workspace_4: ຍ້າຍໄປບ່ອນເຮັດວຽກ 4 - move_to_workspace_2: ຍ້າຍໄປບ່ອນເຮັດວຽກ 2 - send_to_workspace_1: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 1 - reserve_float: ສະຫງວນ Float - send_to_workspace_2: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 2 - send_to_workspace_9: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 9 - move_to_workspace_7: ຍ້າຍໄປບ່ອນເຮັດວຽກ 7 - switch_workspace_0: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 0 - send_to_workspace_5: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 5 - switch_workspace_1: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 1 - switch_workspace_6: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 6 - focus_right: ໂຟກັສຂວາ - focus_left: ໂຟກັສຊ້າຍ - increase_height: ເພີ່ມຄວາມສູງ - focus_latest: Focus ຫຼ້າສຸດ - send_to_workspace_7: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 7 - reserve_left: ຈອງຊ້າຍ - reserve_bottom: ຈອງລຸ່ມ - move_to_workspace_1: ຍ້າຍໄປບ່ອນເຮັດວຽກ 1 - send_to_workspace_0: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 0 - move_to_workspace_5: ຍ້າຍໄປບ່ອນເຮັດວຽກ 5 - switch_workspace_5: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 5 - decrease_height: ຫຼຸດຄວາມສູງ - decrease_width: ຫຼຸດຄວາມກວ້າງ - switch_workspace_9: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 9 - move_to_workspace_8: ຍ້າຍໄປບ່ອນເຮັດວຽກ 8 - send_to_workspace_6: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 6 - move_to_workspace_0: ຍ້າຍໄປບ່ອນເຮັດວຽກ 0 - focus_top: ໂຟກັສເທິງ - increase_width: ເພີ່ມຄວາມກວ້າງ - move_to_workspace_3: ຍ້າຍໄປບ່ອນເຮັດວຽກ 3 - reserve_right: ສະຫງວນສິດ - reserve_stack: ຈອງ stack - reserve_top: ສະຫງວນເທິງ - move_to_workspace_6: ຍ້າຍໄປບ່ອນເຮັດວຽກ 6 - move_to_workspace_9: ຍ້າຍໄປບ່ອນເຮັດວຽກ 9 - switch_workspace_8: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 8 - switch_workspace_7: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 7 - switch_workspace_2: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 2 - switch_workspace_3: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 3 - switch_workspace_4: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 4 - send_to_workspace_8: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 8 - focus_bottom: ໂຟກັສລຸ່ມ - enable_tooltip: ປິດໃຊ້ງານຖ້າທ່ານຈະປະຕິບັດທາງລັດຂອງທ່ານເອງໂດຍໃຊ້ Seelen Core Api - enable: ເປີດໃຊ້ທາງລັດປະສົມປະສານ (ahk) -cancel: ຍົກເລີກ -loading: ກຳລັງໂຫລດ... -delete: ລຶບ -quit: ເຊົາ -save: ບັນທຶກ -inProgress: ຢູ່ໃນຄວາມຄືບໜ້າ... -open: ເປີດ +sides: + bottom: ລຸ່ມ + top: ເທິງ + right: ສິດ + left: ຊ້າຍ +header: + labels: + general: ທົ່ວໄປ + shortcuts: ທາງລັດ + info: ຂໍ້ມູນ + seelen_weg: Dock/Taskbar + seelen_bar: ແຖບເຄື່ອງມືແຟນຊີ + specific_apps: ແອັບສະເພາະ + seelen_wm: ຜູ້ຈັດການປ່ອງຢ້ຽມ + monitors: ຈໍພາບ + developer: ນັກພັດທະນາ +start: + title: ຍິນດີຕ້ອນຮັບ! + message_accent: ເພີ່ມປະສິດທິພາບການຜະລິດຂອງເຈົ້າດ້ວຍຮູບແບບ! + message: >- + ຍິນ​ດີ​ຕ້ອນ​ຮັບ​ສູ່ Seelen UI, + ສິ່ງ​ແວດ​ລ້ອມ​ເດັສ​ທັອບ​ທີ່​ດີ​ທີ່​ສຸດ​ທີ່​ມີ​ຕົວ​ຈັດ​ການ​ໜ້າ​ຕ່າງ​ກະ​ເບື້ອງ​ທີ່​ປະ​ກອບ​ເຂົ້າ​ເພື່ອ​ເພີ່ມ​ປະ​ສົບ​ການ + Windows 11 ຂອງ​ທ່ານ! ສຳຫຼວດຍຸກໃໝ່ຂອງປະສິດທິພາບ + ແລະການເຮັດວຽກຫຼາຍໜ້າດ້ວຍການໂຕ້ຕອບທີ່ເຂົ້າໃຈງ່າຍ + ແລະຄຸນສົມບັດຂັ້ນສູງຂອງພວກເຮົາ. +general: + theme: + tags: ປ້າຍກຳກັບ + author: ຜູ້ຂຽນ + description: ລາຍລະອຽດ + enabled: ຮູບແບບສີສັນທີ່ເປີດໃຊ້ງານ + label: ຂໍ້ມູນຫົວຂໍ້ + placeholder: ເລືອກຫົວຂໍ້ + added: ເພີ່ມຮູບແບບສີສັນແລ້ວ + add: ເພີ່ມຫົວຂໍ້ + available: ມີໄວ້ + selected: ຄັດເລືອກ + language: ພາສາ + startup: ດໍາເນີນການກ່ຽວກັບການເລີ່ມຕົ້ນ? + icon_pack: + label: icon ຊອງ + accent_color: ສີສໍານຽງ +toolbar: + placeholder: + author: ຜູ້ຂຽນ + description: ລາຍລະອຽດ + select: ໂຄງສ້າງແຖບເຄື່ອງມື + enable: ເປີດໃຊ້ແຖບເຄື່ອງມື Fancy + height: ຄວາມສູງ +wm: + border: + enable: ເປີດໃຊ້ຂອບຂອງປ່ອງຢ້ຽມ + width: ຄວາມກວ້າງຊາຍແດນ + offset: Border Offset + author: ຜູ້ຂຽນ + description: ລາຍລະອຽດ + layout: ແຜນຜັງ + resize_delta: ປັບຂະໜາດ Delta (%) + space_between_containers: ຊ່ອງຫວ່າງລະຫວ່າງບັນຈຸ + enable: ເປີດໃຊ້ Window Manager + workspace_padding: ພື້ນທີ່ເຮັດວຽກ Padding + workspace_offset: ພື້ນທີ່ເຮັດວຽກຊົດເຊີຍ (ຂອບ) + disabled_windows10: Window Manager ບໍ່ສາມາດໃຊ້ໄດ້ສໍາລັບ Windows 10. +weg: + items: + label: ລາຍການ + visible_separators: ຕົວແຍກທີ່ເບິ່ງເຫັນໄດ້ + zoom_size: ຂະຫຍາຍຂະໜາດ (ໃຊ້ສຳລັບຮູບແບບສີສັນ) + gap: ຊ່ອງຫວ່າງລະຫວ່າງລາຍການ + size: ຂະໜາດລາຍການ + auto_hide: ເຊື່ອງອັດຕະໂນມັດ + width: ກວ້າງ + margin: ຂອບ + label: Dock/Taskbar + padding: padding + gap: ຊ່ອງຫວ່າງ + enable: ເປີດໃຊ້ Dock/Taskbar + dock_side: Dock Side +devtools: + custom_config_file: ໂຫຼດໄຟລ໌ການຕັ້ງຄ່າແບບກຳນົດເອງ + enable: ເປີດໃຊ້ເຄື່ອງມືນັກພັດທະນາ + load: ໂຫຼດ + app_folders: ໂຟນເດີ App + settings_file: ໄຟລ໌ການຕັ້ງຄ່າ + install_folder: ໂຟນເດີການຕິດຕັ້ງ + data_folder: ແຟ້ມຂໍ້ມູນ +apps_configurations: + app: + options: + float: ລອຍ + unmanage: ຍົກເລີກການຈັດການ + pinned: ປັກໝຸດ + force: ບັງຄັບໃຫ້ຈັດການ + monitor: ຕິດຕາມກວດກາ + title_create: ການສ້າງ {{name}} + options_label: ທາງເລືອກພິເສດ + monitor_placeholder: ບໍ່ມີ + workspace_placeholder: ບໍ່ມີ + name: ຊື່ + category_placeholder: ບໍ່ມີ + workspace: ພື້ນທີ່ເຮັດວຽກ + ok_edit: ອັບເດດ + category: ປະເພດ + title_readonly: ກຳລັງເບິ່ງ {{name}} + title_edit: ການແກ້ໄຂ {{name}} + ok_readonly: ແກ້ໄຂເປັນໃໝ່ + ok_create: ສ້າງ + bindings: ການຜູກມັດ (ຫມາຍເຫດທັງສອງທາງເລືອກແມ່ນຈໍາເປັນ) + identifier: + and: ແລະ + negation: Negate ການຈັບຄູ່ + add_block: ເພີ່ມ Block + remove: ລຶບ Block + or: ຫຼື + kind: ກໍານົດໂດຍ + matching_strategy: ຍຸດທະສາດການຈັບຄູ່ + id: ຕົວລະບຸ + search: ຊອກຫາ + export: ສົ່ງອອກ + new: ໃຫມ່ + swap: ແລກປ່ຽນ + import: ນໍາເຂົ້າ + delete: ລຶບ + bundled_title: App Config Bundled ກັບ Seelen + confirm_delete_title: ຢືນຢັນການລຶບ + bundled_msg: >- + ການຕັ້ງຄ່າຊຸດເຫຼົ່ານີ້ບໍ່ສາມາດແກ້ໄຂໄດ້ + ແລະຖືກອອກແບບມາເພື່ອໃຫ້ປະສົບການທີ່ດີທີ່ສຸດແກ່ເຈົ້າໂດຍບໍ່ມີການປັບແຕ່ງ. + ພວກເຂົາຕັ້ງຄ່າແອັບພລິເຄຊັນທົ່ວໄປທີ່ສຸດສໍາລັບທ່ານໂດຍອັດຕະໂນມັດ. + confirm_delete: ທ່ານແນ່ໃຈບໍ່ວ່າຕ້ອງການລຶບການຕັ້ງຄ່ານີ້? +extras: + version: ຮຸ່ນ + github: GitHub + discord: ຄວາມຂັດແຍ້ງ + links: ການເຊື່ອມຕໍ່ຢ່າງເປັນທາງການ + relaunch: ເປີດຄືນໃໝ່ + exit: ອອກ/ອອກ +shortcuts: + labels: + send_to_workspace_3: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 3 + send_to_workspace_4: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 4 + restore_sizes: ຟື້ນຟູຂະໜາດ + move_to_workspace_4: ຍ້າຍໄປບ່ອນເຮັດວຽກ 4 + move_to_workspace_2: ຍ້າຍໄປບ່ອນເຮັດວຽກ 2 + send_to_workspace_1: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 1 + reserve_float: ສະຫງວນ Float + send_to_workspace_2: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 2 + send_to_workspace_9: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 9 + move_to_workspace_7: ຍ້າຍໄປບ່ອນເຮັດວຽກ 7 + switch_workspace_0: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 0 + send_to_workspace_5: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 5 + switch_workspace_1: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 1 + switch_workspace_6: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 6 + focus_right: ໂຟກັສຂວາ + focus_left: ໂຟກັສຊ້າຍ + increase_height: ເພີ່ມຄວາມສູງ + focus_latest: Focus ຫຼ້າສຸດ + send_to_workspace_7: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 7 + reserve_left: ຈອງຊ້າຍ + reserve_bottom: ຈອງລຸ່ມ + move_to_workspace_1: ຍ້າຍໄປບ່ອນເຮັດວຽກ 1 + send_to_workspace_0: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 0 + move_to_workspace_5: ຍ້າຍໄປບ່ອນເຮັດວຽກ 5 + switch_workspace_5: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 5 + decrease_height: ຫຼຸດຄວາມສູງ + decrease_width: ຫຼຸດຄວາມກວ້າງ + switch_workspace_9: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 9 + move_to_workspace_8: ຍ້າຍໄປບ່ອນເຮັດວຽກ 8 + send_to_workspace_6: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 6 + move_to_workspace_0: ຍ້າຍໄປບ່ອນເຮັດວຽກ 0 + focus_top: ໂຟກັສເທິງ + increase_width: ເພີ່ມຄວາມກວ້າງ + move_to_workspace_3: ຍ້າຍໄປບ່ອນເຮັດວຽກ 3 + reserve_right: ສະຫງວນສິດ + reserve_stack: ຈອງ stack + reserve_top: ສະຫງວນເທິງ + move_to_workspace_6: ຍ້າຍໄປບ່ອນເຮັດວຽກ 6 + move_to_workspace_9: ຍ້າຍໄປບ່ອນເຮັດວຽກ 9 + switch_workspace_8: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 8 + switch_workspace_7: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 7 + switch_workspace_2: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 2 + switch_workspace_3: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 3 + switch_workspace_4: ສະຫຼັບໄປບ່ອນເຮັດວຽກ 4 + send_to_workspace_8: ສົ່ງໄປທີ່ບ່ອນເຮັດວຽກ 8 + focus_bottom: ໂຟກັສລຸ່ມ + enable_tooltip: ປິດໃຊ້ງານຖ້າທ່ານຈະປະຕິບັດທາງລັດຂອງທ່ານເອງໂດຍໃຊ້ Seelen Core Api + enable: ເປີດໃຊ້ທາງລັດປະສົມປະສານ (ahk) +cancel: ຍົກເລີກ +loading: ກຳລັງໂຫລດ... +delete: ລຶບ +quit: ເຊົາ +save: ບັນທຶກ +inProgress: ຢູ່ໃນຄວາມຄືບໜ້າ... +open: ເປີດ diff --git a/src/apps/settings/i18n/translations/lt.yml b/src/apps/settings/i18n/translations/lt.yml index aab931bc..7514bd1d 100644 --- a/src/apps/settings/i18n/translations/lt.yml +++ b/src/apps/settings/i18n/translations/lt.yml @@ -1,193 +1,193 @@ -sides: - left: Kairėje - right: Teisingai - top: Viršus - bottom: Apačia -header: - labels: - developer: Programuotojas - seelen_wm: Lango vadovas - specific_apps: Konkrečios programos - seelen_bar: Išgalvota įrankių juosta - monitors: Monitoriai - seelen_weg: „Dock“/„Taskbar“ - info: Informacija - shortcuts: Nuorodos - general: Bendrasis -start: - title: Sveiki! - message_accent: Optimizuokite savo produktyvumą stiliumi! - message: >- - Sveiki atvykę į „Seelen UI“, „Ultimate Desktop“ aplinką su „Incorporated“ - plytelių „Windows Manager“, kad patobulintumėte „Windows 11“ patirtį! - Naršykite naują efektyvumo ir daugiafunkcinių užduočių erą naudodamiesi - intuityvia sąsaja ir pažangiomis funkcijomis. -general: - theme: - enabled: Įgalintos temos - description: apibūdinimas - add: Pridėkite temą - placeholder: Pasirinkite temą - label: Informacija apie temą - added: Jau pridėta tema - author: Autorius - tags: Žymos - available: Galima - selected: Pasirinktas - language: Kalba - startup: Paleisti paleidimą? - icon_pack: - label: ICON PACKS - accent_color: Akcento spalva -toolbar: - placeholder: - select: Įrankių juostos struktūra - description: apibūdinimas - author: Autorius - height: Ūgis - enable: Įgalinkite išgalvotą įrankių juostą -wm: - border: - enable: Įgalinti lango sieną - offset: Sienos poslinkis - width: Sienos plotis - space_between_containers: Tarpas tarp konteinerių - description: apibūdinimas - enable: Įgalinkite lango tvarkyklę - resize_delta: Pakeisti deltos dydį (%) - layout: Išdėstymas - disabled_windows10: „Windows Manager“ nėra „Windows 10“. - author: Autorius - workspace_offset: Darbo vietos poslinkis (paraštės) - workspace_padding: Darbo vietų pamušalas -weg: - items: - size: Prekės dydis - zoom_size: Mastelio dydis (naudojamas temoms) - gap: Tarpas tarp daiktų - visible_separators: Matomi separatoriai - label: Daiktai - auto_hide: Automatinis slėptuvė - padding: Paminkštinimas - margin: Paraštė - label: „Dock“/„Taskbar“ - width: Plotis - enable: Įgalinti doką/užduočių juostą - dock_side: Doko pusė - gap: Tarpas -devtools: - settings_file: Nustatymų failas - custom_config_file: Įkelkite pasirinktinį konfigūracijos failą - enable: Įgalinkite kūrėjo įrankius - data_folder: Duomenų aplankas - install_folder: Diegimo aplankas - load: Įkelti - app_folders: Programos aplankai -apps_configurations: - app: - options: - float: Plūdė - force: Jėgos valdymas - pinned: Prigludęs - unmanage: Nevaldomas - name: vardas - title_readonly: Peržiūra {{name}} - monitor_placeholder: Nė vienas - category: Kategorija - category_placeholder: Nė vienas - title_create: Kurti {{name}} - bindings: Įrišimas (pastaba yra būtinos abi parinktys) - title_edit: Redagavimas {{name}} - workspace: Darbo vieta - workspace_placeholder: Nė vienas - options_label: Papildomos galimybės - ok_edit: Atnaujinimas - ok_create: Sukurti - monitor: Monitorius - ok_readonly: Redaguoti kaip naują - identifier: - id: Identifikatorius - negation: Neigiamas - matching_strategy: Atitikimo strategija - add_block: Pridėkite bloką - remove: Ištrinti bloką - kind: Identifikuoti - and: Ir - or: Arba - swap: Apsikeitimas - delete: Ištrinti - search: Paieška - bundled_msg: >- - Šios sujungtos konfigūracijos nėra redaguojamos ir yra skirtos suteikti jums - geriausią patirtį be pritaikymo. Jie automatiškai sukonfigūruoja dažniausiai - jums. - new: Nauja - confirm_delete: Ar tikrai norite ištrinti šią konfigūraciją (-us)? - import: Importuoti - confirm_delete_title: Patvirtinkite ištrynti - export: Eksportas - bundled_title: APP CONFIC sujungta su „Seelen“ -extras: - links: Oficialios nuorodos - github: Github - discord: Nesantaika - relaunch: Atsikrauti - exit: Mesti/išeiti - version: Versija -shortcuts: - labels: - reserve_right: Rezervuokite dešinę - send_to_workspace_1: Siųsti į 1 darbo vietą - switch_workspace_9: Perjunkite į 9 darbo vietą - move_to_workspace_3: Pereikite į 3 darbo vietą - increase_width: Padidinti plotį - send_to_workspace_0: Siųsti į darbo vietą 0 - focus_right: Susitelkite teisingai - decrease_width: Sumažinti plotį - switch_workspace_7: Perjunkite į 7 darbo vietą - reserve_bottom: Rezervo dugnas - send_to_workspace_8: Siųsti į „Workspace 8“ - reserve_left: Rezervas kairėje - reserve_float: Atsargos plūdė - send_to_workspace_2: Siųsti į 2 darbo vietą - move_to_workspace_5: Pereikite į 5 darbo vietą - switch_workspace_1: Perjunkite į 1 darbo vietą - focus_top: Fokusavimo viršus - focus_latest: Sutelkite naujausią - send_to_workspace_5: Siųsti į 5 darbo vietą - switch_workspace_4: Perjunkite į 4 darbo vietą - send_to_workspace_4: Siųsti į 4 darbo vietą - send_to_workspace_9: Siųsti į „Workspace 9“ - send_to_workspace_6: Siųsti į „Workspace 6“ - move_to_workspace_4: Pereikite į 4 darbo vietą - switch_workspace_2: Perjunkite į 2 darbo vietą - move_to_workspace_2: Pereikite į 2 darbo vietą - switch_workspace_8: Perjunkite į 8 darbo vietą - focus_left: Fokusavimas kairėje - move_to_workspace_1: Pereikite į 1 darbo vietą - increase_height: Padidinti aukštį - reserve_top: Rezervuokite viršų - switch_workspace_6: Perjunkite į 6 darbo vietą - move_to_workspace_7: Pereikite į 7 darbo vietą - move_to_workspace_8: Pereikite į 8 darbo vietą - switch_workspace_0: Perjunkite į darbo vietą 0 - switch_workspace_5: Perjunkite į 5 darbo vietą - send_to_workspace_7: Siųsti į „Workspace 7“ - send_to_workspace_3: Siųsti į 3 „Workspace“ - decrease_height: Sumažinti aukštį - restore_sizes: Atkurti dydžius - move_to_workspace_6: Pereikite į 6 darbo vietą - move_to_workspace_9: Pereikite į 9 darbo vietą - switch_workspace_3: Perjunkite į 3 darbo vietą - move_to_workspace_0: Pereikite į 0 darbo vietą - reserve_stack: Rezervo kaminas - focus_bottom: Fokusavimo dugnas - enable: Įgalinkite integruotus sparčiuosius klavišus (AHK) - enable_tooltip: Išjunkite, jei įdiegsite savo nuorodas naudodami „Seelen Core API“ -delete: Ištrinti -open: Atviras -save: Sutaupyti -inProgress: Vyksta ... -quit: Mesti -loading: Pakrovimas ... -cancel: Atšaukti +sides: + left: Kairėje + right: Teisingai + top: Viršus + bottom: Apačia +header: + labels: + developer: Programuotojas + seelen_wm: Lango vadovas + specific_apps: Konkrečios programos + seelen_bar: Išgalvota įrankių juosta + monitors: Monitoriai + seelen_weg: „Dock“/„Taskbar“ + info: Informacija + shortcuts: Nuorodos + general: Bendrasis +start: + title: Sveiki! + message_accent: Optimizuokite savo produktyvumą stiliumi! + message: >- + Sveiki atvykę į „Seelen UI“, „Ultimate Desktop“ aplinką su „Incorporated“ + plytelių „Windows Manager“, kad patobulintumėte „Windows 11“ patirtį! + Naršykite naują efektyvumo ir daugiafunkcinių užduočių erą naudodamiesi + intuityvia sąsaja ir pažangiomis funkcijomis. +general: + theme: + enabled: Įgalintos temos + description: apibūdinimas + add: Pridėkite temą + placeholder: Pasirinkite temą + label: Informacija apie temą + added: Jau pridėta tema + author: Autorius + tags: Žymos + available: Galima + selected: Pasirinktas + language: Kalba + startup: Paleisti paleidimą? + icon_pack: + label: ICON PACKS + accent_color: Akcento spalva +toolbar: + placeholder: + select: Įrankių juostos struktūra + description: apibūdinimas + author: Autorius + height: Ūgis + enable: Įgalinkite išgalvotą įrankių juostą +wm: + border: + enable: Įgalinti lango sieną + offset: Sienos poslinkis + width: Sienos plotis + space_between_containers: Tarpas tarp konteinerių + description: apibūdinimas + enable: Įgalinkite lango tvarkyklę + resize_delta: Pakeisti deltos dydį (%) + layout: Išdėstymas + disabled_windows10: „Windows Manager“ nėra „Windows 10“. + author: Autorius + workspace_offset: Darbo vietos poslinkis (paraštės) + workspace_padding: Darbo vietų pamušalas +weg: + items: + size: Prekės dydis + zoom_size: Mastelio dydis (naudojamas temoms) + gap: Tarpas tarp daiktų + visible_separators: Matomi separatoriai + label: Daiktai + auto_hide: Automatinis slėptuvė + padding: Paminkštinimas + margin: Paraštė + label: „Dock“/„Taskbar“ + width: Plotis + enable: Įgalinti doką/užduočių juostą + dock_side: Doko pusė + gap: Tarpas +devtools: + settings_file: Nustatymų failas + custom_config_file: Įkelkite pasirinktinį konfigūracijos failą + enable: Įgalinkite kūrėjo įrankius + data_folder: Duomenų aplankas + install_folder: Diegimo aplankas + load: Įkelti + app_folders: Programos aplankai +apps_configurations: + app: + options: + float: Plūdė + force: Jėgos valdymas + pinned: Prigludęs + unmanage: Nevaldomas + name: vardas + title_readonly: Peržiūra {{name}} + monitor_placeholder: Nė vienas + category: Kategorija + category_placeholder: Nė vienas + title_create: Kurti {{name}} + bindings: Įrišimas (pastaba yra būtinos abi parinktys) + title_edit: Redagavimas {{name}} + workspace: Darbo vieta + workspace_placeholder: Nė vienas + options_label: Papildomos galimybės + ok_edit: Atnaujinimas + ok_create: Sukurti + monitor: Monitorius + ok_readonly: Redaguoti kaip naują + identifier: + id: Identifikatorius + negation: Neigiamas + matching_strategy: Atitikimo strategija + add_block: Pridėkite bloką + remove: Ištrinti bloką + kind: Identifikuoti + and: Ir + or: Arba + swap: Apsikeitimas + delete: Ištrinti + search: Paieška + bundled_msg: >- + Šios sujungtos konfigūracijos nėra redaguojamos ir yra skirtos suteikti jums + geriausią patirtį be pritaikymo. Jie automatiškai sukonfigūruoja dažniausiai + jums. + new: Nauja + confirm_delete: Ar tikrai norite ištrinti šią konfigūraciją (-us)? + import: Importuoti + confirm_delete_title: Patvirtinkite ištrynti + export: Eksportas + bundled_title: APP CONFIC sujungta su „Seelen“ +extras: + links: Oficialios nuorodos + github: Github + discord: Nesantaika + relaunch: Atsikrauti + exit: Mesti/išeiti + version: Versija +shortcuts: + labels: + reserve_right: Rezervuokite dešinę + send_to_workspace_1: Siųsti į 1 darbo vietą + switch_workspace_9: Perjunkite į 9 darbo vietą + move_to_workspace_3: Pereikite į 3 darbo vietą + increase_width: Padidinti plotį + send_to_workspace_0: Siųsti į darbo vietą 0 + focus_right: Susitelkite teisingai + decrease_width: Sumažinti plotį + switch_workspace_7: Perjunkite į 7 darbo vietą + reserve_bottom: Rezervo dugnas + send_to_workspace_8: Siųsti į „Workspace 8“ + reserve_left: Rezervas kairėje + reserve_float: Atsargos plūdė + send_to_workspace_2: Siųsti į 2 darbo vietą + move_to_workspace_5: Pereikite į 5 darbo vietą + switch_workspace_1: Perjunkite į 1 darbo vietą + focus_top: Fokusavimo viršus + focus_latest: Sutelkite naujausią + send_to_workspace_5: Siųsti į 5 darbo vietą + switch_workspace_4: Perjunkite į 4 darbo vietą + send_to_workspace_4: Siųsti į 4 darbo vietą + send_to_workspace_9: Siųsti į „Workspace 9“ + send_to_workspace_6: Siųsti į „Workspace 6“ + move_to_workspace_4: Pereikite į 4 darbo vietą + switch_workspace_2: Perjunkite į 2 darbo vietą + move_to_workspace_2: Pereikite į 2 darbo vietą + switch_workspace_8: Perjunkite į 8 darbo vietą + focus_left: Fokusavimas kairėje + move_to_workspace_1: Pereikite į 1 darbo vietą + increase_height: Padidinti aukštį + reserve_top: Rezervuokite viršų + switch_workspace_6: Perjunkite į 6 darbo vietą + move_to_workspace_7: Pereikite į 7 darbo vietą + move_to_workspace_8: Pereikite į 8 darbo vietą + switch_workspace_0: Perjunkite į darbo vietą 0 + switch_workspace_5: Perjunkite į 5 darbo vietą + send_to_workspace_7: Siųsti į „Workspace 7“ + send_to_workspace_3: Siųsti į 3 „Workspace“ + decrease_height: Sumažinti aukštį + restore_sizes: Atkurti dydžius + move_to_workspace_6: Pereikite į 6 darbo vietą + move_to_workspace_9: Pereikite į 9 darbo vietą + switch_workspace_3: Perjunkite į 3 darbo vietą + move_to_workspace_0: Pereikite į 0 darbo vietą + reserve_stack: Rezervo kaminas + focus_bottom: Fokusavimo dugnas + enable: Įgalinkite integruotus sparčiuosius klavišus (AHK) + enable_tooltip: Išjunkite, jei įdiegsite savo nuorodas naudodami „Seelen Core API“ +delete: Ištrinti +open: Atviras +save: Sutaupyti +inProgress: Vyksta ... +quit: Mesti +loading: Pakrovimas ... +cancel: Atšaukti diff --git a/src/apps/settings/i18n/translations/lv.yml b/src/apps/settings/i18n/translations/lv.yml index d703f9f2..abc7b28f 100644 --- a/src/apps/settings/i18n/translations/lv.yml +++ b/src/apps/settings/i18n/translations/lv.yml @@ -1,193 +1,193 @@ -sides: - top: Tops - right: Pa labi - left: Atstāts - bottom: Dibens -header: - labels: - info: Informācija - shortcuts: Saīsnes - specific_apps: Īpašas lietotnes - seelen_bar: Izdomāta rīkjosla - developer: Attīstītājs - seelen_wm: Logu vadītājs - general: Ģenerāldirektors - seelen_weg: Doks/uzdevumjosla - monitors: Monitori -start: - message_accent: Optimizējiet savu produktivitāti ar stilu! - message: >- - Laipni lūdzam Seelen Ui, galvenajā darbvirsmas vidē ar iestrādātu flīzes - Windows Manager, lai uzlabotu jūsu Windows 11 pieredzi! Izpētiet jaunu - efektivitātes un daudzuzdevumu laikmetu ar mūsu intuitīvo interfeisu un - uzlabotajām funkcijām. - title: Laipni lūdzam! -general: - theme: - added: Tēma jau pievienota - add: Pievienot tēmu - description: Apraksts - placeholder: Atlasīt tēmu - tags: Tagi - label: Informācija par tēmu - author: Autors - enabled: Iespējotās tēmas - selected: Atlasīts - available: Pieejams - startup: Skriet startup? - language: Valoda - icon_pack: - label: Ikonu paketes - accent_color: Akcents -toolbar: - placeholder: - author: Autors - description: Apraksts - select: Rīkjoslas struktūra - enable: Iespējot izdomātu rīkjoslu - height: Augstums -wm: - border: - enable: Iespējot loga robežu - offset: Robežas kompensācija - width: Apmales platums - space_between_containers: Telpa starp konteineriem - author: Autors - enable: Iespējot logu pārvaldnieku - resize_delta: Delta izmēra maiņa (%) - disabled_windows10: Logu pārvaldnieks nav pieejams operētājsistēmai Windows 10. - workspace_offset: Darbvietu kompensācija (malas) - layout: Izkārtojums - workspace_padding: Darbvietas polsterējums - description: Apraksts -weg: - items: - visible_separators: Redzami atdalītāji - zoom_size: Tuvināta izmēra (izmanto tēmām) - label: Priekšmeti - size: Vienuma izmērs - gap: Vieta starp priekšmetiem - gap: Plaisa - label: Doks/uzdevumjosla - auto_hide: Auto paslēpt - padding: Polsterējums - enable: Iespējot doku/uzdevumjoslu - margin: Robeža - width: Platums - dock_side: Doka puse -devtools: - install_folder: Instalēšanas mape - enable: Iespējot izstrādātāju rīkus - custom_config_file: Ielādēt pielāgotu konfigurācijas failu - settings_file: Iestatīšanas fails - app_folders: Lietotņu mapes - load: Slodze - data_folder: Datu mape -apps_configurations: - app: - options: - float: Peldēt - pinned: Saspiests - force: Piespiest pārvaldīt - unmanage: Pārvalde - ok_edit: Atjaunināt - monitor_placeholder: Neviens - category: Kategorija - name: Nosaukt - title_edit: Rediģēšana {{name}} - title_create: Izveidot {{name}} - ok_readonly: Rediģēt kā jaunu - workspace_placeholder: Neviens - bindings: Iesiešana (ņemiet vērā, ka ir vajadzīgas abas opcijas) - title_readonly: Skatoties {{name}} - options_label: Papildu iespējas - category_placeholder: Neviens - monitor: Kontrolēt - workspace: Darba vieta - ok_create: Radīt - identifier: - and: UN - matching_strategy: Atbilstības stratēģija - remove: Dzēst bloku - add_block: Pievienot bloku - or: Vai - kind: Identificēt ar - negation: Negatīva atbilstība - id: Identifikators - search: Meklēt - swap: Apmaiņa - import: Importēt - bundled_title: Lietotnes konfigurācija, kas komplektēta ar Seelen - confirm_delete: Vai esat pārliecināts, ka vēlaties izdzēst šo konfigurāciju/-as? - confirm_delete_title: Apstipriniet izdzēst - new: Jauns - export: Eksportēt - bundled_msg: >- - Šīs komplektētās konfigurācijas nav rediģējamas un ir paredzētas, lai - sniegtu jums vislabāko pieredzi bez pielāgošanas. Tie automātiski konfigurē - jums visizplatītākās lietojumprogrammas. - delete: Dzēst -extras: - relaunch: Atsākšana - links: Oficiālas saites - discord: Nesaskaņas - github: Github - exit: Atmest/iziet - version: Versija -shortcuts: - labels: - move_to_workspace_4: Pārvietojieties uz Workspace 4 - switch_workspace_2: Pārslēdzieties uz darbvietu 2 - focus_left: Fokusēt pa kreisi - move_to_workspace_3: Pārvietojieties uz darbvietu 3 - switch_workspace_9: Pārslēdzieties uz darbvietu 9 - switch_workspace_6: Pārslēdzieties uz darbvietu 6 - move_to_workspace_0: Pārvietojieties uz darbvietu 0 - decrease_height: Samazināt augstumu - focus_top: Fokusa tops - focus_bottom: Fokusēt apakšā - switch_workspace_7: Pārslēdzieties uz darbvietu 7 - focus_latest: Fokuss jaunākais - switch_workspace_3: Pārslēdzieties uz darbvietu 3 - move_to_workspace_6: Pārvietojieties uz darbvietu 6 - move_to_workspace_8: Pārvietojieties uz Workspace 8 - send_to_workspace_1: Nosūtīt uz 1. darbvietu - increase_width: Palielināt platumu - move_to_workspace_5: Pārvietojieties uz Workspace 5 - send_to_workspace_8: Nosūtīt uz darbvietu 8 - send_to_workspace_2: Nosūtīt uz darbvietu 2 - increase_height: Palielināt augstumu - switch_workspace_0: Pārslēdzieties uz darbvietu 0 - restore_sizes: Atjaunot izmērus - send_to_workspace_4: Nosūtiet uz Workspace 4 - send_to_workspace_9: Nosūtīt uz darbvietu 9 - switch_workspace_4: Pārslēdzieties uz darbvietu 4 - reserve_top: Rezerves tops - reserve_bottom: Rezervēt apakšdaļu - reserve_right: Rezervēt pa labi - switch_workspace_5: Pārslēdzieties uz Workspace 5 - switch_workspace_1: Pārslēdzieties uz 1. darbvietu - reserve_left: Rezervēt pa kreisi - switch_workspace_8: Pārslēdzieties uz darbvietu 8 - reserve_float: Rezerves pludiņš - move_to_workspace_1: Pārvietojieties uz 1. darbvietu - send_to_workspace_6: Nosūtīt uz darbvietu 6 - focus_right: Fokusēt pa labi - move_to_workspace_2: Pārvietojieties uz darbvietu 2 - send_to_workspace_5: Nosūtīt uz darba vietu 5 - move_to_workspace_9: Pārvietojieties uz darbvietu 9 - move_to_workspace_7: Pārvietojieties uz darbvietu 7 - send_to_workspace_0: Nosūtīt uz darbvietu 0 - send_to_workspace_7: Nosūtīt uz darbvietu 7 - reserve_stack: Rezerves kaudze - decrease_width: Samazināt platumu - send_to_workspace_3: Nosūtīt uz darbvietu 3 - enable: Iespējot integrētus saīsnes (AHK) - enable_tooltip: Atspējot, ja ieviesīsit savus saīsnes, izmantojot Seelen Core API -delete: Dzēst -cancel: Atcelt -loading: Iekraušana ... -quit: Atmest -inProgress: Notiek ... -open: Atvērt -save: Ietaupīt +sides: + top: Tops + right: Pa labi + left: Atstāts + bottom: Dibens +header: + labels: + info: Informācija + shortcuts: Saīsnes + specific_apps: Īpašas lietotnes + seelen_bar: Izdomāta rīkjosla + developer: Attīstītājs + seelen_wm: Logu vadītājs + general: Ģenerāldirektors + seelen_weg: Doks/uzdevumjosla + monitors: Monitori +start: + message_accent: Optimizējiet savu produktivitāti ar stilu! + message: >- + Laipni lūdzam Seelen Ui, galvenajā darbvirsmas vidē ar iestrādātu flīzes + Windows Manager, lai uzlabotu jūsu Windows 11 pieredzi! Izpētiet jaunu + efektivitātes un daudzuzdevumu laikmetu ar mūsu intuitīvo interfeisu un + uzlabotajām funkcijām. + title: Laipni lūdzam! +general: + theme: + added: Tēma jau pievienota + add: Pievienot tēmu + description: Apraksts + placeholder: Atlasīt tēmu + tags: Tagi + label: Informācija par tēmu + author: Autors + enabled: Iespējotās tēmas + selected: Atlasīts + available: Pieejams + startup: Skriet startup? + language: Valoda + icon_pack: + label: Ikonu paketes + accent_color: Akcents +toolbar: + placeholder: + author: Autors + description: Apraksts + select: Rīkjoslas struktūra + enable: Iespējot izdomātu rīkjoslu + height: Augstums +wm: + border: + enable: Iespējot loga robežu + offset: Robežas kompensācija + width: Apmales platums + space_between_containers: Telpa starp konteineriem + author: Autors + enable: Iespējot logu pārvaldnieku + resize_delta: Delta izmēra maiņa (%) + disabled_windows10: Logu pārvaldnieks nav pieejams operētājsistēmai Windows 10. + workspace_offset: Darbvietu kompensācija (malas) + layout: Izkārtojums + workspace_padding: Darbvietas polsterējums + description: Apraksts +weg: + items: + visible_separators: Redzami atdalītāji + zoom_size: Tuvināta izmēra (izmanto tēmām) + label: Priekšmeti + size: Vienuma izmērs + gap: Vieta starp priekšmetiem + gap: Plaisa + label: Doks/uzdevumjosla + auto_hide: Auto paslēpt + padding: Polsterējums + enable: Iespējot doku/uzdevumjoslu + margin: Robeža + width: Platums + dock_side: Doka puse +devtools: + install_folder: Instalēšanas mape + enable: Iespējot izstrādātāju rīkus + custom_config_file: Ielādēt pielāgotu konfigurācijas failu + settings_file: Iestatīšanas fails + app_folders: Lietotņu mapes + load: Slodze + data_folder: Datu mape +apps_configurations: + app: + options: + float: Peldēt + pinned: Saspiests + force: Piespiest pārvaldīt + unmanage: Pārvalde + ok_edit: Atjaunināt + monitor_placeholder: Neviens + category: Kategorija + name: Nosaukt + title_edit: Rediģēšana {{name}} + title_create: Izveidot {{name}} + ok_readonly: Rediģēt kā jaunu + workspace_placeholder: Neviens + bindings: Iesiešana (ņemiet vērā, ka ir vajadzīgas abas opcijas) + title_readonly: Skatoties {{name}} + options_label: Papildu iespējas + category_placeholder: Neviens + monitor: Kontrolēt + workspace: Darba vieta + ok_create: Radīt + identifier: + and: UN + matching_strategy: Atbilstības stratēģija + remove: Dzēst bloku + add_block: Pievienot bloku + or: Vai + kind: Identificēt ar + negation: Negatīva atbilstība + id: Identifikators + search: Meklēt + swap: Apmaiņa + import: Importēt + bundled_title: Lietotnes konfigurācija, kas komplektēta ar Seelen + confirm_delete: Vai esat pārliecināts, ka vēlaties izdzēst šo konfigurāciju/-as? + confirm_delete_title: Apstipriniet izdzēst + new: Jauns + export: Eksportēt + bundled_msg: >- + Šīs komplektētās konfigurācijas nav rediģējamas un ir paredzētas, lai + sniegtu jums vislabāko pieredzi bez pielāgošanas. Tie automātiski konfigurē + jums visizplatītākās lietojumprogrammas. + delete: Dzēst +extras: + relaunch: Atsākšana + links: Oficiālas saites + discord: Nesaskaņas + github: Github + exit: Atmest/iziet + version: Versija +shortcuts: + labels: + move_to_workspace_4: Pārvietojieties uz Workspace 4 + switch_workspace_2: Pārslēdzieties uz darbvietu 2 + focus_left: Fokusēt pa kreisi + move_to_workspace_3: Pārvietojieties uz darbvietu 3 + switch_workspace_9: Pārslēdzieties uz darbvietu 9 + switch_workspace_6: Pārslēdzieties uz darbvietu 6 + move_to_workspace_0: Pārvietojieties uz darbvietu 0 + decrease_height: Samazināt augstumu + focus_top: Fokusa tops + focus_bottom: Fokusēt apakšā + switch_workspace_7: Pārslēdzieties uz darbvietu 7 + focus_latest: Fokuss jaunākais + switch_workspace_3: Pārslēdzieties uz darbvietu 3 + move_to_workspace_6: Pārvietojieties uz darbvietu 6 + move_to_workspace_8: Pārvietojieties uz Workspace 8 + send_to_workspace_1: Nosūtīt uz 1. darbvietu + increase_width: Palielināt platumu + move_to_workspace_5: Pārvietojieties uz Workspace 5 + send_to_workspace_8: Nosūtīt uz darbvietu 8 + send_to_workspace_2: Nosūtīt uz darbvietu 2 + increase_height: Palielināt augstumu + switch_workspace_0: Pārslēdzieties uz darbvietu 0 + restore_sizes: Atjaunot izmērus + send_to_workspace_4: Nosūtiet uz Workspace 4 + send_to_workspace_9: Nosūtīt uz darbvietu 9 + switch_workspace_4: Pārslēdzieties uz darbvietu 4 + reserve_top: Rezerves tops + reserve_bottom: Rezervēt apakšdaļu + reserve_right: Rezervēt pa labi + switch_workspace_5: Pārslēdzieties uz Workspace 5 + switch_workspace_1: Pārslēdzieties uz 1. darbvietu + reserve_left: Rezervēt pa kreisi + switch_workspace_8: Pārslēdzieties uz darbvietu 8 + reserve_float: Rezerves pludiņš + move_to_workspace_1: Pārvietojieties uz 1. darbvietu + send_to_workspace_6: Nosūtīt uz darbvietu 6 + focus_right: Fokusēt pa labi + move_to_workspace_2: Pārvietojieties uz darbvietu 2 + send_to_workspace_5: Nosūtīt uz darba vietu 5 + move_to_workspace_9: Pārvietojieties uz darbvietu 9 + move_to_workspace_7: Pārvietojieties uz darbvietu 7 + send_to_workspace_0: Nosūtīt uz darbvietu 0 + send_to_workspace_7: Nosūtīt uz darbvietu 7 + reserve_stack: Rezerves kaudze + decrease_width: Samazināt platumu + send_to_workspace_3: Nosūtīt uz darbvietu 3 + enable: Iespējot integrētus saīsnes (AHK) + enable_tooltip: Atspējot, ja ieviesīsit savus saīsnes, izmantojot Seelen Core API +delete: Dzēst +cancel: Atcelt +loading: Iekraušana ... +quit: Atmest +inProgress: Notiek ... +open: Atvērt +save: Ietaupīt diff --git a/src/apps/settings/i18n/translations/mk.yml b/src/apps/settings/i18n/translations/mk.yml index 12d5cc19..d33ac8e0 100644 --- a/src/apps/settings/i18n/translations/mk.yml +++ b/src/apps/settings/i18n/translations/mk.yml @@ -1,195 +1,195 @@ -sides: - left: Лево - top: Врв - bottom: Дно - right: Десно -header: - labels: - seelen_bar: Фенси лента со алатки - developer: Развивач - shortcuts: Кратенки - general: Општо - info: Информации - seelen_wm: Менаџер на прозорци - seelen_weg: Док/лента со задачи - monitors: Монитори - specific_apps: Специфични апликации -start: - title: Добредојдовте! - message_accent: Оптимизирајте ја вашата продуктивност со стил! - message: >- - Добредојдовте во Seelen UI, крајната околина за десктоп со вграден менаџер - за прозорци за Windows за подобрување на вашето искуство со Windows 11! - Истражете нова ера на ефикасност и мултитаскинг со нашиот интуитивен - интерфејс и напредни карактеристики. -general: - theme: - tags: Тагови - enabled: Овозможени теми - author: Автор - added: Веќе додадена тема - label: Информации за теми - description: Опис - placeholder: Изберете тема - add: Додадете тема - selected: Избран - available: Достапно - language: Јазик - startup: Стартувам на стартување? - icon_pack: - label: Икони пакувања - accent_color: Боја на акцент -toolbar: - placeholder: - author: Автор - select: Структура на лентата со алатки - description: Опис - height: Висина - enable: Овозможете фенси лента со алатки -wm: - border: - width: Ширина на границата - offset: Офсет за граница - enable: Овозможете ја границата на прозорецот - enable: Овозможи менаџер на прозорци - workspace_padding: Подлога за работни места - resize_delta: Променете ја големината на Делта (%) - disabled_windows10: Менаџерот на прозорецот не е достапен за Windows 10. - workspace_offset: Работни места за неутрализирање (маргини) - space_between_containers: Простор помеѓу контејнери - layout: Распоред - description: Опис - author: Автор -weg: - items: - size: Големина на артикалот - label: Предмети - zoom_size: Зумирана големина (се користи за теми) - visible_separators: Видливи сепаратори - gap: Простор помеѓу предмети - width: Ширина - dock_side: Страна на пристаништето - enable: Овозможете пристаниште/лента со задачи - auto_hide: Автоматско скриј - gap: Јаз - margin: Маргина - padding: Подлога - label: Док/лента со задачи -devtools: - load: Оптоварување - custom_config_file: Вчитајте ја датотеката за прилагодена конфигурација - data_folder: Папка со податоци - install_folder: Папка за инсталација - settings_file: Датотека за поставки - enable: Овозможете алатки за развивачи - app_folders: Папки со апликации -apps_configurations: - app: - options: - float: Плови - unmanage: Unmanage - pinned: Закачен - force: Управување со сила - title_edit: Уредување {{име}} - ok_edit: Ажурирање - category_placeholder: Ништо - name: Име - workspace_placeholder: Ништо - workspace: Работен простор - ok_create: Креирај - monitor_placeholder: Ништо - bindings: Обврзувачки (Забележете дека се потребни и двете опции) - title_readonly: Гледање {{име}} - monitor: Монитор - options_label: Дополнителни опции - ok_readonly: Уреди како ново - category: Категорија - title_create: Креирање {{име}} - identifier: - remove: Избриши блок - matching_strategy: Стратегија за појавување - or: Или - id: Идентификатор - kind: Идентификувајте од - and: И - negation: Негираат совпаѓање - add_block: Додадете блок - delete: Избриши - export: Извоз - swap: Разменување - search: Пребарување - bundled_msg: >- - Овие конфигурации во комплет не се уредни и се дизајнирани да ви обезбедат - најдобро искуство без прилагодување. Тие автоматски ги конфигурираат - најчестите апликации за вас. - import: Увоз - confirm_delete: Дали сте сигурни дека сакате да ја избришете оваа конфигурација/а? - new: Ново - bundled_title: Конфигурирана апликација во комплет со Селен - confirm_delete_title: Потврдете го Избриши -extras: - relaunch: Повторно започнување - links: Официјални врски - exit: Откажете/излез - version: Верзија - github: Github - discord: Раздор -shortcuts: - labels: - move_to_workspace_2: Преместете се на работниот простор 2 - move_to_workspace_6: Преместете се на работниот простор 6 - switch_workspace_2: Префрлете се на работниот простор 2 - send_to_workspace_3: Испратете на работниот простор 3 - switch_workspace_5: Префрлете се на работниот простор 5 - move_to_workspace_7: Преместете се на работниот простор 7 - reserve_left: Резерва лево - focus_bottom: Фокус дното - move_to_workspace_1: Преместете се на работниот простор 1 - reserve_float: Резерва плови - send_to_workspace_2: Испратете на работниот простор 2 - focus_top: Фокус врвот - switch_workspace_1: Префрлете се на работниот простор 1 - send_to_workspace_0: Испратете на работниот простор 0 - reserve_stack: Резервен магацин - increase_height: Зголемете ја висината - switch_workspace_9: Префрлете се на работниот простор 9 - decrease_height: Намалување на висината - increase_width: Зголемете ја ширината - send_to_workspace_6: Испратете на работниот простор 6 - focus_right: Фокусирајте се десно - reserve_top: Резервен врв - reserve_right: Резервирајте десно - send_to_workspace_8: Испратете на работниот простор 8 - send_to_workspace_5: Испратете на работниот простор 5 - move_to_workspace_0: Преместете се на работниот простор 0 - move_to_workspace_8: Преместете се на работниот простор 8 - reserve_bottom: Резервно дно - send_to_workspace_1: Испратете на работниот простор 1 - switch_workspace_7: Префрлете се на работниот простор 7 - switch_workspace_4: Префрлете се на работниот простор 4 - focus_left: Фокусот лево - switch_workspace_0: Префрлете се на работниот простор 0 - send_to_workspace_4: Испратете на работниот простор 4 - focus_latest: Фокусирајте се најновите - switch_workspace_6: Префрлете се на работниот простор 6 - send_to_workspace_7: Испратете на работниот простор 7 - send_to_workspace_9: Испратете на работниот простор 9 - restore_sizes: Врати големини - switch_workspace_8: Префрлете се на работниот простор 8 - move_to_workspace_3: Преместете се на работниот простор 3 - decrease_width: Намалување на ширината - move_to_workspace_5: Преместете се во работниот простор 5 - move_to_workspace_4: Преместете се на работниот простор 4 - move_to_workspace_9: Преместете се на работниот простор 9 - switch_workspace_3: Префрлете се на работниот простор 3 - enable_tooltip: >- - Оневозможете ако ги имплементирате вашите сопствени кратенки со користење на - API на Core Seelen - enable: Овозможете интегрирани кратенки (AHK) -inProgress: Во тек... -delete: Избриши -cancel: Откажи -loading: Вчитување ... -quit: Откажете се -save: Зачувај -open: Отворено +sides: + left: Лево + top: Врв + bottom: Дно + right: Десно +header: + labels: + seelen_bar: Фенси лента со алатки + developer: Развивач + shortcuts: Кратенки + general: Општо + info: Информации + seelen_wm: Менаџер на прозорци + seelen_weg: Док/лента со задачи + monitors: Монитори + specific_apps: Специфични апликации +start: + title: Добредојдовте! + message_accent: Оптимизирајте ја вашата продуктивност со стил! + message: >- + Добредојдовте во Seelen UI, крајната околина за десктоп со вграден менаџер + за прозорци за Windows за подобрување на вашето искуство со Windows 11! + Истражете нова ера на ефикасност и мултитаскинг со нашиот интуитивен + интерфејс и напредни карактеристики. +general: + theme: + tags: Тагови + enabled: Овозможени теми + author: Автор + added: Веќе додадена тема + label: Информации за теми + description: Опис + placeholder: Изберете тема + add: Додадете тема + selected: Избран + available: Достапно + language: Јазик + startup: Стартувам на стартување? + icon_pack: + label: Икони пакувања + accent_color: Боја на акцент +toolbar: + placeholder: + author: Автор + select: Структура на лентата со алатки + description: Опис + height: Висина + enable: Овозможете фенси лента со алатки +wm: + border: + width: Ширина на границата + offset: Офсет за граница + enable: Овозможете ја границата на прозорецот + enable: Овозможи менаџер на прозорци + workspace_padding: Подлога за работни места + resize_delta: Променете ја големината на Делта (%) + disabled_windows10: Менаџерот на прозорецот не е достапен за Windows 10. + workspace_offset: Работни места за неутрализирање (маргини) + space_between_containers: Простор помеѓу контејнери + layout: Распоред + description: Опис + author: Автор +weg: + items: + size: Големина на артикалот + label: Предмети + zoom_size: Зумирана големина (се користи за теми) + visible_separators: Видливи сепаратори + gap: Простор помеѓу предмети + width: Ширина + dock_side: Страна на пристаништето + enable: Овозможете пристаниште/лента со задачи + auto_hide: Автоматско скриј + gap: Јаз + margin: Маргина + padding: Подлога + label: Док/лента со задачи +devtools: + load: Оптоварување + custom_config_file: Вчитајте ја датотеката за прилагодена конфигурација + data_folder: Папка со податоци + install_folder: Папка за инсталација + settings_file: Датотека за поставки + enable: Овозможете алатки за развивачи + app_folders: Папки со апликации +apps_configurations: + app: + options: + float: Плови + unmanage: Unmanage + pinned: Закачен + force: Управување со сила + title_edit: Уредување {{име}} + ok_edit: Ажурирање + category_placeholder: Ништо + name: Име + workspace_placeholder: Ништо + workspace: Работен простор + ok_create: Креирај + monitor_placeholder: Ништо + bindings: Обврзувачки (Забележете дека се потребни и двете опции) + title_readonly: Гледање {{име}} + monitor: Монитор + options_label: Дополнителни опции + ok_readonly: Уреди како ново + category: Категорија + title_create: Креирање {{име}} + identifier: + remove: Избриши блок + matching_strategy: Стратегија за појавување + or: Или + id: Идентификатор + kind: Идентификувајте од + and: И + negation: Негираат совпаѓање + add_block: Додадете блок + delete: Избриши + export: Извоз + swap: Разменување + search: Пребарување + bundled_msg: >- + Овие конфигурации во комплет не се уредни и се дизајнирани да ви обезбедат + најдобро искуство без прилагодување. Тие автоматски ги конфигурираат + најчестите апликации за вас. + import: Увоз + confirm_delete: Дали сте сигурни дека сакате да ја избришете оваа конфигурација/а? + new: Ново + bundled_title: Конфигурирана апликација во комплет со Селен + confirm_delete_title: Потврдете го Избриши +extras: + relaunch: Повторно започнување + links: Официјални врски + exit: Откажете/излез + version: Верзија + github: Github + discord: Раздор +shortcuts: + labels: + move_to_workspace_2: Преместете се на работниот простор 2 + move_to_workspace_6: Преместете се на работниот простор 6 + switch_workspace_2: Префрлете се на работниот простор 2 + send_to_workspace_3: Испратете на работниот простор 3 + switch_workspace_5: Префрлете се на работниот простор 5 + move_to_workspace_7: Преместете се на работниот простор 7 + reserve_left: Резерва лево + focus_bottom: Фокус дното + move_to_workspace_1: Преместете се на работниот простор 1 + reserve_float: Резерва плови + send_to_workspace_2: Испратете на работниот простор 2 + focus_top: Фокус врвот + switch_workspace_1: Префрлете се на работниот простор 1 + send_to_workspace_0: Испратете на работниот простор 0 + reserve_stack: Резервен магацин + increase_height: Зголемете ја висината + switch_workspace_9: Префрлете се на работниот простор 9 + decrease_height: Намалување на висината + increase_width: Зголемете ја ширината + send_to_workspace_6: Испратете на работниот простор 6 + focus_right: Фокусирајте се десно + reserve_top: Резервен врв + reserve_right: Резервирајте десно + send_to_workspace_8: Испратете на работниот простор 8 + send_to_workspace_5: Испратете на работниот простор 5 + move_to_workspace_0: Преместете се на работниот простор 0 + move_to_workspace_8: Преместете се на работниот простор 8 + reserve_bottom: Резервно дно + send_to_workspace_1: Испратете на работниот простор 1 + switch_workspace_7: Префрлете се на работниот простор 7 + switch_workspace_4: Префрлете се на работниот простор 4 + focus_left: Фокусот лево + switch_workspace_0: Префрлете се на работниот простор 0 + send_to_workspace_4: Испратете на работниот простор 4 + focus_latest: Фокусирајте се најновите + switch_workspace_6: Префрлете се на работниот простор 6 + send_to_workspace_7: Испратете на работниот простор 7 + send_to_workspace_9: Испратете на работниот простор 9 + restore_sizes: Врати големини + switch_workspace_8: Префрлете се на работниот простор 8 + move_to_workspace_3: Преместете се на работниот простор 3 + decrease_width: Намалување на ширината + move_to_workspace_5: Преместете се во работниот простор 5 + move_to_workspace_4: Преместете се на работниот простор 4 + move_to_workspace_9: Преместете се на работниот простор 9 + switch_workspace_3: Префрлете се на работниот простор 3 + enable_tooltip: >- + Оневозможете ако ги имплементирате вашите сопствени кратенки со користење на + API на Core Seelen + enable: Овозможете интегрирани кратенки (AHK) +inProgress: Во тек... +delete: Избриши +cancel: Откажи +loading: Вчитување ... +quit: Откажете се +save: Зачувај +open: Отворено diff --git a/src/apps/settings/i18n/translations/mn.yml b/src/apps/settings/i18n/translations/mn.yml index 330d60b5..d83705a4 100644 --- a/src/apps/settings/i18n/translations/mn.yml +++ b/src/apps/settings/i18n/translations/mn.yml @@ -1,192 +1,192 @@ -sides: - top: Таг - right: Зөв байх - left: Зүүн - bottom: Ероол -header: - labels: - seelen_bar: Уран зөгнөлийн багаж самбар - shortcuts: Хэв хаягдал - general: Жанжин - specific_apps: ТУСГАЙ АЖИЛЛАГАА - developer: Хөгжчин - seelen_weg: Док / Taskbar - seelen_wm: Цонхны менежер - monitors: Хэлэлт авагч - info: Мэдээлэл -start: - message_accent: Өөрийнхөө бүтээмжийг загвараар оновчтой болгох! - message: >- - Seelen Ui, Windows 11-ийг сайжруулахын тулд Windows 11-ийг сайжруулахын тулд - хамгийн дээд талын цонхны менежертэй морилно уу. Шинэ ERA-ийг судлах, олон - тооны интерфэйстэй, дэвшилтэт шинж чанаруудтай олон тооны үр ашийг судлах. - title: Сайтар хүлээх,! -general: - theme: - label: Сэдвийн мэдээлэл - tags: Бичиглэл байна - author: Зохиолч - add: Сэдэв нэмэх - description: Тодорхойлолт / төрөл анги - enabled: Идэвхжүүлсэн сэдэв - placeholder: Сонгуулыг сонгоно уу - added: Сэдэв аль хэдийн нэмэгдсэн - available: Бэлнээр байгаа - selected: Сүл -ийг хийсэн - language: Хэл - startup: Эхлэх үед гүйх үү? - icon_pack: - label: Icon багц - accent_color: Эргүүлэг -toolbar: - placeholder: - description: Тодорхойлолт / төрөл анги - select: Хэрэгслийн бүтэц - author: Зохиолч - enable: Ширээний хэрэгслийн самбарыг идэвхжүүлэх - height: Өндөрлөг -wm: - border: - offset: Хилийн офсет - width: Хилийн өргөн - enable: Цонхны хилийг идэвхжүүлэх - workspace_offset: Ажлын талбар нь офсет (Margins) - space_between_containers: Савны хоорондох зай - layout: Төлөвлөгөө - description: Тодорхойлолт / төрөл анги - workspace_padding: Ажлын талбарууд - author: Зохиолч - enable: Цонх менежерийг идэвхжүүлэх - resize_delta: Дельтааг өөрчлөх (%) - disabled_windows10: Цонхны менежер Windows 10-д байхгүй байна. -weg: - items: - label: Зүйл - gap: Зүйлийн хоорондох зай - zoom_size: Томруулсан хэмжээ (сэдэвт ашигладаг) - size: Зүйлийн хэмжээ - visible_separators: Харагдах тусгаарлагч - enable: Док / Taskbar-г идэвхжүүлэх - dock_side: Дохын тухай - label: Док / Taskbar - width: Өргөн - padding: Дэвсгэр - margin: Саруулган өвс - gap: Цонх - auto_hide: Авто гүнд -devtools: - settings_file: Тохиргооын нэр - enable: Хөгжүүлэгч хэрэгслийг идэвхжүүлэх - app_folders: Апп хавтас - install_folder: Суулгалах хүрээ - custom_config_file: Custom Compigh файлыг ачаалах - data_folder: Д код хавтас - load: Ачих -apps_configurations: - app: - options: - pinned: Ан хатуу - float: Нисэн өнгөрөх - force: Хүч удирдах - unmanage: Нээлттэй - category: Зэрэглэл - title_readonly: Үзэх {{нэр}} - bindings: Батлах (Анхааруулга хоёулаа сонголтыг оруулах шаардлагатай) - category_placeholder: Хэн ч - workspace: Ауун тал - ok_edit: Шинэчлэх - monitor: Хянах - workspace_placeholder: Хэн ч - title_edit: '{{Нэр}}}}' - ok_create: Шуүгиан дэгдээх - options_label: Нэмий сонголт - ok_readonly: Шинэ болгон засах - name: Нэр - monitor_placeholder: Хэн ч - title_create: Үүсгэх {{нэр}}} - identifier: - id: Өмнө тайлбар - or: ЭСВЭЛ - negation: Тохирохыг үгүйсгэх - kind: Тодорхойлох - add_block: Нид нэмнэ - and: Ба - matching_strategy: Тохирох стратеги - remove: Блок устгах - delete: Эдгээх - swap: Түлхэх - bundled_title: App Config Selen-тай багцлав - confirm_delete_title: Устгахыг баталгаажуулна уу - new: Шинэ - import: Импортлох - confirm_delete: Та энэ тохиргоог устгахыг хүсч байна уу? - bundled_msg: >- - Эдгээр багцын тохиргоо нь засварлах боломжгүй бөгөөд танд тохируулга - хийхгүйгээр хамгийн сайн туршлага өгөх зорилготой юм. Тэд таны хувьд хамгийн - түгээмэл програмуудыг автоматаар тохируулдаг. - search: Эрэл хайгуул хийх - export: Гадаадад гаргах -extras: - github: Github - relaunch: OradAUN - exit: Гарах / гарах - links: Албан ёсны холбоос - version: Таамаглал - discord: Холор -shortcuts: - labels: - switch_workspace_2: Ажлын талбарт 2 руу шилжих - reserve_top: Нэр гаргах - move_to_workspace_9: Ажлын талбар руу шилжих 9 - decrease_height: Өндөр хэмжээг - reserve_float: Нөөцийн хөвөх - switch_workspace_8: Ажлын талбар руу шилжих 8 - send_to_workspace_7: Ажлын талбар руу илгээх 7 - reserve_right: Нөөцийг зөв дарна уу - send_to_workspace_5: Ажлын талбар руу илгээх 5 - focus_latest: Фандик хамгийн сүүлийн үеийн - send_to_workspace_2: Ажлын талбарт 2 руу илгээнэ үү - focus_top: Додуулах нь эсрэг - increase_width: Өргөнийг нэмэгдүүлэх - focus_bottom: Дээр төвлөрүү - switch_workspace_6: Ажлын талбарт шилжих 6 - move_to_workspace_1: Ажлын талбар руу шилжих 1 - reserve_left: Зуух Зүүн - switch_workspace_1: Ажлын талбарт шилжих 1 - switch_workspace_5: Ажлын талбар руу шилжих 5 - move_to_workspace_8: Ажлын талбар руу шилжих 8 - focus_right: Домог - decrease_width: Гарын хойш хөгжих - increase_height: Дээд хэмжээг нэмэгдүүлэх - reserve_bottom: Нөөцийг нөөцлөх - move_to_workspace_6: Ажлын талбар руу шилжих 6 - switch_workspace_0: Ажлын талбар руу шилжих 0 - move_to_workspace_7: Ажлын талбар руу шилжих 7 - send_to_workspace_4: Ажлын талбарт илгээх 4 - move_to_workspace_3: Ажлын талбар руу шилжих 3 - switch_workspace_7: Ажлын талбарт шилжих 7 - reserve_stack: Дурсамж авах - move_to_workspace_4: Ажлын талбарт шилжих 4 - move_to_workspace_2: Ажлын талбар руу шилжих 2 - switch_workspace_4: Ажлын талбар 4 руу шилжих - send_to_workspace_6: Workpace 6 руу илгээнэ үү - move_to_workspace_0: Ажлын талбар руу шилжих 0 - switch_workspace_3: Ажлын талбар руу шилжих 3 - send_to_workspace_0: Ажлын талбарт 0 руу илгээнэ үү - send_to_workspace_8: Ажлын талбар руу илгээх 8 - send_to_workspace_1: Ажлын талбар руу илгээх 1 - focus_left: Зүүн талд байна - send_to_workspace_3: Ажлын талбар руу илгээх 3 - move_to_workspace_5: Ажлын талбар руу шилжих 5 - restore_sizes: Хэмжээг сэргээх - switch_workspace_9: Ажлын талбарт шилжих 9 - send_to_workspace_9: Ажлын талбарт 9-р илгээнэ үү - enable_tooltip: Seelen Core Api ашиглан өөрийн товчлолуудыг хэрэгжүүлэхийг идэвхгүй болго - enable: Нэгдсэн товчлолыг идэвхжүүлэх (AHK) -inProgress: Явагдаж байна ... -delete: Эдгээх -loading: Ачаалах ... -cancel: Цуаах -quit: Орхих -open: Нээлттэй -save: Аврах +sides: + top: Таг + right: Зөв байх + left: Зүүн + bottom: Ероол +header: + labels: + seelen_bar: Уран зөгнөлийн багаж самбар + shortcuts: Хэв хаягдал + general: Жанжин + specific_apps: ТУСГАЙ АЖИЛЛАГАА + developer: Хөгжчин + seelen_weg: Док / Taskbar + seelen_wm: Цонхны менежер + monitors: Хэлэлт авагч + info: Мэдээлэл +start: + message_accent: Өөрийнхөө бүтээмжийг загвараар оновчтой болгох! + message: >- + Seelen Ui, Windows 11-ийг сайжруулахын тулд Windows 11-ийг сайжруулахын тулд + хамгийн дээд талын цонхны менежертэй морилно уу. Шинэ ERA-ийг судлах, олон + тооны интерфэйстэй, дэвшилтэт шинж чанаруудтай олон тооны үр ашийг судлах. + title: Сайтар хүлээх,! +general: + theme: + label: Сэдвийн мэдээлэл + tags: Бичиглэл байна + author: Зохиолч + add: Сэдэв нэмэх + description: Тодорхойлолт / төрөл анги + enabled: Идэвхжүүлсэн сэдэв + placeholder: Сонгуулыг сонгоно уу + added: Сэдэв аль хэдийн нэмэгдсэн + available: Бэлнээр байгаа + selected: Сүл -ийг хийсэн + language: Хэл + startup: Эхлэх үед гүйх үү? + icon_pack: + label: Icon багц + accent_color: Эргүүлэг +toolbar: + placeholder: + description: Тодорхойлолт / төрөл анги + select: Хэрэгслийн бүтэц + author: Зохиолч + enable: Ширээний хэрэгслийн самбарыг идэвхжүүлэх + height: Өндөрлөг +wm: + border: + offset: Хилийн офсет + width: Хилийн өргөн + enable: Цонхны хилийг идэвхжүүлэх + workspace_offset: Ажлын талбар нь офсет (Margins) + space_between_containers: Савны хоорондох зай + layout: Төлөвлөгөө + description: Тодорхойлолт / төрөл анги + workspace_padding: Ажлын талбарууд + author: Зохиолч + enable: Цонх менежерийг идэвхжүүлэх + resize_delta: Дельтааг өөрчлөх (%) + disabled_windows10: Цонхны менежер Windows 10-д байхгүй байна. +weg: + items: + label: Зүйл + gap: Зүйлийн хоорондох зай + zoom_size: Томруулсан хэмжээ (сэдэвт ашигладаг) + size: Зүйлийн хэмжээ + visible_separators: Харагдах тусгаарлагч + enable: Док / Taskbar-г идэвхжүүлэх + dock_side: Дохын тухай + label: Док / Taskbar + width: Өргөн + padding: Дэвсгэр + margin: Саруулган өвс + gap: Цонх + auto_hide: Авто гүнд +devtools: + settings_file: Тохиргооын нэр + enable: Хөгжүүлэгч хэрэгслийг идэвхжүүлэх + app_folders: Апп хавтас + install_folder: Суулгалах хүрээ + custom_config_file: Custom Compigh файлыг ачаалах + data_folder: Д код хавтас + load: Ачих +apps_configurations: + app: + options: + pinned: Ан хатуу + float: Нисэн өнгөрөх + force: Хүч удирдах + unmanage: Нээлттэй + category: Зэрэглэл + title_readonly: Үзэх {{нэр}} + bindings: Батлах (Анхааруулга хоёулаа сонголтыг оруулах шаардлагатай) + category_placeholder: Хэн ч + workspace: Ауун тал + ok_edit: Шинэчлэх + monitor: Хянах + workspace_placeholder: Хэн ч + title_edit: '{{Нэр}}}}' + ok_create: Шуүгиан дэгдээх + options_label: Нэмий сонголт + ok_readonly: Шинэ болгон засах + name: Нэр + monitor_placeholder: Хэн ч + title_create: Үүсгэх {{нэр}}} + identifier: + id: Өмнө тайлбар + or: ЭСВЭЛ + negation: Тохирохыг үгүйсгэх + kind: Тодорхойлох + add_block: Нид нэмнэ + and: Ба + matching_strategy: Тохирох стратеги + remove: Блок устгах + delete: Эдгээх + swap: Түлхэх + bundled_title: App Config Selen-тай багцлав + confirm_delete_title: Устгахыг баталгаажуулна уу + new: Шинэ + import: Импортлох + confirm_delete: Та энэ тохиргоог устгахыг хүсч байна уу? + bundled_msg: >- + Эдгээр багцын тохиргоо нь засварлах боломжгүй бөгөөд танд тохируулга + хийхгүйгээр хамгийн сайн туршлага өгөх зорилготой юм. Тэд таны хувьд хамгийн + түгээмэл програмуудыг автоматаар тохируулдаг. + search: Эрэл хайгуул хийх + export: Гадаадад гаргах +extras: + github: Github + relaunch: OradAUN + exit: Гарах / гарах + links: Албан ёсны холбоос + version: Таамаглал + discord: Холор +shortcuts: + labels: + switch_workspace_2: Ажлын талбарт 2 руу шилжих + reserve_top: Нэр гаргах + move_to_workspace_9: Ажлын талбар руу шилжих 9 + decrease_height: Өндөр хэмжээг + reserve_float: Нөөцийн хөвөх + switch_workspace_8: Ажлын талбар руу шилжих 8 + send_to_workspace_7: Ажлын талбар руу илгээх 7 + reserve_right: Нөөцийг зөв дарна уу + send_to_workspace_5: Ажлын талбар руу илгээх 5 + focus_latest: Фандик хамгийн сүүлийн үеийн + send_to_workspace_2: Ажлын талбарт 2 руу илгээнэ үү + focus_top: Додуулах нь эсрэг + increase_width: Өргөнийг нэмэгдүүлэх + focus_bottom: Дээр төвлөрүү + switch_workspace_6: Ажлын талбарт шилжих 6 + move_to_workspace_1: Ажлын талбар руу шилжих 1 + reserve_left: Зуух Зүүн + switch_workspace_1: Ажлын талбарт шилжих 1 + switch_workspace_5: Ажлын талбар руу шилжих 5 + move_to_workspace_8: Ажлын талбар руу шилжих 8 + focus_right: Домог + decrease_width: Гарын хойш хөгжих + increase_height: Дээд хэмжээг нэмэгдүүлэх + reserve_bottom: Нөөцийг нөөцлөх + move_to_workspace_6: Ажлын талбар руу шилжих 6 + switch_workspace_0: Ажлын талбар руу шилжих 0 + move_to_workspace_7: Ажлын талбар руу шилжих 7 + send_to_workspace_4: Ажлын талбарт илгээх 4 + move_to_workspace_3: Ажлын талбар руу шилжих 3 + switch_workspace_7: Ажлын талбарт шилжих 7 + reserve_stack: Дурсамж авах + move_to_workspace_4: Ажлын талбарт шилжих 4 + move_to_workspace_2: Ажлын талбар руу шилжих 2 + switch_workspace_4: Ажлын талбар 4 руу шилжих + send_to_workspace_6: Workpace 6 руу илгээнэ үү + move_to_workspace_0: Ажлын талбар руу шилжих 0 + switch_workspace_3: Ажлын талбар руу шилжих 3 + send_to_workspace_0: Ажлын талбарт 0 руу илгээнэ үү + send_to_workspace_8: Ажлын талбар руу илгээх 8 + send_to_workspace_1: Ажлын талбар руу илгээх 1 + focus_left: Зүүн талд байна + send_to_workspace_3: Ажлын талбар руу илгээх 3 + move_to_workspace_5: Ажлын талбар руу шилжих 5 + restore_sizes: Хэмжээг сэргээх + switch_workspace_9: Ажлын талбарт шилжих 9 + send_to_workspace_9: Ажлын талбарт 9-р илгээнэ үү + enable_tooltip: Seelen Core Api ашиглан өөрийн товчлолуудыг хэрэгжүүлэхийг идэвхгүй болго + enable: Нэгдсэн товчлолыг идэвхжүүлэх (AHK) +inProgress: Явагдаж байна ... +delete: Эдгээх +loading: Ачаалах ... +cancel: Цуаах +quit: Орхих +open: Нээлттэй +save: Аврах diff --git a/src/apps/settings/i18n/translations/ms.yml b/src/apps/settings/i18n/translations/ms.yml index 4c38339d..381e211c 100644 --- a/src/apps/settings/i18n/translations/ms.yml +++ b/src/apps/settings/i18n/translations/ms.yml @@ -1,195 +1,195 @@ -sides: - left: Dibiarkan - bottom: Bawah - right: Betul - top: Atas -header: - labels: - specific_apps: Aplikasi khusus - seelen_wm: Pengurus tetingkap - info: Maklumat - seelen_weg: Dock/Taskbar - developer: Pemaju - general: Umum - seelen_bar: Bar alat mewah - monitors: Monitor - shortcuts: Pintasan -start: - title: Selamat datang! - message_accent: Mengoptimumkan produktiviti anda dengan gaya! - message: >- - Selamat datang ke Seelen UI, persekitaran desktop muktamad dengan Pengurus - Windows Tiling yang diperbadankan untuk meningkatkan pengalaman Windows 11 - anda! Terokai era kecekapan baru dan multitasking dengan antara muka - intuitif dan ciri canggih kami. -general: - theme: - description: Penerangan - add: Tambah tema - placeholder: Pilih tema - author: Pengarang - added: Tema sudah ditambah - tags: Tag - enabled: Tema yang diaktifkan - label: Maklumat tema - available: Terdapat - selected: Dipilih - startup: Jalankan permulaan? - language: Bahasa - icon_pack: - label: Pek ikon - accent_color: Warna aksen -toolbar: - placeholder: - description: Penerangan - author: Pengarang - select: Struktur bar alat - enable: Dayakan bar alat mewah - height: Ketinggian -wm: - border: - enable: Dayakan sempadan tetingkap - offset: Mengimbangi sempadan - width: Lebar sempadan - enable: Dayakan Pengurus Tetingkap - layout: Susun atur - description: Penerangan - disabled_windows10: Pengurus Window tidak tersedia untuk Windows 10. - space_between_containers: Ruang antara bekas - workspace_offset: Ruang Kerja Offset (margin) - resize_delta: Saiz semula delta (%) - author: Pengarang - workspace_padding: Padding ruang kerja -weg: - items: - zoom_size: Saiz zum (digunakan untuk tema) - size: Saiz item - gap: Ruang antara item - label: Item - visible_separators: Pemisah yang kelihatan - enable: Dayakan Dock/Taskbar - margin: Margin - padding: Padding - width: Lebar - gap: Jurang - label: Dock/Taskbar - auto_hide: Menyembunyikan auto - dock_side: Sebelah dok -devtools: - load: Beban - data_folder: Folder Data - settings_file: Fail tetapan - app_folders: Folder App - enable: Dayakan alat pemaju - custom_config_file: Muatkan fail konfigurasi tersuai - install_folder: Folder pemasangan -apps_configurations: - app: - options: - force: Daya mengurus - float: Terapung - unmanage: Unmanage - pinned: Disematkan - title_edit: Editting {{name}} - category: Kategori - ok_edit: Kemas kini - title_readonly: Melihat {{name}} - name: Nama - bindings: Mengikat (perhatikan kedua -dua pilihan diperlukan) - workspace: Ruang kerja - ok_readonly: Edit sebagai baru - options_label: Pilihan tambahan - workspace_placeholder: Tiada - monitor_placeholder: Tiada - title_create: Menciptakan {{name}} - ok_create: Buat - category_placeholder: Tiada - monitor: Memantau - identifier: - matching_strategy: Strategi yang sepadan - and: Dan - add_block: Tambah blok - negation: Menafikan padanan - kind: Mengenal pasti oleh - or: Atau - remove: Padam blok - id: Pengenalpastian - new: Baru - export: Eksport - swap: Bertukar - import: Import - bundled_title: Konfigurasi aplikasi dibundel dengan seelen - confirm_delete: Adakah anda pasti mahu memadamkan konfigurasi ini? - confirm_delete_title: Sahkan padam - search: Cari - delete: Padam - bundled_msg: >- - Konfigurasi yang dibundel ini tidak dapat diedit dan direka untuk memberi - anda pengalaman terbaik tanpa penyesuaian. Mereka secara automatik - mengkonfigurasi aplikasi yang paling biasa untuk anda. -extras: - links: Pautan Rasmi - github: Github - relaunch: Pelancaran semula - version: Versi - discord: Perselisihan - exit: Berhenti/keluar -shortcuts: - labels: - send_to_workspace_4: Hantar ke Ruang Kerja 4 - move_to_workspace_2: Pindah ke Ruang Kerja 2 - reserve_stack: Timbunan simpanan - decrease_height: Mengurangkan ketinggian - send_to_workspace_6: Hantar ke Ruang Kerja 6 - focus_left: Fokus kiri - send_to_workspace_8: Hantar ke Ruang Kerja 8 - restore_sizes: Pulihkan saiz - switch_workspace_4: Beralih ke ruang kerja 4 - move_to_workspace_5: Pindah ke Ruang Kerja 5 - switch_workspace_5: Beralih ke ruang kerja 5 - increase_width: Meningkatkan lebar - move_to_workspace_7: Pindah ke Ruang Kerja 7 - focus_top: Fokus atas - focus_bottom: Fokus bawah - switch_workspace_9: Beralih ke ruang kerja 9 - focus_right: Fokus betul - send_to_workspace_1: Hantar ke Ruang Kerja 1 - move_to_workspace_9: Pindah ke Ruang Kerja 9 - reserve_right: Rizab betul - switch_workspace_8: Beralih ke ruang kerja 8 - focus_latest: Fokus terkini - move_to_workspace_8: Pindah ke Ruang Kerja 8 - send_to_workspace_9: Hantar ke Ruang Kerja 9 - send_to_workspace_2: Hantar ke Ruang Kerja 2 - send_to_workspace_5: Hantar ke Ruang Kerja 5 - switch_workspace_1: Beralih ke ruang kerja 1 - decrease_width: Mengurangkan lebar - reserve_bottom: Bawah simpanan - send_to_workspace_0: Hantar ke Ruang Kerja 0 - switch_workspace_3: Beralih ke ruang kerja 3 - move_to_workspace_3: Pindah ke Ruang Kerja 3 - move_to_workspace_0: Pindah ke Ruang Kerja 0 - switch_workspace_6: Beralih ke ruang kerja 6 - move_to_workspace_4: Pindah ke Ruang Kerja 4 - move_to_workspace_6: Pindah ke Ruang Kerja 6 - increase_height: Meningkatkan ketinggian - switch_workspace_2: Beralih ke ruang kerja 2 - switch_workspace_0: Beralih ke ruang kerja 0 - reserve_float: Rizab terapung - reserve_top: Rizab atas - reserve_left: Rizab kiri - switch_workspace_7: Tukar ke Ruang Kerja 7 - move_to_workspace_1: Pindah ke Ruang Kerja 1 - send_to_workspace_7: Hantar ke Ruang Kerja 7 - send_to_workspace_3: Hantar ke Ruang Kerja 3 - enable_tooltip: >- - Lumpuhkan jika anda akan melaksanakan pintasan anda sendiri menggunakan API - teras Seelen - enable: Dayakan Pintasan Bersepadu (AHK) -open: Buka -save: Simpan -quit: Berhenti -cancel: Batalkan -delete: Padam -inProgress: Dalam proses ... -loading: Memuatkan ... +sides: + left: Dibiarkan + bottom: Bawah + right: Betul + top: Atas +header: + labels: + specific_apps: Aplikasi khusus + seelen_wm: Pengurus tetingkap + info: Maklumat + seelen_weg: Dock/Taskbar + developer: Pemaju + general: Umum + seelen_bar: Bar alat mewah + monitors: Monitor + shortcuts: Pintasan +start: + title: Selamat datang! + message_accent: Mengoptimumkan produktiviti anda dengan gaya! + message: >- + Selamat datang ke Seelen UI, persekitaran desktop muktamad dengan Pengurus + Windows Tiling yang diperbadankan untuk meningkatkan pengalaman Windows 11 + anda! Terokai era kecekapan baru dan multitasking dengan antara muka + intuitif dan ciri canggih kami. +general: + theme: + description: Penerangan + add: Tambah tema + placeholder: Pilih tema + author: Pengarang + added: Tema sudah ditambah + tags: Tag + enabled: Tema yang diaktifkan + label: Maklumat tema + available: Terdapat + selected: Dipilih + startup: Jalankan permulaan? + language: Bahasa + icon_pack: + label: Pek ikon + accent_color: Warna aksen +toolbar: + placeholder: + description: Penerangan + author: Pengarang + select: Struktur bar alat + enable: Dayakan bar alat mewah + height: Ketinggian +wm: + border: + enable: Dayakan sempadan tetingkap + offset: Mengimbangi sempadan + width: Lebar sempadan + enable: Dayakan Pengurus Tetingkap + layout: Susun atur + description: Penerangan + disabled_windows10: Pengurus Window tidak tersedia untuk Windows 10. + space_between_containers: Ruang antara bekas + workspace_offset: Ruang Kerja Offset (margin) + resize_delta: Saiz semula delta (%) + author: Pengarang + workspace_padding: Padding ruang kerja +weg: + items: + zoom_size: Saiz zum (digunakan untuk tema) + size: Saiz item + gap: Ruang antara item + label: Item + visible_separators: Pemisah yang kelihatan + enable: Dayakan Dock/Taskbar + margin: Margin + padding: Padding + width: Lebar + gap: Jurang + label: Dock/Taskbar + auto_hide: Menyembunyikan auto + dock_side: Sebelah dok +devtools: + load: Beban + data_folder: Folder Data + settings_file: Fail tetapan + app_folders: Folder App + enable: Dayakan alat pemaju + custom_config_file: Muatkan fail konfigurasi tersuai + install_folder: Folder pemasangan +apps_configurations: + app: + options: + force: Daya mengurus + float: Terapung + unmanage: Unmanage + pinned: Disematkan + title_edit: Editting {{name}} + category: Kategori + ok_edit: Kemas kini + title_readonly: Melihat {{name}} + name: Nama + bindings: Mengikat (perhatikan kedua -dua pilihan diperlukan) + workspace: Ruang kerja + ok_readonly: Edit sebagai baru + options_label: Pilihan tambahan + workspace_placeholder: Tiada + monitor_placeholder: Tiada + title_create: Menciptakan {{name}} + ok_create: Buat + category_placeholder: Tiada + monitor: Memantau + identifier: + matching_strategy: Strategi yang sepadan + and: Dan + add_block: Tambah blok + negation: Menafikan padanan + kind: Mengenal pasti oleh + or: Atau + remove: Padam blok + id: Pengenalpastian + new: Baru + export: Eksport + swap: Bertukar + import: Import + bundled_title: Konfigurasi aplikasi dibundel dengan seelen + confirm_delete: Adakah anda pasti mahu memadamkan konfigurasi ini? + confirm_delete_title: Sahkan padam + search: Cari + delete: Padam + bundled_msg: >- + Konfigurasi yang dibundel ini tidak dapat diedit dan direka untuk memberi + anda pengalaman terbaik tanpa penyesuaian. Mereka secara automatik + mengkonfigurasi aplikasi yang paling biasa untuk anda. +extras: + links: Pautan Rasmi + github: Github + relaunch: Pelancaran semula + version: Versi + discord: Perselisihan + exit: Berhenti/keluar +shortcuts: + labels: + send_to_workspace_4: Hantar ke Ruang Kerja 4 + move_to_workspace_2: Pindah ke Ruang Kerja 2 + reserve_stack: Timbunan simpanan + decrease_height: Mengurangkan ketinggian + send_to_workspace_6: Hantar ke Ruang Kerja 6 + focus_left: Fokus kiri + send_to_workspace_8: Hantar ke Ruang Kerja 8 + restore_sizes: Pulihkan saiz + switch_workspace_4: Beralih ke ruang kerja 4 + move_to_workspace_5: Pindah ke Ruang Kerja 5 + switch_workspace_5: Beralih ke ruang kerja 5 + increase_width: Meningkatkan lebar + move_to_workspace_7: Pindah ke Ruang Kerja 7 + focus_top: Fokus atas + focus_bottom: Fokus bawah + switch_workspace_9: Beralih ke ruang kerja 9 + focus_right: Fokus betul + send_to_workspace_1: Hantar ke Ruang Kerja 1 + move_to_workspace_9: Pindah ke Ruang Kerja 9 + reserve_right: Rizab betul + switch_workspace_8: Beralih ke ruang kerja 8 + focus_latest: Fokus terkini + move_to_workspace_8: Pindah ke Ruang Kerja 8 + send_to_workspace_9: Hantar ke Ruang Kerja 9 + send_to_workspace_2: Hantar ke Ruang Kerja 2 + send_to_workspace_5: Hantar ke Ruang Kerja 5 + switch_workspace_1: Beralih ke ruang kerja 1 + decrease_width: Mengurangkan lebar + reserve_bottom: Bawah simpanan + send_to_workspace_0: Hantar ke Ruang Kerja 0 + switch_workspace_3: Beralih ke ruang kerja 3 + move_to_workspace_3: Pindah ke Ruang Kerja 3 + move_to_workspace_0: Pindah ke Ruang Kerja 0 + switch_workspace_6: Beralih ke ruang kerja 6 + move_to_workspace_4: Pindah ke Ruang Kerja 4 + move_to_workspace_6: Pindah ke Ruang Kerja 6 + increase_height: Meningkatkan ketinggian + switch_workspace_2: Beralih ke ruang kerja 2 + switch_workspace_0: Beralih ke ruang kerja 0 + reserve_float: Rizab terapung + reserve_top: Rizab atas + reserve_left: Rizab kiri + switch_workspace_7: Tukar ke Ruang Kerja 7 + move_to_workspace_1: Pindah ke Ruang Kerja 1 + send_to_workspace_7: Hantar ke Ruang Kerja 7 + send_to_workspace_3: Hantar ke Ruang Kerja 3 + enable_tooltip: >- + Lumpuhkan jika anda akan melaksanakan pintasan anda sendiri menggunakan API + teras Seelen + enable: Dayakan Pintasan Bersepadu (AHK) +open: Buka +save: Simpan +quit: Berhenti +cancel: Batalkan +delete: Padam +inProgress: Dalam proses ... +loading: Memuatkan ... diff --git a/src/apps/settings/i18n/translations/mt.yml b/src/apps/settings/i18n/translations/mt.yml index ace931c4..df72ac2d 100644 --- a/src/apps/settings/i18n/translations/mt.yml +++ b/src/apps/settings/i18n/translations/mt.yml @@ -1,193 +1,193 @@ -sides: - bottom: Qiegħ - left: Xellug - top: Quċċata - right: Dritt -header: - labels: - info: Informazzjoni - general: Ġenerali - seelen_wm: Window Manager - shortcuts: Shortcuts - seelen_bar: Toolbar tal-Fancy - specific_apps: Applikazzjonijiet speċifiċi - seelen_weg: Dock / Taskbar - developer: Żviluppatur - monitors: Monitors -start: - title: Merħba! - message: >- - Merħba għal Seelen UI, l-ambjent tad-desktop aħħari b'maniġġ tal-Windows - tal-madum inkorporat biex itejjeb l-esperjenza tal-Windows 11 tiegħek! - Esplora era ġdida ta 'effiċjenza u multitasking bl-interface intuwittiv - tagħna u karatteristiċi avvanzati. - message_accent: Ottimizza l-produttività tiegħek bl-istil! -general: - theme: - add: Żid it-tema - placeholder: Agħżel Tema - label: Informazzjoni dwar it-tema - description: Deskrizzjoni - enabled: Temi ppermettiet - author: Awtur - added: Tema diġà miżjuda - tags: Tags - selected: Magħżula - available: Disponibbli - language: Lingwa - startup: Mexxi fuq l-istartjar? - icon_pack: - label: Pakketti tal-ikona - accent_color: Kulur tal-aċċent -toolbar: - placeholder: - author: Awtur - description: Deskrizzjoni - select: Struttura tal-Toolbar - height: Għoli - enable: Jippermetti toolbar tal-fancy -wm: - border: - enable: Ippermetti l-fruntiera tat-tieqa - width: Wisa 'tal-fruntiera - offset: Offset tal-fruntiera - description: Deskrizzjoni - enable: Ippermetti l-maniġer tat-twieqi - layout: Tqassim - resize_delta: Daqs mill-ġdid Delta (%) - disabled_windows10: Il-maniġer tat-twieqi mhux disponibbli għall-Windows 10. - author: Awtur - workspace_offset: Spazji tax-Xogħol Offset (Marġini) - space_between_containers: Spazju bejn il-kontenituri - workspace_padding: Padding tal-ispazji tax-xogħol -weg: - items: - visible_separators: Separaturi viżibbli - label: Oġġetti - gap: Spazju bejn l-oġġetti - size: Daqs tal-oġġett - zoom_size: Daqs miżjud (użat għat-temi) - dock_side: Naħa tal-baċir - label: Dock / Taskbar - width: Wisa ' - enable: Enable Dock / Taskbar - gap: Vojt - auto_hide: Auto Hide - padding: Ikkuttunar - margin: Marġni -devtools: - data_folder: Folder tad-dejta - install_folder: Folder tal-installazzjoni - load: Tagħbija - enable: Ippermetti għodod għall-iżviluppaturi - settings_file: Settings Fajl - custom_config_file: Tagħbija Fajl tal-Konfigurazzjoni Custom - app_folders: Folders tal-app -apps_configurations: - app: - options: - unmanage: Mhux immaniġġjat - float: Galleġġjant - pinned: Imqabbad - force: Forza ta 'tmexxija - title_readonly: Wiri {{isem}} - options_label: Għażliet żejda - monitor: Tissorvelja - ok_readonly: Editja bħala ġdida - name: Isem - category_placeholder: Xejn - ok_edit: Aġġornament - title_create: Ħolqien ta '{{isem}} - workspace_placeholder: Xejn - workspace: Spazju ta 'xogħol - ok_create: Oħloq - category: Kategorija - bindings: Torbot (innota ż-żewġ għażliet huma meħtieġa) - title_edit: Editting {{isem}} - monitor_placeholder: Xejn - identifier: - matching_strategy: Strateġija ta 'tqabbil - and: U - id: Identifikatur - add_block: Żid blokka - or: Jew - negation: Iċħad it-tqabbil - remove: Ħassar il-blokka - kind: Identifika minn - import: Importa - export: Esportazzjoni - confirm_delete: Int żgur li trid tħassar din il-konfigurazzjoni / i? - search: Tfittxija - bundled_msg: >- - Dawn il-konfigurazzjonijiet miġbura mhumiex editabbli u huma mfassla biex - jipprovdulek l-aħjar esperjenza mingħajr personalizzazzjoni. Huma - awtomatikament jikkonfiguraw l-aktar applikazzjonijiet komuni għalik. - bundled_title: App konfigurazzjoni miġbura ma 'seelen - confirm_delete_title: Ikkonferma Ħassar - delete: Ħassar - new: Ġdid - swap: Tpartit -extras: - relaunch: Tnedija mill-ġdid - github: Github - links: Rabtiet uffiċjali - exit: Nieqaf / ħruġ - version: Verżjoni - discord: Diskordja -shortcuts: - labels: - reserve_bottom: Riserva tal-qiegħ - reserve_right: Riserva dritt - focus_top: Focus top - reserve_top: Riserva ta 'fuq - switch_workspace_6: Aqleb għall-Ispazju tax-Xogħol 6 - move_to_workspace_0: Mexxi għall-Ispazju tax-Xogħol 0 - send_to_workspace_1: Ibgħat lill-Ispazju tax-Xogħol 1 - move_to_workspace_6: Mexxi għall-Ispazju tax-Xogħol 6 - switch_workspace_5: Aqleb għall-Ispazju tax-Xogħol 5 - move_to_workspace_9: Mexxi għall-Ispazju tax-Xogħol 9 - focus_bottom: Fokus tal-qiegħ - focus_left: Fokus xellug - send_to_workspace_6: Ibgħat lill-Ispazju tax-Xogħol 6 - switch_workspace_7: Aqleb għall-Ispazju tax-Xogħol 7 - send_to_workspace_5: Ibgħat lill-Ispazju tax-Xogħol 5 - move_to_workspace_1: Mexxi għall-Ispazju tax-Xogħol 1 - send_to_workspace_4: Ibgħat lill-Ispazju tax-Xogħol 4 - move_to_workspace_2: Mexxi għall-Ispazju tax-Xogħol 2 - decrease_width: Tnaqqis il-wisa ' - reserve_float: Riżerva float - reserve_stack: Riżerva munzell - reserve_left: Riserva xellug - switch_workspace_3: Aqleb għall-Ispazju tax-Xogħol 3 - increase_width: Iżżid il-wisa ' - move_to_workspace_4: Mexxi għall-Ispazju tax-Xogħol 4 - restore_sizes: Irrestawra d-daqsijiet - send_to_workspace_7: Ibgħat lill-Ispazju tax-Xogħol 7 - increase_height: Iżid l-għoli - switch_workspace_4: Aqleb għall-Ispazju tax-Xogħol 4 - send_to_workspace_2: Ibgħat lill-Ispazju tax-Xogħol 2 - send_to_workspace_8: Ibgħat lill-Ispazju tax-Xogħol 8 - switch_workspace_1: Aqleb għall-Ispazju tax-Xogħol 1 - focus_right: Iffoka t-tajjeb - move_to_workspace_3: Mexxi għall-Ispazju tax-Xogħol 3 - send_to_workspace_0: Ibgħat lill-Ispazju tax-Xogħol 0 - decrease_height: Tnaqqas l-għoli - switch_workspace_8: Aqleb għall-Ispazju tax-Xogħol 8 - switch_workspace_9: Aqleb għall-Ispazju tax-Xogħol 9 - switch_workspace_0: Aqleb għall-Ispazju tax-Xogħol 0 - move_to_workspace_7: Mexxi għall-Ispazju tax-Xogħol 7 - send_to_workspace_9: Ibgħat lill-Ispazju tax-Xogħol 9 - switch_workspace_2: Aqleb għall-Ispazju tax-Xogħol 2 - move_to_workspace_5: Mexxi għall-Ispazju tax-Xogħol 5 - move_to_workspace_8: Mexxi għall-Ispazju tax-Xogħol 8 - focus_latest: Iffoka l-aħħar - send_to_workspace_3: Ibgħat lill-Ispazju tax-Xogħol 3 - enable: Enable Shortcuts Integrati (AHK) - enable_tooltip: Itfi jekk timplimenta s-shortcuts tiegħek stess billi tuża l-API Seelen Core -loading: Tagħbija... -inProgress: Fil-progress... -cancel: Ikkanċella -open: Miftuħa -save: Ħlief -quit: Nieqaf -delete: Ħassar +sides: + bottom: Qiegħ + left: Xellug + top: Quċċata + right: Dritt +header: + labels: + info: Informazzjoni + general: Ġenerali + seelen_wm: Window Manager + shortcuts: Shortcuts + seelen_bar: Toolbar tal-Fancy + specific_apps: Applikazzjonijiet speċifiċi + seelen_weg: Dock / Taskbar + developer: Żviluppatur + monitors: Monitors +start: + title: Merħba! + message: >- + Merħba għal Seelen UI, l-ambjent tad-desktop aħħari b'maniġġ tal-Windows + tal-madum inkorporat biex itejjeb l-esperjenza tal-Windows 11 tiegħek! + Esplora era ġdida ta 'effiċjenza u multitasking bl-interface intuwittiv + tagħna u karatteristiċi avvanzati. + message_accent: Ottimizza l-produttività tiegħek bl-istil! +general: + theme: + add: Żid it-tema + placeholder: Agħżel Tema + label: Informazzjoni dwar it-tema + description: Deskrizzjoni + enabled: Temi ppermettiet + author: Awtur + added: Tema diġà miżjuda + tags: Tags + selected: Magħżula + available: Disponibbli + language: Lingwa + startup: Mexxi fuq l-istartjar? + icon_pack: + label: Pakketti tal-ikona + accent_color: Kulur tal-aċċent +toolbar: + placeholder: + author: Awtur + description: Deskrizzjoni + select: Struttura tal-Toolbar + height: Għoli + enable: Jippermetti toolbar tal-fancy +wm: + border: + enable: Ippermetti l-fruntiera tat-tieqa + width: Wisa 'tal-fruntiera + offset: Offset tal-fruntiera + description: Deskrizzjoni + enable: Ippermetti l-maniġer tat-twieqi + layout: Tqassim + resize_delta: Daqs mill-ġdid Delta (%) + disabled_windows10: Il-maniġer tat-twieqi mhux disponibbli għall-Windows 10. + author: Awtur + workspace_offset: Spazji tax-Xogħol Offset (Marġini) + space_between_containers: Spazju bejn il-kontenituri + workspace_padding: Padding tal-ispazji tax-xogħol +weg: + items: + visible_separators: Separaturi viżibbli + label: Oġġetti + gap: Spazju bejn l-oġġetti + size: Daqs tal-oġġett + zoom_size: Daqs miżjud (użat għat-temi) + dock_side: Naħa tal-baċir + label: Dock / Taskbar + width: Wisa ' + enable: Enable Dock / Taskbar + gap: Vojt + auto_hide: Auto Hide + padding: Ikkuttunar + margin: Marġni +devtools: + data_folder: Folder tad-dejta + install_folder: Folder tal-installazzjoni + load: Tagħbija + enable: Ippermetti għodod għall-iżviluppaturi + settings_file: Settings Fajl + custom_config_file: Tagħbija Fajl tal-Konfigurazzjoni Custom + app_folders: Folders tal-app +apps_configurations: + app: + options: + unmanage: Mhux immaniġġjat + float: Galleġġjant + pinned: Imqabbad + force: Forza ta 'tmexxija + title_readonly: Wiri {{isem}} + options_label: Għażliet żejda + monitor: Tissorvelja + ok_readonly: Editja bħala ġdida + name: Isem + category_placeholder: Xejn + ok_edit: Aġġornament + title_create: Ħolqien ta '{{isem}} + workspace_placeholder: Xejn + workspace: Spazju ta 'xogħol + ok_create: Oħloq + category: Kategorija + bindings: Torbot (innota ż-żewġ għażliet huma meħtieġa) + title_edit: Editting {{isem}} + monitor_placeholder: Xejn + identifier: + matching_strategy: Strateġija ta 'tqabbil + and: U + id: Identifikatur + add_block: Żid blokka + or: Jew + negation: Iċħad it-tqabbil + remove: Ħassar il-blokka + kind: Identifika minn + import: Importa + export: Esportazzjoni + confirm_delete: Int żgur li trid tħassar din il-konfigurazzjoni / i? + search: Tfittxija + bundled_msg: >- + Dawn il-konfigurazzjonijiet miġbura mhumiex editabbli u huma mfassla biex + jipprovdulek l-aħjar esperjenza mingħajr personalizzazzjoni. Huma + awtomatikament jikkonfiguraw l-aktar applikazzjonijiet komuni għalik. + bundled_title: App konfigurazzjoni miġbura ma 'seelen + confirm_delete_title: Ikkonferma Ħassar + delete: Ħassar + new: Ġdid + swap: Tpartit +extras: + relaunch: Tnedija mill-ġdid + github: Github + links: Rabtiet uffiċjali + exit: Nieqaf / ħruġ + version: Verżjoni + discord: Diskordja +shortcuts: + labels: + reserve_bottom: Riserva tal-qiegħ + reserve_right: Riserva dritt + focus_top: Focus top + reserve_top: Riserva ta 'fuq + switch_workspace_6: Aqleb għall-Ispazju tax-Xogħol 6 + move_to_workspace_0: Mexxi għall-Ispazju tax-Xogħol 0 + send_to_workspace_1: Ibgħat lill-Ispazju tax-Xogħol 1 + move_to_workspace_6: Mexxi għall-Ispazju tax-Xogħol 6 + switch_workspace_5: Aqleb għall-Ispazju tax-Xogħol 5 + move_to_workspace_9: Mexxi għall-Ispazju tax-Xogħol 9 + focus_bottom: Fokus tal-qiegħ + focus_left: Fokus xellug + send_to_workspace_6: Ibgħat lill-Ispazju tax-Xogħol 6 + switch_workspace_7: Aqleb għall-Ispazju tax-Xogħol 7 + send_to_workspace_5: Ibgħat lill-Ispazju tax-Xogħol 5 + move_to_workspace_1: Mexxi għall-Ispazju tax-Xogħol 1 + send_to_workspace_4: Ibgħat lill-Ispazju tax-Xogħol 4 + move_to_workspace_2: Mexxi għall-Ispazju tax-Xogħol 2 + decrease_width: Tnaqqis il-wisa ' + reserve_float: Riżerva float + reserve_stack: Riżerva munzell + reserve_left: Riserva xellug + switch_workspace_3: Aqleb għall-Ispazju tax-Xogħol 3 + increase_width: Iżżid il-wisa ' + move_to_workspace_4: Mexxi għall-Ispazju tax-Xogħol 4 + restore_sizes: Irrestawra d-daqsijiet + send_to_workspace_7: Ibgħat lill-Ispazju tax-Xogħol 7 + increase_height: Iżid l-għoli + switch_workspace_4: Aqleb għall-Ispazju tax-Xogħol 4 + send_to_workspace_2: Ibgħat lill-Ispazju tax-Xogħol 2 + send_to_workspace_8: Ibgħat lill-Ispazju tax-Xogħol 8 + switch_workspace_1: Aqleb għall-Ispazju tax-Xogħol 1 + focus_right: Iffoka t-tajjeb + move_to_workspace_3: Mexxi għall-Ispazju tax-Xogħol 3 + send_to_workspace_0: Ibgħat lill-Ispazju tax-Xogħol 0 + decrease_height: Tnaqqas l-għoli + switch_workspace_8: Aqleb għall-Ispazju tax-Xogħol 8 + switch_workspace_9: Aqleb għall-Ispazju tax-Xogħol 9 + switch_workspace_0: Aqleb għall-Ispazju tax-Xogħol 0 + move_to_workspace_7: Mexxi għall-Ispazju tax-Xogħol 7 + send_to_workspace_9: Ibgħat lill-Ispazju tax-Xogħol 9 + switch_workspace_2: Aqleb għall-Ispazju tax-Xogħol 2 + move_to_workspace_5: Mexxi għall-Ispazju tax-Xogħol 5 + move_to_workspace_8: Mexxi għall-Ispazju tax-Xogħol 8 + focus_latest: Iffoka l-aħħar + send_to_workspace_3: Ibgħat lill-Ispazju tax-Xogħol 3 + enable: Enable Shortcuts Integrati (AHK) + enable_tooltip: Itfi jekk timplimenta s-shortcuts tiegħek stess billi tuża l-API Seelen Core +loading: Tagħbija... +inProgress: Fil-progress... +cancel: Ikkanċella +open: Miftuħa +save: Ħlief +quit: Nieqaf +delete: Ħassar diff --git a/src/apps/settings/i18n/translations/ne.yml b/src/apps/settings/i18n/translations/ne.yml index 3aadf2f6..a3962ecb 100644 --- a/src/apps/settings/i18n/translations/ne.yml +++ b/src/apps/settings/i18n/translations/ne.yml @@ -1,194 +1,194 @@ -sides: - bottom: पिंध - right: ठिक - left: देब्रे - top: टुप्पो -header: - labels: - seelen_bar: फेन्सी उपकरणपट्टी - specific_apps: विशिष्ट अनुप्रयोगहरू - monitors: मोनिटरहरू - developer: विकासकर्ता - seelen_weg: डक / टास्कबार - shortcuts: सर्टकटहरू - info: सुचना - general: जर्नेल - seelen_wm: वान प्रबन्धक -start: - message_accent: शैलीको साथ तपाईंको उत्पादकता अनुकूल बनाउनुहोस्! - message: >- - UI देखिएको UICTOP वातावरणको साथ स्वागत छ कि एक समावेशी यात्रा गर्ने ठाउँको - साथ तपाईंको विन्डोज 11 अनुभव बढाउन! हाम्रो सहज ईन्टरफेस र उन्नत सुविधाहरूको - साथ दक्षता र मल्टिस्किंगको नयाँ युग अन्वेषण गर्नुहोस्। - title: स्वागत छ! -general: - theme: - enabled: XMES सक्षम गरियो - add: थिम थप्नुहोस् - label: विषयवस्तु जानकारी - author: लेखिका - added: विषयवस्तु पहिले नै थपिएको छ - placeholder: थिम चयन गर्नुहोस् - tags: ट्यागहरू - description: वर्णन - available: सुलभ - selected: चयनित - startup: स्टार्टअपमा भाग्नुहोस्? - language: भाषा - icon_pack: - label: आइकन प्याक - accent_color: हिम्मता रंग -toolbar: - placeholder: - description: वर्णन - select: उपकरणपट्टी संरचना - author: लेखिका - height: ऊचाई - enable: फैन्सी उपकरणपट्टी सक्षम गर्नुहोस् -wm: - border: - offset: सीमा अफसेट - enable: विन्डोको सीमा सक्षम गर्नुहोस् - width: सीमा चौडाई - description: वर्णन - space_between_containers: कन्टेनर बीचको ठाउँ - workspace_offset: कार्यस्पेस अफसेट (मार्जिन) - enable: विन्डो प्रबन्धक सक्षम गर्नुहोस् - disabled_windows10: विन्डो प्रबन्धक विन्डोज 10 को लागि उपलब्ध छैन। - layout: नक्शा - author: लेखिका - resize_delta: रिसाइज डेल्टा (%) - workspace_padding: कार्यक्षेत्र प्याडिंग -weg: - items: - label: वस्तुहरू - gap: वस्तुहरू बीचको ठाउँ - visible_separators: दृश्य बिल्कुलरहरू - size: वस्तुको आकार - zoom_size: Zoomed आकार (थिमका लागि प्रयोग गरिएको) - padding: प्याडडि .्वन - margin: स्पानलिन - dock_side: डक पक्ष - width: चौडाई - auto_hide: 'स्वत: लुकाउने' - gap: अन्तराल - enable: डक / टास्कबार सक्षम गर्नुहोस् - label: डक / टास्कबार -devtools: - app_folders: निल्डर - custom_config_file: कस्टम कन्फिगरि फाईल लोड गर्नुहोस् - data_folder: डेटा फोल्डर - load: बोभ्क - settings_file: सेटिंग्स फाइल - install_folder: स्थापना फोल्डर - enable: विकासकर्ता उपकरणहरू सक्षम गर्नुहोस् -apps_configurations: - app: - options: - pinned: गाइन्ड लाग्यो - float: उत्रनु - unmanage: अज्ञात - force: शक्ति प्रबन्ध - bindings: बाध्यकारी (नोटहरू दुबै विकल्पहरू आवश्यक छन्) - ok_create: सृष्टि गर्नु् - title_edit: '{{{Name n}}}}}}' - ok_readonly: नयाँ जस्तै सम्पादन गर्नुहोस् - options_label: अतिरिक्त विकल्पहरू - workspace: कार्यक्षेत्र - category_placeholder: केहि पनि होइन - ok_edit: अद्यावधिक गर्नुहोस् - monitor: मुल्यांकन गर्नु - title_readonly: '{{Name N}} अवलोकन}}' - category: श्रेणी - name: नाम - title_create: '{{Neame नाम} सिर्जना गर्दै}' - monitor_placeholder: केहि पनि होइन - workspace_placeholder: केहि पनि होइन - identifier: - and: र - id: पहिचानकर्ता - or: अथवा - kind: द्वारा पहिचान - add_block: ब्लक थप्नुहोस् - negation: मिल्दो मिल्दो - matching_strategy: मिलान रणनीति - remove: ब्लक मेट्नुहोस् - delete: मेटाउन - confirm_delete: के तपाईं पक्का यो कन्फिगरेसन / एस मेटाउन चाहनुहुन्छ? - confirm_delete_title: पुष्टि गर्नुहोस् - import: आयात - new: नंया - bundled_msg: >- - यी बन्डल कन्फिगरेसनहरू सम्पादन हुँदैन र तपाईंलाई अनुकूलन बिना उत्तम अनुभव - प्रदान गर्न डिजाइन गरिएको हो। तिनीहरू स्वचालित रूपमा तपाइँको लागि सबैभन्दा - सामान्य अनुप्रयोगहरू कन्फिगर गर्छन्। - export: निर्यात गर्नु - bundled_title: अनुप्रयोग कन्फिगलेेनले भावनाको साथ बन्डल - search: खोजी - swap: स्वप गर्नु -extras: - exit: छोड्नुहोस् / बाहिर निस्कनुहोस् - github: Github - links: आधिकारिक लिंकहरू - relaunch: पुनःस्था - version: रुपान्तर - discord: छलफल दिनु -shortcuts: - labels: - reserve_float: रिजर्भ फ्लोट - send_to_workspace_8: कार्यक्षेत्र to मा पठाउनुहोस् - move_to_workspace_3: कार्यक्षेत्र in मा सार्नुहोस् - increase_height: उचाइ बढाउनुहोस् - switch_workspace_0: कार्यक्षेत्र 0 मा स्विच गर्नुहोस् - send_to_workspace_9: कार्यक्षेत्र to मा पठाउनुहोस् - reserve_bottom: रिजर्व तल - move_to_workspace_8: कार्यक्षेत्र to मा सार्नुहोस् - switch_workspace_4: कार्यक्षेत्र to मा स्विच गर्नुहोस् - move_to_workspace_5: कार्यस्थान to मा सार्नुहोस् - decrease_height: उचाई घटाउनुहोस् - switch_workspace_3: कार्यक्षेत्र in मा स्विच गर्नुहोस् - reserve_top: रिजर्व शीर्ष - move_to_workspace_4: कार्यक्षेत्र to मा सार्नुहोस् - reserve_stack: रिजर्व स्ट्याक - switch_workspace_2: कार्यक्षेत्र 2 मा स्विच गर्नुहोस् - focus_top: फोकस शीर्ष - move_to_workspace_1: कार्यक्षेत्र 1 मा सार्नुहोस् - move_to_workspace_9: कार्यक्षेत्र in मा सार्नुहोस् - send_to_workspace_0: कार्यक्षेत्र 0 लाई पठाउनुहोस् - send_to_workspace_5: कार्यक्षेत्र to मा पठाउनुहोस् - send_to_workspace_6: कार्यक्षेत्र to मा पठाउनुहोस् - reserve_left: त्यागी बायाँ - move_to_workspace_6: कार्यक्षेत्र in मा सार्नुहोस् - switch_workspace_6: कार्यक्षेत्र in मा स्विच गर्नुहोस् - focus_bottom: फोकस तल - switch_workspace_1: कार्यक्षेत्र 1 मा स्विच गर्नुहोस् - send_to_workspace_7: कार्यक्षेत्र to मा पठाउनुहोस् - increase_width: चौडाई बढाउनुहोस् - move_to_workspace_7: कार्यस्थान to मा सार्नुहोस् - send_to_workspace_2: कार्यक्षेत्र 2 लाई पठाउनुहोस् - send_to_workspace_4: कार्यक्षेत्र to मा पठाउनुहोस् - switch_workspace_8: कार्यक्षेत्रमा स्विच गर्नुहोस्। - move_to_workspace_0: कार्यक्षेत्र 0 मा सार्नुहोस् - focus_right: ध्यान केन्द्रित गर्नुहोस् - switch_workspace_5: कार्यक्षेत्र in मा स्विच गर्नुहोस्। - send_to_workspace_3: कार्यक्षेत्र to मा पठाउनुहोस् - focus_latest: पछिल्लो ध्यान दिनुहोस् - send_to_workspace_1: कार्यक्षेत्र 1 लाई पठाउनुहोस् - focus_left: फर्काउनुहोस् - move_to_workspace_2: कार्यक्षेत्र 2 मा सार्नुहोस् - switch_workspace_7: कार्यक्षेत्र in मा स्विच गर्नुहोस् - decrease_width: चौडाई कम - reserve_right: रिजर्व सहि - restore_sizes: आकार पुनर्स्थापना गर्नुहोस् - switch_workspace_9: कार्यक्षेत्र in मा स्विच गर्नुहोस् - enable_tooltip: >- - असक्षम गर्नुहोस् यदि तपाईं देखिने कोर एपीआई प्रयोग गरेर तपाईंको आफ्नै - सर्टकटहरू लागू गर्नुहुन्छ भने असक्षम गर्नुहोस् - enable: एकीकृत सर्टकट सक्षम गर्नुहोस् (AHK) -inProgress: प्रगति हुदैछ... -delete: मेटाउन -loading: लोड गर्दै ... -open: खोल्नु -quit: छोड्नु -cancel: रद्द गर्नु -save: बचाउनु +sides: + bottom: पिंध + right: ठिक + left: देब्रे + top: टुप्पो +header: + labels: + seelen_bar: फेन्सी उपकरणपट्टी + specific_apps: विशिष्ट अनुप्रयोगहरू + monitors: मोनिटरहरू + developer: विकासकर्ता + seelen_weg: डक / टास्कबार + shortcuts: सर्टकटहरू + info: सुचना + general: जर्नेल + seelen_wm: वान प्रबन्धक +start: + message_accent: शैलीको साथ तपाईंको उत्पादकता अनुकूल बनाउनुहोस्! + message: >- + UI देखिएको UICTOP वातावरणको साथ स्वागत छ कि एक समावेशी यात्रा गर्ने ठाउँको + साथ तपाईंको विन्डोज 11 अनुभव बढाउन! हाम्रो सहज ईन्टरफेस र उन्नत सुविधाहरूको + साथ दक्षता र मल्टिस्किंगको नयाँ युग अन्वेषण गर्नुहोस्। + title: स्वागत छ! +general: + theme: + enabled: XMES सक्षम गरियो + add: थिम थप्नुहोस् + label: विषयवस्तु जानकारी + author: लेखिका + added: विषयवस्तु पहिले नै थपिएको छ + placeholder: थिम चयन गर्नुहोस् + tags: ट्यागहरू + description: वर्णन + available: सुलभ + selected: चयनित + startup: स्टार्टअपमा भाग्नुहोस्? + language: भाषा + icon_pack: + label: आइकन प्याक + accent_color: हिम्मता रंग +toolbar: + placeholder: + description: वर्णन + select: उपकरणपट्टी संरचना + author: लेखिका + height: ऊचाई + enable: फैन्सी उपकरणपट्टी सक्षम गर्नुहोस् +wm: + border: + offset: सीमा अफसेट + enable: विन्डोको सीमा सक्षम गर्नुहोस् + width: सीमा चौडाई + description: वर्णन + space_between_containers: कन्टेनर बीचको ठाउँ + workspace_offset: कार्यस्पेस अफसेट (मार्जिन) + enable: विन्डो प्रबन्धक सक्षम गर्नुहोस् + disabled_windows10: विन्डो प्रबन्धक विन्डोज 10 को लागि उपलब्ध छैन। + layout: नक्शा + author: लेखिका + resize_delta: रिसाइज डेल्टा (%) + workspace_padding: कार्यक्षेत्र प्याडिंग +weg: + items: + label: वस्तुहरू + gap: वस्तुहरू बीचको ठाउँ + visible_separators: दृश्य बिल्कुलरहरू + size: वस्तुको आकार + zoom_size: Zoomed आकार (थिमका लागि प्रयोग गरिएको) + padding: प्याडडि .्वन + margin: स्पानलिन + dock_side: डक पक्ष + width: चौडाई + auto_hide: 'स्वत: लुकाउने' + gap: अन्तराल + enable: डक / टास्कबार सक्षम गर्नुहोस् + label: डक / टास्कबार +devtools: + app_folders: निल्डर + custom_config_file: कस्टम कन्फिगरि फाईल लोड गर्नुहोस् + data_folder: डेटा फोल्डर + load: बोभ्क + settings_file: सेटिंग्स फाइल + install_folder: स्थापना फोल्डर + enable: विकासकर्ता उपकरणहरू सक्षम गर्नुहोस् +apps_configurations: + app: + options: + pinned: गाइन्ड लाग्यो + float: उत्रनु + unmanage: अज्ञात + force: शक्ति प्रबन्ध + bindings: बाध्यकारी (नोटहरू दुबै विकल्पहरू आवश्यक छन्) + ok_create: सृष्टि गर्नु् + title_edit: '{{{Name n}}}}}}' + ok_readonly: नयाँ जस्तै सम्पादन गर्नुहोस् + options_label: अतिरिक्त विकल्पहरू + workspace: कार्यक्षेत्र + category_placeholder: केहि पनि होइन + ok_edit: अद्यावधिक गर्नुहोस् + monitor: मुल्यांकन गर्नु + title_readonly: '{{Name N}} अवलोकन}}' + category: श्रेणी + name: नाम + title_create: '{{Neame नाम} सिर्जना गर्दै}' + monitor_placeholder: केहि पनि होइन + workspace_placeholder: केहि पनि होइन + identifier: + and: र + id: पहिचानकर्ता + or: अथवा + kind: द्वारा पहिचान + add_block: ब्लक थप्नुहोस् + negation: मिल्दो मिल्दो + matching_strategy: मिलान रणनीति + remove: ब्लक मेट्नुहोस् + delete: मेटाउन + confirm_delete: के तपाईं पक्का यो कन्फिगरेसन / एस मेटाउन चाहनुहुन्छ? + confirm_delete_title: पुष्टि गर्नुहोस् + import: आयात + new: नंया + bundled_msg: >- + यी बन्डल कन्फिगरेसनहरू सम्पादन हुँदैन र तपाईंलाई अनुकूलन बिना उत्तम अनुभव + प्रदान गर्न डिजाइन गरिएको हो। तिनीहरू स्वचालित रूपमा तपाइँको लागि सबैभन्दा + सामान्य अनुप्रयोगहरू कन्फिगर गर्छन्। + export: निर्यात गर्नु + bundled_title: अनुप्रयोग कन्फिगलेेनले भावनाको साथ बन्डल + search: खोजी + swap: स्वप गर्नु +extras: + exit: छोड्नुहोस् / बाहिर निस्कनुहोस् + github: Github + links: आधिकारिक लिंकहरू + relaunch: पुनःस्था + version: रुपान्तर + discord: छलफल दिनु +shortcuts: + labels: + reserve_float: रिजर्भ फ्लोट + send_to_workspace_8: कार्यक्षेत्र to मा पठाउनुहोस् + move_to_workspace_3: कार्यक्षेत्र in मा सार्नुहोस् + increase_height: उचाइ बढाउनुहोस् + switch_workspace_0: कार्यक्षेत्र 0 मा स्विच गर्नुहोस् + send_to_workspace_9: कार्यक्षेत्र to मा पठाउनुहोस् + reserve_bottom: रिजर्व तल + move_to_workspace_8: कार्यक्षेत्र to मा सार्नुहोस् + switch_workspace_4: कार्यक्षेत्र to मा स्विच गर्नुहोस् + move_to_workspace_5: कार्यस्थान to मा सार्नुहोस् + decrease_height: उचाई घटाउनुहोस् + switch_workspace_3: कार्यक्षेत्र in मा स्विच गर्नुहोस् + reserve_top: रिजर्व शीर्ष + move_to_workspace_4: कार्यक्षेत्र to मा सार्नुहोस् + reserve_stack: रिजर्व स्ट्याक + switch_workspace_2: कार्यक्षेत्र 2 मा स्विच गर्नुहोस् + focus_top: फोकस शीर्ष + move_to_workspace_1: कार्यक्षेत्र 1 मा सार्नुहोस् + move_to_workspace_9: कार्यक्षेत्र in मा सार्नुहोस् + send_to_workspace_0: कार्यक्षेत्र 0 लाई पठाउनुहोस् + send_to_workspace_5: कार्यक्षेत्र to मा पठाउनुहोस् + send_to_workspace_6: कार्यक्षेत्र to मा पठाउनुहोस् + reserve_left: त्यागी बायाँ + move_to_workspace_6: कार्यक्षेत्र in मा सार्नुहोस् + switch_workspace_6: कार्यक्षेत्र in मा स्विच गर्नुहोस् + focus_bottom: फोकस तल + switch_workspace_1: कार्यक्षेत्र 1 मा स्विच गर्नुहोस् + send_to_workspace_7: कार्यक्षेत्र to मा पठाउनुहोस् + increase_width: चौडाई बढाउनुहोस् + move_to_workspace_7: कार्यस्थान to मा सार्नुहोस् + send_to_workspace_2: कार्यक्षेत्र 2 लाई पठाउनुहोस् + send_to_workspace_4: कार्यक्षेत्र to मा पठाउनुहोस् + switch_workspace_8: कार्यक्षेत्रमा स्विच गर्नुहोस्। + move_to_workspace_0: कार्यक्षेत्र 0 मा सार्नुहोस् + focus_right: ध्यान केन्द्रित गर्नुहोस् + switch_workspace_5: कार्यक्षेत्र in मा स्विच गर्नुहोस्। + send_to_workspace_3: कार्यक्षेत्र to मा पठाउनुहोस् + focus_latest: पछिल्लो ध्यान दिनुहोस् + send_to_workspace_1: कार्यक्षेत्र 1 लाई पठाउनुहोस् + focus_left: फर्काउनुहोस् + move_to_workspace_2: कार्यक्षेत्र 2 मा सार्नुहोस् + switch_workspace_7: कार्यक्षेत्र in मा स्विच गर्नुहोस् + decrease_width: चौडाई कम + reserve_right: रिजर्व सहि + restore_sizes: आकार पुनर्स्थापना गर्नुहोस् + switch_workspace_9: कार्यक्षेत्र in मा स्विच गर्नुहोस् + enable_tooltip: >- + असक्षम गर्नुहोस् यदि तपाईं देखिने कोर एपीआई प्रयोग गरेर तपाईंको आफ्नै + सर्टकटहरू लागू गर्नुहुन्छ भने असक्षम गर्नुहोस् + enable: एकीकृत सर्टकट सक्षम गर्नुहोस् (AHK) +inProgress: प्रगति हुदैछ... +delete: मेटाउन +loading: लोड गर्दै ... +open: खोल्नु +quit: छोड्नु +cancel: रद्द गर्नु +save: बचाउनु diff --git a/src/apps/settings/i18n/translations/nl.yml b/src/apps/settings/i18n/translations/nl.yml index f42b2bf8..6770b7d8 100644 --- a/src/apps/settings/i18n/translations/nl.yml +++ b/src/apps/settings/i18n/translations/nl.yml @@ -1,195 +1,195 @@ -sides: - bottom: Onderkant - top: Bovenkant - right: Rechts - left: Links -header: - labels: - seelen_wm: Window Manager - info: Informatie - developer: Ontwikkelaar - general: Algemeen - specific_apps: Specifieke apps - monitors: Monitoren - seelen_weg: Dock/taakbalk - seelen_bar: Fancy werkbalk - shortcuts: Snelkoppelingen -start: - message_accent: Optimaliseer uw productiviteit met stijl! - title: Welkom! - message: >- - Welkom bij Seelen UI, de ultieme desktopomgeving met een opgenomen Tiling - Windows Manager om uw Windows 11 -ervaring te verbeteren! Verken een nieuw - tijdperk van efficiëntie en multitasking met onze intuïtieve interface en - geavanceerde functies. -general: - theme: - author: Auteur - placeholder: Selecteer thema - description: Beschrijving - add: Thema toevoegen - tags: Tags - label: Thema -informatie - enabled: Ingeschakelde thema's - added: Thema al toegevoegd - selected: Geselecteerd - available: Beschikbaar - language: Taal - startup: Uitvoeren bij het starten? - icon_pack: - label: Pictogrampakketten - accent_color: Accent kleur -toolbar: - placeholder: - author: Auteur - description: Beschrijving - select: Werkbalkstructuur - height: Hoogte - enable: Schakel fancy werkbalk in -wm: - border: - width: Grensbreedte - enable: Schakel Window's Border in - offset: Grens offset - space_between_containers: Ruimte tussen containers - author: Auteur - workspace_offset: Workspaces Offset (marges) - description: Beschrijving - layout: Lay -out - workspace_padding: Workspaces -vulling - enable: Schakel Window Manager in - disabled_windows10: De Window Manager is niet beschikbaar voor Windows 10. - resize_delta: Wijzig de wijzers van delta (%) -weg: - items: - visible_separators: Zichtbare scheiders - size: Artikelgrootte - zoom_size: Ingezoomde grootte (gebruikt voor thema's) - label: Items - gap: Ruimte tussen items - padding: Vulling - margin: Marge - gap: Gat - auto_hide: Auto Hide - width: Breedte - label: Dock/taakbalk - enable: Schakel dock/taakbalk in - dock_side: Dokzijde -devtools: - load: Laden - data_folder: Gegevensmap - app_folders: App -mappen - custom_config_file: Laad het aangepaste configuratiebestand - enable: Schakel ontwikkelaarstools in - settings_file: Instellingenbestand - install_folder: Installatiemap -apps_configurations: - app: - options: - float: Vlot - force: Force beheren - pinned: Vastgemaakt - unmanage: Onschadelijk - category_placeholder: Geen - ok_create: Creëren - ok_edit: Update - category: Categorie - monitor_placeholder: Geen - title_readonly: '{{{Name}} bekijken' - workspace: Werkruimte - title_edit: Bewerken {{name}} - ok_readonly: Bewerken als nieuw - title_create: Het maken van {{name}} - bindings: Binding (merk op beide opties vereist) - workspace_placeholder: Geen - monitor: Monitor - name: Naam - options_label: Extra opties - identifier: - and: EN - or: OF - remove: Verwijder blok - matching_strategy: Matching -strategie - add_block: Block toevoegen - id: Identificatier - negation: Ontkennen matching - kind: Identificeren door - swap: Ruil - confirm_delete_title: Bevestig verwijderen - export: Exporteren - new: Nieuw - confirm_delete: Weet u zeker dat u deze configuratie/en) wilt verwijderen? - delete: Verwijderen - import: Importeren - search: Zoekopdracht - bundled_msg: >- - Deze gebundelde configuraties zijn niet bewerkbaar en zijn ontworpen om u de - beste ervaring zonder aanpassing te bieden. Ze configureren automatisch de - meest voorkomende toepassingen voor u. - bundled_title: App -configuratie gebundeld met selen -extras: - relaunch: Opnieuw lanceren - discord: Meningsverschil - exit: Stop/exit - version: Versie - links: Officiële links - github: Gitub -shortcuts: - labels: - decrease_width: Breedte afnemen - move_to_workspace_6: Ga naar werkruimte 6 - move_to_workspace_2: Ga naar werkruimte 2 - switch_workspace_1: Schakel over naar werkruimte 1 - switch_workspace_6: Schakel over naar werkruimte 6 - switch_workspace_0: Schakel over naar werkruimte 0 - move_to_workspace_4: Ga naar werkruimte 4 - move_to_workspace_9: Ga naar werkruimte 9 - increase_height: Verhoog de hoogte - move_to_workspace_7: Ga naar werkruimte 7 - focus_top: Focus Top - focus_latest: Focus nieuwste - reserve_stack: Reservetapel - reserve_left: Reserveer links - send_to_workspace_0: Stuur naar werkruimte 0 - reserve_float: Reserve Float - send_to_workspace_2: Stuur naar werkruimte 2 - switch_workspace_3: Schakel over naar werkruimte 3 - switch_workspace_4: Schakel over naar werkruimte 4 - move_to_workspace_1: Ga naar werkruimte 1 - switch_workspace_5: Schakel over naar werkruimte 5 - send_to_workspace_8: Stuur naar werkruimte 8 - switch_workspace_9: Schakel over naar werkruimte 9 - focus_left: Focus links - decrease_height: De hoogte verminderen - move_to_workspace_8: Ga naar werkruimte 8 - switch_workspace_2: Schakel over naar werkruimte 2 - send_to_workspace_1: Stuur naar werkruimte 1 - move_to_workspace_5: Ga naar werkruimte 5 - increase_width: Verhoog de breedte - send_to_workspace_7: Stuur naar werkruimte 7 - send_to_workspace_3: Stuur naar werkruimte 3 - move_to_workspace_3: Ga naar werkruimte 3 - send_to_workspace_5: Stuur naar werkruimte 5 - reserve_top: Reserveer top - send_to_workspace_6: Stuur naar werkruimte 6 - reserve_right: Reserve recht - switch_workspace_7: Schakel over naar werkruimte 7 - reserve_bottom: Reserve bodem - move_to_workspace_0: Ga naar de werkruimte 0 - switch_workspace_8: Schakel over naar werkruimte 8 - restore_sizes: Herstel de maten - send_to_workspace_9: Stuur naar werkruimte 9 - send_to_workspace_4: Stuur naar werkruimte 4 - focus_right: Focus goed - focus_bottom: Focusbodem - enable: Geïntegreerde snelkoppelingen inschakelen (AHK) - enable_tooltip: >- - Schakel uit of u uw eigen snelkoppelingen implementeert met behulp van de - Selen Core API -quit: Ontslag nemen -open: Open -save: Redden -inProgress: Bezig... -loading: Bezig met laden... -delete: Verwijderen -cancel: Annuleren +sides: + bottom: Onderkant + top: Bovenkant + right: Rechts + left: Links +header: + labels: + seelen_wm: Window Manager + info: Informatie + developer: Ontwikkelaar + general: Algemeen + specific_apps: Specifieke apps + monitors: Monitoren + seelen_weg: Dock/taakbalk + seelen_bar: Fancy werkbalk + shortcuts: Snelkoppelingen +start: + message_accent: Optimaliseer uw productiviteit met stijl! + title: Welkom! + message: >- + Welkom bij Seelen UI, de ultieme desktopomgeving met een opgenomen Tiling + Windows Manager om uw Windows 11 -ervaring te verbeteren! Verken een nieuw + tijdperk van efficiëntie en multitasking met onze intuïtieve interface en + geavanceerde functies. +general: + theme: + author: Auteur + placeholder: Selecteer thema + description: Beschrijving + add: Thema toevoegen + tags: Tags + label: Thema -informatie + enabled: Ingeschakelde thema's + added: Thema al toegevoegd + selected: Geselecteerd + available: Beschikbaar + language: Taal + startup: Uitvoeren bij het starten? + icon_pack: + label: Pictogrampakketten + accent_color: Accent kleur +toolbar: + placeholder: + author: Auteur + description: Beschrijving + select: Werkbalkstructuur + height: Hoogte + enable: Schakel fancy werkbalk in +wm: + border: + width: Grensbreedte + enable: Schakel Window's Border in + offset: Grens offset + space_between_containers: Ruimte tussen containers + author: Auteur + workspace_offset: Workspaces Offset (marges) + description: Beschrijving + layout: Lay -out + workspace_padding: Workspaces -vulling + enable: Schakel Window Manager in + disabled_windows10: De Window Manager is niet beschikbaar voor Windows 10. + resize_delta: Wijzig de wijzers van delta (%) +weg: + items: + visible_separators: Zichtbare scheiders + size: Artikelgrootte + zoom_size: Ingezoomde grootte (gebruikt voor thema's) + label: Items + gap: Ruimte tussen items + padding: Vulling + margin: Marge + gap: Gat + auto_hide: Auto Hide + width: Breedte + label: Dock/taakbalk + enable: Schakel dock/taakbalk in + dock_side: Dokzijde +devtools: + load: Laden + data_folder: Gegevensmap + app_folders: App -mappen + custom_config_file: Laad het aangepaste configuratiebestand + enable: Schakel ontwikkelaarstools in + settings_file: Instellingenbestand + install_folder: Installatiemap +apps_configurations: + app: + options: + float: Vlot + force: Force beheren + pinned: Vastgemaakt + unmanage: Onschadelijk + category_placeholder: Geen + ok_create: Creëren + ok_edit: Update + category: Categorie + monitor_placeholder: Geen + title_readonly: '{{{Name}} bekijken' + workspace: Werkruimte + title_edit: Bewerken {{name}} + ok_readonly: Bewerken als nieuw + title_create: Het maken van {{name}} + bindings: Binding (merk op beide opties vereist) + workspace_placeholder: Geen + monitor: Monitor + name: Naam + options_label: Extra opties + identifier: + and: EN + or: OF + remove: Verwijder blok + matching_strategy: Matching -strategie + add_block: Block toevoegen + id: Identificatier + negation: Ontkennen matching + kind: Identificeren door + swap: Ruil + confirm_delete_title: Bevestig verwijderen + export: Exporteren + new: Nieuw + confirm_delete: Weet u zeker dat u deze configuratie/en) wilt verwijderen? + delete: Verwijderen + import: Importeren + search: Zoekopdracht + bundled_msg: >- + Deze gebundelde configuraties zijn niet bewerkbaar en zijn ontworpen om u de + beste ervaring zonder aanpassing te bieden. Ze configureren automatisch de + meest voorkomende toepassingen voor u. + bundled_title: App -configuratie gebundeld met selen +extras: + relaunch: Opnieuw lanceren + discord: Meningsverschil + exit: Stop/exit + version: Versie + links: Officiële links + github: Gitub +shortcuts: + labels: + decrease_width: Breedte afnemen + move_to_workspace_6: Ga naar werkruimte 6 + move_to_workspace_2: Ga naar werkruimte 2 + switch_workspace_1: Schakel over naar werkruimte 1 + switch_workspace_6: Schakel over naar werkruimte 6 + switch_workspace_0: Schakel over naar werkruimte 0 + move_to_workspace_4: Ga naar werkruimte 4 + move_to_workspace_9: Ga naar werkruimte 9 + increase_height: Verhoog de hoogte + move_to_workspace_7: Ga naar werkruimte 7 + focus_top: Focus Top + focus_latest: Focus nieuwste + reserve_stack: Reservetapel + reserve_left: Reserveer links + send_to_workspace_0: Stuur naar werkruimte 0 + reserve_float: Reserve Float + send_to_workspace_2: Stuur naar werkruimte 2 + switch_workspace_3: Schakel over naar werkruimte 3 + switch_workspace_4: Schakel over naar werkruimte 4 + move_to_workspace_1: Ga naar werkruimte 1 + switch_workspace_5: Schakel over naar werkruimte 5 + send_to_workspace_8: Stuur naar werkruimte 8 + switch_workspace_9: Schakel over naar werkruimte 9 + focus_left: Focus links + decrease_height: De hoogte verminderen + move_to_workspace_8: Ga naar werkruimte 8 + switch_workspace_2: Schakel over naar werkruimte 2 + send_to_workspace_1: Stuur naar werkruimte 1 + move_to_workspace_5: Ga naar werkruimte 5 + increase_width: Verhoog de breedte + send_to_workspace_7: Stuur naar werkruimte 7 + send_to_workspace_3: Stuur naar werkruimte 3 + move_to_workspace_3: Ga naar werkruimte 3 + send_to_workspace_5: Stuur naar werkruimte 5 + reserve_top: Reserveer top + send_to_workspace_6: Stuur naar werkruimte 6 + reserve_right: Reserve recht + switch_workspace_7: Schakel over naar werkruimte 7 + reserve_bottom: Reserve bodem + move_to_workspace_0: Ga naar de werkruimte 0 + switch_workspace_8: Schakel over naar werkruimte 8 + restore_sizes: Herstel de maten + send_to_workspace_9: Stuur naar werkruimte 9 + send_to_workspace_4: Stuur naar werkruimte 4 + focus_right: Focus goed + focus_bottom: Focusbodem + enable: Geïntegreerde snelkoppelingen inschakelen (AHK) + enable_tooltip: >- + Schakel uit of u uw eigen snelkoppelingen implementeert met behulp van de + Selen Core API +quit: Ontslag nemen +open: Open +save: Redden +inProgress: Bezig... +loading: Bezig met laden... +delete: Verwijderen +cancel: Annuleren diff --git a/src/apps/settings/i18n/translations/no.yml b/src/apps/settings/i18n/translations/no.yml index eb23642c..e72e4d27 100644 --- a/src/apps/settings/i18n/translations/no.yml +++ b/src/apps/settings/i18n/translations/no.yml @@ -1,195 +1,195 @@ -sides: - top: Topp - left: Venstre - right: Ikke sant - bottom: Bunn -header: - labels: - info: Informasjon - general: Generell - seelen_bar: Fancy verktøylinje - seelen_wm: Vindusleder - shortcuts: Snarveier - specific_apps: Spesifikke apper - developer: Utvikler - seelen_weg: Dock/oppgavelinje - monitors: Skjermer -start: - title: Velkommen! - message: >- - Velkommen til Seelen UI, Ultimate Desktop Environment med en innlemmet - tilflising av Windows Manager for å forbedre Windows 11 -opplevelsen din! - Utforsk en ny epoke med effektivitet og multitasking med vårt intuitive - grensesnitt og avanserte funksjoner. - message_accent: Optimaliser produktiviteten din med stil! -general: - theme: - description: Beskrivelse - author: Forfatter - enabled: Aktiverte temaer - label: Temainformasjon - added: Tema som allerede er lagt til - tags: Tagger - placeholder: Velg tema - add: Legg til tema - available: Tilgjengelig - selected: Valgt - language: Språk - startup: Kjør ved oppstart? - icon_pack: - label: Ikonpakker - accent_color: Aksentfarge -toolbar: - placeholder: - description: Beskrivelse - author: Forfatter - select: Verktøylinjestruktur - height: Høyde - enable: Aktiver fancy verktøylinje -wm: - border: - enable: Aktiver vinduets grense - width: Grensebredde - offset: Grenseforskyvning - author: Forfatter - description: Beskrivelse - layout: Oppsett - space_between_containers: Plass mellom containere - resize_delta: Endre størrelse på Delta (%) - workspace_offset: Arbeidsområder forskyvning (marginer) - workspace_padding: Arbeidsområder polstring - disabled_windows10: Window Manager er ikke tilgjengelig for Windows 10. - enable: Aktiver Window Manager -weg: - items: - zoom_size: Zoomet størrelse (brukt til temaer) - visible_separators: Synlige separatorer - size: Varestørrelse - label: Gjenstander - gap: Plass mellom varene - width: Bredde - auto_hide: Skjul automatisk - margin: Margin - gap: Mellomrom - padding: Polstring - dock_side: Dock Side - label: Dock/oppgavelinje - enable: Aktiver dock/oppgavelinje -devtools: - load: Laste - custom_config_file: Last inn tilpasset konfigurasjonsfil - settings_file: Innstillingsfilen - install_folder: Installasjonsmappe - app_folders: App -mapper - data_folder: Datamappen - enable: Aktiver utviklerverktøy -apps_configurations: - app: - options: - float: Flyte - force: Force Manag - pinned: Festet - unmanage: Unmanage - title_edit: Redigering {{name}} - category: Kategori - title_create: Opprette {{name}} - monitor_placeholder: Ingen - ok_edit: Oppdater - ok_create: Skape - category_placeholder: Ingen - bindings: Binding (Merk begge alternativene er påkrevd) - workspace_placeholder: Ingen - name: Navn - monitor: Observere - title_readonly: Visning {{name}} - options_label: Ekstra alternativer - workspace: Arbeidsområde - ok_readonly: Rediger som ny - identifier: - and: OG - kind: Identifisere av - or: ELLER - add_block: Legg til blokkering - matching_strategy: Matchende strategi - id: Identifikator - remove: Slett blokkering - negation: Negere matching - swap: Bytte - search: Søk - confirm_delete: Er du sikker på at du vil slette denne konfigurasjonen/S? - new: Ny - bundled_msg: >- - Disse samlede konfigurasjonene er ikke redigerbare og er designet for å gi - deg den beste opplevelsen uten tilpasning. De konfigurerer automatisk de - vanligste applikasjonene for deg. - delete: Slett - export: Eksport - import: Import - confirm_delete_title: Bekreft slett - bundled_title: App Config samlet med Seelen -extras: - version: Versjon - github: Github - relaunch: Relanseres - exit: Avslutt/avslutte - links: Offisielle lenker - discord: Uenighet -shortcuts: - labels: - focus_latest: Fokusere siste - reserve_left: Reserve igjen - switch_workspace_1: Bytt til arbeidsområdet 1 - focus_top: Fokus topp - switch_workspace_2: Bytt til arbeidsområdet 2 - send_to_workspace_8: Send til arbeidsområdet 8 - switch_workspace_7: Bytt til arbeidsområdet 7 - increase_width: Øke bredden - send_to_workspace_4: Send til arbeidsområdet 4 - switch_workspace_0: Bytt til arbeidsområdet 0 - decrease_width: Redusere bredden - move_to_workspace_4: Flytt til arbeidsområdet 4 - reserve_bottom: Reserve bunn - reserve_stack: Reserve stack - reserve_float: Reserve flyter - move_to_workspace_6: Flytt til arbeidsområdet 6 - increase_height: Øk høyden - focus_right: Fokuser riktig - switch_workspace_8: Bytt til arbeidsområdet 8 - switch_workspace_9: Bytt til arbeidsområdet 9 - switch_workspace_6: Bytt til arbeidsområdet 6 - decrease_height: Reduser høyden - reserve_top: Reserve top - move_to_workspace_8: Flytt til arbeidsområdet 8 - restore_sizes: Gjenopprett størrelser - move_to_workspace_9: Flytt til arbeidsområdet 9 - focus_bottom: Fokus bunnen - move_to_workspace_1: Flytt til arbeidsområdet 1 - send_to_workspace_2: Send til arbeidsområdet 2 - reserve_right: Reservere riktig - switch_workspace_5: Bytt til arbeidsområdet 5 - send_to_workspace_6: Send til arbeidsområdet 6 - switch_workspace_3: Bytt til arbeidsområdet 3 - move_to_workspace_5: Flytt til arbeidsområdet 5 - move_to_workspace_2: Flytt til arbeidsområdet 2 - move_to_workspace_7: Flytt til arbeidsområdet 7 - switch_workspace_4: Bytt til arbeidsområdet 4 - move_to_workspace_0: Flytt til arbeidsområdet 0 - send_to_workspace_5: Send til arbeidsområdet 5 - focus_left: Fokus igjen - send_to_workspace_1: Send til arbeidsområdet 1 - send_to_workspace_0: Send til arbeidsområdet 0 - send_to_workspace_9: Send til arbeidsområdet 9 - move_to_workspace_3: Flytt til arbeidsområdet 3 - send_to_workspace_7: Send til arbeidsområdet 7 - send_to_workspace_3: Send til arbeidsområdet 3 - enable_tooltip: >- - Deaktiver om du vil implementere dine egne snarveier ved hjelp av Seelen - Core API - enable: Aktiver integrerte snarveier (AHK) -cancel: Avbryt -inProgress: I prosess... -quit: Slutte -open: Åpen -save: Lagre -delete: Slett -loading: Laster ... +sides: + top: Topp + left: Venstre + right: Ikke sant + bottom: Bunn +header: + labels: + info: Informasjon + general: Generell + seelen_bar: Fancy verktøylinje + seelen_wm: Vindusleder + shortcuts: Snarveier + specific_apps: Spesifikke apper + developer: Utvikler + seelen_weg: Dock/oppgavelinje + monitors: Skjermer +start: + title: Velkommen! + message: >- + Velkommen til Seelen UI, Ultimate Desktop Environment med en innlemmet + tilflising av Windows Manager for å forbedre Windows 11 -opplevelsen din! + Utforsk en ny epoke med effektivitet og multitasking med vårt intuitive + grensesnitt og avanserte funksjoner. + message_accent: Optimaliser produktiviteten din med stil! +general: + theme: + description: Beskrivelse + author: Forfatter + enabled: Aktiverte temaer + label: Temainformasjon + added: Tema som allerede er lagt til + tags: Tagger + placeholder: Velg tema + add: Legg til tema + available: Tilgjengelig + selected: Valgt + language: Språk + startup: Kjør ved oppstart? + icon_pack: + label: Ikonpakker + accent_color: Aksentfarge +toolbar: + placeholder: + description: Beskrivelse + author: Forfatter + select: Verktøylinjestruktur + height: Høyde + enable: Aktiver fancy verktøylinje +wm: + border: + enable: Aktiver vinduets grense + width: Grensebredde + offset: Grenseforskyvning + author: Forfatter + description: Beskrivelse + layout: Oppsett + space_between_containers: Plass mellom containere + resize_delta: Endre størrelse på Delta (%) + workspace_offset: Arbeidsområder forskyvning (marginer) + workspace_padding: Arbeidsområder polstring + disabled_windows10: Window Manager er ikke tilgjengelig for Windows 10. + enable: Aktiver Window Manager +weg: + items: + zoom_size: Zoomet størrelse (brukt til temaer) + visible_separators: Synlige separatorer + size: Varestørrelse + label: Gjenstander + gap: Plass mellom varene + width: Bredde + auto_hide: Skjul automatisk + margin: Margin + gap: Mellomrom + padding: Polstring + dock_side: Dock Side + label: Dock/oppgavelinje + enable: Aktiver dock/oppgavelinje +devtools: + load: Laste + custom_config_file: Last inn tilpasset konfigurasjonsfil + settings_file: Innstillingsfilen + install_folder: Installasjonsmappe + app_folders: App -mapper + data_folder: Datamappen + enable: Aktiver utviklerverktøy +apps_configurations: + app: + options: + float: Flyte + force: Force Manag + pinned: Festet + unmanage: Unmanage + title_edit: Redigering {{name}} + category: Kategori + title_create: Opprette {{name}} + monitor_placeholder: Ingen + ok_edit: Oppdater + ok_create: Skape + category_placeholder: Ingen + bindings: Binding (Merk begge alternativene er påkrevd) + workspace_placeholder: Ingen + name: Navn + monitor: Observere + title_readonly: Visning {{name}} + options_label: Ekstra alternativer + workspace: Arbeidsområde + ok_readonly: Rediger som ny + identifier: + and: OG + kind: Identifisere av + or: ELLER + add_block: Legg til blokkering + matching_strategy: Matchende strategi + id: Identifikator + remove: Slett blokkering + negation: Negere matching + swap: Bytte + search: Søk + confirm_delete: Er du sikker på at du vil slette denne konfigurasjonen/S? + new: Ny + bundled_msg: >- + Disse samlede konfigurasjonene er ikke redigerbare og er designet for å gi + deg den beste opplevelsen uten tilpasning. De konfigurerer automatisk de + vanligste applikasjonene for deg. + delete: Slett + export: Eksport + import: Import + confirm_delete_title: Bekreft slett + bundled_title: App Config samlet med Seelen +extras: + version: Versjon + github: Github + relaunch: Relanseres + exit: Avslutt/avslutte + links: Offisielle lenker + discord: Uenighet +shortcuts: + labels: + focus_latest: Fokusere siste + reserve_left: Reserve igjen + switch_workspace_1: Bytt til arbeidsområdet 1 + focus_top: Fokus topp + switch_workspace_2: Bytt til arbeidsområdet 2 + send_to_workspace_8: Send til arbeidsområdet 8 + switch_workspace_7: Bytt til arbeidsområdet 7 + increase_width: Øke bredden + send_to_workspace_4: Send til arbeidsområdet 4 + switch_workspace_0: Bytt til arbeidsområdet 0 + decrease_width: Redusere bredden + move_to_workspace_4: Flytt til arbeidsområdet 4 + reserve_bottom: Reserve bunn + reserve_stack: Reserve stack + reserve_float: Reserve flyter + move_to_workspace_6: Flytt til arbeidsområdet 6 + increase_height: Øk høyden + focus_right: Fokuser riktig + switch_workspace_8: Bytt til arbeidsområdet 8 + switch_workspace_9: Bytt til arbeidsområdet 9 + switch_workspace_6: Bytt til arbeidsområdet 6 + decrease_height: Reduser høyden + reserve_top: Reserve top + move_to_workspace_8: Flytt til arbeidsområdet 8 + restore_sizes: Gjenopprett størrelser + move_to_workspace_9: Flytt til arbeidsområdet 9 + focus_bottom: Fokus bunnen + move_to_workspace_1: Flytt til arbeidsområdet 1 + send_to_workspace_2: Send til arbeidsområdet 2 + reserve_right: Reservere riktig + switch_workspace_5: Bytt til arbeidsområdet 5 + send_to_workspace_6: Send til arbeidsområdet 6 + switch_workspace_3: Bytt til arbeidsområdet 3 + move_to_workspace_5: Flytt til arbeidsområdet 5 + move_to_workspace_2: Flytt til arbeidsområdet 2 + move_to_workspace_7: Flytt til arbeidsområdet 7 + switch_workspace_4: Bytt til arbeidsområdet 4 + move_to_workspace_0: Flytt til arbeidsområdet 0 + send_to_workspace_5: Send til arbeidsområdet 5 + focus_left: Fokus igjen + send_to_workspace_1: Send til arbeidsområdet 1 + send_to_workspace_0: Send til arbeidsområdet 0 + send_to_workspace_9: Send til arbeidsområdet 9 + move_to_workspace_3: Flytt til arbeidsområdet 3 + send_to_workspace_7: Send til arbeidsområdet 7 + send_to_workspace_3: Send til arbeidsområdet 3 + enable_tooltip: >- + Deaktiver om du vil implementere dine egne snarveier ved hjelp av Seelen + Core API + enable: Aktiver integrerte snarveier (AHK) +cancel: Avbryt +inProgress: I prosess... +quit: Slutte +open: Åpen +save: Lagre +delete: Slett +loading: Laster ... diff --git a/src/apps/settings/i18n/translations/pa.yml b/src/apps/settings/i18n/translations/pa.yml index 955c9b53..34981e26 100644 --- a/src/apps/settings/i18n/translations/pa.yml +++ b/src/apps/settings/i18n/translations/pa.yml @@ -1,195 +1,195 @@ -sides: - left: ਖੱਬੇ - bottom: ਹੇਠਾਂ - top: ਸਿਖਰ - right: ਸੱਜਾ -header: - labels: - general: ਜਨਰਲ - seelen_wm: ਵਿੰਡੋ ਮੈਨੇਜਰ - seelen_bar: ਫੈਂਸੀ ਟੂਲਬਾਰ - monitors: ਨਿਗਰਾਨੀ ਕਰਦਾ ਹੈ - specific_apps: ਖਾਸ ਐਪਸ - shortcuts: ਸ਼ਾਰਟਕੱਟ - info: ਜਾਣਕਾਰੀ - developer: ਵਿਕਾਸਕਾਰ - seelen_weg: ਡੌਕ/ਟਾਸਕਬਾਰ -start: - message: >- - Seelen UI ਵਿੱਚ ਤੁਹਾਡਾ ਸੁਆਗਤ ਹੈ, ਤੁਹਾਡੇ Windows 11 ਅਨੁਭਵ ਨੂੰ ਵਧਾਉਣ ਲਈ ਇੱਕ - ਇਨਕੋਪੋਰੇਟਿਡ ਟਾਈਲਿੰਗ ਵਿੰਡੋਜ਼ ਮੈਨੇਜਰ ਦੇ ਨਾਲ ਅੰਤਮ ਡੈਸਕਟਾਪ ਵਾਤਾਵਰਨ! ਸਾਡੇ ਅਨੁਭਵੀ - ਇੰਟਰਫੇਸ ਅਤੇ ਉੱਨਤ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨਾਲ ਕੁਸ਼ਲਤਾ ਅਤੇ ਮਲਟੀਟਾਸਕਿੰਗ ਦੇ ਇੱਕ ਨਵੇਂ ਯੁੱਗ - ਦੀ ਪੜਚੋਲ ਕਰੋ। - message_accent: ਸ਼ੈਲੀ ਨਾਲ ਆਪਣੀ ਉਤਪਾਦਕਤਾ ਨੂੰ ਅਨੁਕੂਲ ਬਣਾਓ! - title: ਜੀ ਆਇਆਂ ਨੂੰ! -general: - theme: - description: ਵਰਣਨ - placeholder: ਥੀਮ ਚੁਣੋ - enabled: ਸਮਰਥਿਤ ਥੀਮ - add: ਥੀਮ ਸ਼ਾਮਲ ਕਰੋ - tags: ਟੈਗਸ - author: ਲੇਖਕ - added: ਥੀਮ ਪਹਿਲਾਂ ਹੀ ਸ਼ਾਮਲ ਕੀਤੀ ਗਈ ਹੈ - label: ਥੀਮ ਜਾਣਕਾਰੀ - available: ਉਪਲੱਬਧ - selected: ਚੁਣਿਆ ਹੋਇਆ - language: ਭਾਸ਼ਾ - startup: ਸਟਾਰਟਅੱਪ 'ਤੇ ਚਲਾਉਣਾ? - icon_pack: - label: ਆਈਕਾਨ ਪੈਕ - accent_color: ਲਹਿਜ਼ਾ ਰੰਗ ਦਾ ਰੰਗ -toolbar: - placeholder: - description: ਵਰਣਨ - select: ਟੂਲਬਾਰ ਢਾਂਚਾ - author: ਲੇਖਕ - height: ਉਚਾਈ - enable: ਫੈਂਸੀ ਟੂਲਬਾਰ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ -wm: - border: - offset: ਬਾਰਡਰ ਆਫਸੈੱਟ - enable: ਵਿੰਡੋ ਦੇ ਬਾਰਡਰ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ - width: ਬਾਰਡਰ ਚੌੜਾਈ - description: ਵਰਣਨ - workspace_offset: ਵਰਕਸਪੇਸ ਆਫਸੈੱਟ (ਮਾਰਜਿਨ) - author: ਲੇਖਕ - space_between_containers: ਕੰਟੇਨਰਾਂ ਵਿਚਕਾਰ ਸਪੇਸ - resize_delta: ਡੈਲਟਾ ਦਾ ਆਕਾਰ ਬਦਲੋ (%) - enable: ਵਿੰਡੋ ਮੈਨੇਜਰ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ - workspace_padding: ਵਰਕਸਪੇਸ ਪੈਡਿੰਗ - disabled_windows10: ਵਿੰਡੋ ਮੈਨੇਜਰ ਵਿੰਡੋਜ਼ 10 ਲਈ ਉਪਲਬਧ ਨਹੀਂ ਹੈ। - layout: ਖਾਕਾ -weg: - items: - label: ਇਕਾਈ - gap: ਆਈਟਮਾਂ ਵਿਚਕਾਰ ਸਪੇਸ - size: ਆਈਟਮ ਦਾ ਆਕਾਰ - zoom_size: ਜ਼ੂਮ ਕੀਤਾ ਆਕਾਰ (ਥੀਮਾਂ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ) - visible_separators: ਦਿਖਣਯੋਗ ਵਿਭਾਜਕ - enable: ਡੌਕ/ਟਾਸਕਬਾਰ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ - padding: ਪੈਡਿੰਗ - dock_side: ਡੌਕ ਸਾਈਡ - auto_hide: ਆਟੋ ਓਹਲੇ - gap: ਪਾੜਾ - width: ਚੌੜਾਈ - margin: ਹਾਸ਼ੀਏ - label: ਡੌਕ/ਟਾਸਕਬਾਰ -devtools: - load: ਲੋਡ ਕਰੋ - settings_file: ਸੈਟਿੰਗਜ਼ ਫਾਈਲ - enable: ਡਿਵੈਲਪਰ ਟੂਲਸ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ - data_folder: ਡਾਟਾ ਫੋਲਡਰ - app_folders: ਐਪ ਫੋਲਡਰ - custom_config_file: ਕਸਟਮ ਕੌਂਫਿਗ ਫਾਈਲ ਲੋਡ ਕਰੋ - install_folder: ਇੰਸਟਾਲੇਸ਼ਨ ਫੋਲਡਰ -apps_configurations: - app: - options: - float: ਫਲੋਟ - pinned: ਪਿੰਨ ਕੀਤਾ - unmanage: ਅਪ੍ਰਬੰਧਿਤ ਕਰੋ - force: ਫੋਰਸ ਪ੍ਰਬੰਧਨ - category: ਸ਼੍ਰੇਣੀ - bindings: ਬਾਈਡਿੰਗ (ਨੋਟ ਕਰੋ ਕਿ ਦੋਵੇਂ ਵਿਕਲਪ ਲੋੜੀਂਦੇ ਹਨ) - monitor_placeholder: ਕੋਈ ਨਹੀਂ - title_readonly: '{{name}} ਦੇਖ ਰਹੇ ਹਾਂ' - ok_readonly: ਨਵੇਂ ਵਜੋਂ ਸੰਪਾਦਿਤ ਕਰੋ - workspace: ਵਰਕਸਪੇਸ - name: ਨਾਮ - workspace_placeholder: ਕੋਈ ਨਹੀਂ - title_edit: ਸੰਪਾਦਨ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ {{name}} - ok_create: ਬਣਾਓ - category_placeholder: ਕੋਈ ਨਹੀਂ - ok_edit: ਅਪਡੇਟ - monitor: ਮਾਨੀਟਰ - title_create: '{{name}} ਬਣਾਉਣਾ' - options_label: ਵਾਧੂ ਵਿਕਲਪ - identifier: - kind: ਦੁਆਰਾ ਪਛਾਣੋ - id: ਪਛਾਣਕਰਤਾ - or: ਜਾਂ - and: ਅਤੇ - matching_strategy: ਮੈਚਿੰਗ ਰਣਨੀਤੀ - remove: ਬਲਾਕ ਮਿਟਾਓ - negation: ਨੈਗੇਟ ਮੈਚਿੰਗ - add_block: ਬਲਾਕ ਸ਼ਾਮਲ ਕਰੋ - confirm_delete: ਕੀ ਤੁਸੀਂ ਯਕੀਨੀ ਤੌਰ 'ਤੇ ਇਸ ਸੰਰਚਨਾ/s ਨੂੰ ਮਿਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? - export: ਨਿਰਯਾਤ - confirm_delete_title: ਮਿਟਾਉਣ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ - bundled_msg: >- - ਇਹ ਬੰਡਲ ਕੀਤੀਆਂ ਸੰਰਚਨਾਵਾਂ ਸੰਪਾਦਨਯੋਗ ਨਹੀਂ ਹਨ ਅਤੇ ਤੁਹਾਨੂੰ ਅਨੁਕੂਲਿਤ ਕੀਤੇ ਬਿਨਾਂ - ਵਧੀਆ ਅਨੁਭਵ ਪ੍ਰਦਾਨ ਕਰਨ ਲਈ ਤਿਆਰ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ। ਉਹ ਤੁਹਾਡੇ ਲਈ ਸਭ ਤੋਂ ਆਮ - ਐਪਲੀਕੇਸ਼ਨਾਂ ਨੂੰ ਸਵੈਚਲਿਤ ਤੌਰ 'ਤੇ ਕੌਂਫਿਗਰ ਕਰਦੇ ਹਨ। - delete: ਮਿਟਾਓ - swap: ਸਵੈਪ - search: ਖੋਜ - new: ਨਵਾਂ - bundled_title: ਐਪ ਕੌਂਫਿਗ ਸੀਲੇਨ ਨਾਲ ਬੰਡਲ ਕੀਤੀ ਗਈ - import: ਆਯਾਤ ਕਰੋ -extras: - discord: ਵਿਵਾਦ - links: ਅਧਿਕਾਰਤ ਲਿੰਕ - exit: ਛੱਡੋ/ਬਾਹਰ ਨਿਕਲੋ - relaunch: ਮੁੜ-ਲਾਂਚ ਕਰੋ - github: GitHub - version: ਸੰਸਕਰਣ -shortcuts: - labels: - switch_workspace_7: ਵਰਕਸਪੇਸ 7 'ਤੇ ਜਾਓ - reserve_stack: ਰਿਜ਼ਰਵ ਸਟੈਕ - decrease_width: ਚੌੜਾਈ ਘਟਾਓ - decrease_height: ਉਚਾਈ ਘਟਾਓ - reserve_right: ਰਾਖਵਾਂ ਅਧਿਕਾਰ - reserve_top: ਰਿਜ਼ਰਵ ਸਿਖਰ - switch_workspace_9: ਵਰਕਸਪੇਸ 9 'ਤੇ ਜਾਓ - switch_workspace_8: ਵਰਕਸਪੇਸ 8 'ਤੇ ਜਾਓ - reserve_left: ਖੱਬੇ ਪਾਸੇ ਰਾਖਵਾਂ ਕਰੋ - switch_workspace_5: ਵਰਕਸਪੇਸ 5 'ਤੇ ਜਾਓ - increase_width: ਚੌੜਾਈ ਵਧਾਓ - send_to_workspace_8: ਵਰਕਸਪੇਸ 8 'ਤੇ ਭੇਜੋ - switch_workspace_4: ਵਰਕਸਪੇਸ 4 'ਤੇ ਜਾਓ - move_to_workspace_3: ਵਰਕਸਪੇਸ 3 'ਤੇ ਜਾਓ - focus_bottom: ਹੇਠਾਂ ਫੋਕਸ ਕਰੋ - switch_workspace_3: ਵਰਕਸਪੇਸ 3 'ਤੇ ਜਾਓ - focus_top: ਫੋਕਸ ਸਿਖਰ - move_to_workspace_8: ਵਰਕਸਪੇਸ 8 'ਤੇ ਜਾਓ - send_to_workspace_6: ਵਰਕਸਪੇਸ 6 'ਤੇ ਭੇਜੋ - reserve_bottom: ਹੇਠਾਂ ਰਿਜ਼ਰਵ ਕਰੋ - switch_workspace_2: ਵਰਕਸਪੇਸ 2 'ਤੇ ਜਾਓ - move_to_workspace_0: ਵਰਕਸਪੇਸ 0 'ਤੇ ਜਾਓ - send_to_workspace_1: ਵਰਕਸਪੇਸ 1 'ਤੇ ਭੇਜੋ - switch_workspace_0: ਵਰਕਸਪੇਸ 0 'ਤੇ ਜਾਓ - send_to_workspace_7: ਵਰਕਸਪੇਸ 7 'ਤੇ ਭੇਜੋ - send_to_workspace_3: ਵਰਕਸਪੇਸ 3 'ਤੇ ਭੇਜੋ - move_to_workspace_1: ਵਰਕਸਪੇਸ 1 ਤੇ ਜਾਓ - move_to_workspace_6: ਵਰਕਸਪੇਸ 6 ਤੇ ਜਾਓ - move_to_workspace_7: ਵਰਕਸਪੇਸ 7 'ਤੇ ਜਾਓ - restore_sizes: ਆਕਾਰ ਰੀਸਟੋਰ ਕਰੋ - increase_height: ਉਚਾਈ ਵਧਾਓ - send_to_workspace_5: ਵਰਕਸਪੇਸ 5 'ਤੇ ਭੇਜੋ - switch_workspace_1: ਵਰਕਸਪੇਸ 1 'ਤੇ ਜਾਓ - focus_left: ਖੱਬੇ ਪਾਸੇ ਫੋਕਸ ਕਰੋ - move_to_workspace_4: ਵਰਕਸਪੇਸ 4 'ਤੇ ਜਾਓ - send_to_workspace_0: ਵਰਕਸਪੇਸ 0 'ਤੇ ਭੇਜੋ - focus_right: ਸੱਜੇ ਫੋਕਸ ਕਰੋ - send_to_workspace_2: ਵਰਕਸਪੇਸ 2 'ਤੇ ਭੇਜੋ - send_to_workspace_9: ਵਰਕਸਪੇਸ 9 'ਤੇ ਭੇਜੋ - move_to_workspace_5: ਵਰਕਸਪੇਸ 5 'ਤੇ ਜਾਓ - move_to_workspace_9: ਵਰਕਸਪੇਸ 9 'ਤੇ ਜਾਓ - send_to_workspace_4: ਵਰਕਸਪੇਸ 4 'ਤੇ ਭੇਜੋ - reserve_float: ਰਿਜ਼ਰਵ ਫਲੋਟ - move_to_workspace_2: ਵਰਕਸਪੇਸ 2 'ਤੇ ਜਾਓ - focus_latest: ਫੋਕਸ ਤਾਜ਼ਾ - switch_workspace_6: ਵਰਕਸਪੇਸ 6 'ਤੇ ਜਾਓ - enable_tooltip: >- - ਅਸਮਰੱਥ ਕਰੋ ਜੇਕਰ ਤੁਸੀਂ ਸੀਲੇਨ ਕੋਰ ਏਪੀਆਈ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਆਪਣੇ ਖੁਦ ਦੇ ਸ਼ਾਰਟਕੱਟ - ਲਾਗੂ ਕਰਦੇ ਹੋ - enable: ਏਕੀਕ੍ਰਿਤ ਸ਼ਾਰਟਕੱਟ (ahk) ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ -open: ਖੋਲ੍ਹੋ -loading: ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ... -save: ਸੇਵ ਕਰੋ -delete: ਮਿਟਾਓ -inProgress: ਤਰੱਕੀ ਹੋ ਰਹੀ ਹੈ... -cancel: ਰੱਦ ਕਰੋ -quit: ਛੱਡੋ +sides: + left: ਖੱਬੇ + bottom: ਹੇਠਾਂ + top: ਸਿਖਰ + right: ਸੱਜਾ +header: + labels: + general: ਜਨਰਲ + seelen_wm: ਵਿੰਡੋ ਮੈਨੇਜਰ + seelen_bar: ਫੈਂਸੀ ਟੂਲਬਾਰ + monitors: ਨਿਗਰਾਨੀ ਕਰਦਾ ਹੈ + specific_apps: ਖਾਸ ਐਪਸ + shortcuts: ਸ਼ਾਰਟਕੱਟ + info: ਜਾਣਕਾਰੀ + developer: ਵਿਕਾਸਕਾਰ + seelen_weg: ਡੌਕ/ਟਾਸਕਬਾਰ +start: + message: >- + Seelen UI ਵਿੱਚ ਤੁਹਾਡਾ ਸੁਆਗਤ ਹੈ, ਤੁਹਾਡੇ Windows 11 ਅਨੁਭਵ ਨੂੰ ਵਧਾਉਣ ਲਈ ਇੱਕ + ਇਨਕੋਪੋਰੇਟਿਡ ਟਾਈਲਿੰਗ ਵਿੰਡੋਜ਼ ਮੈਨੇਜਰ ਦੇ ਨਾਲ ਅੰਤਮ ਡੈਸਕਟਾਪ ਵਾਤਾਵਰਨ! ਸਾਡੇ ਅਨੁਭਵੀ + ਇੰਟਰਫੇਸ ਅਤੇ ਉੱਨਤ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨਾਲ ਕੁਸ਼ਲਤਾ ਅਤੇ ਮਲਟੀਟਾਸਕਿੰਗ ਦੇ ਇੱਕ ਨਵੇਂ ਯੁੱਗ + ਦੀ ਪੜਚੋਲ ਕਰੋ। + message_accent: ਸ਼ੈਲੀ ਨਾਲ ਆਪਣੀ ਉਤਪਾਦਕਤਾ ਨੂੰ ਅਨੁਕੂਲ ਬਣਾਓ! + title: ਜੀ ਆਇਆਂ ਨੂੰ! +general: + theme: + description: ਵਰਣਨ + placeholder: ਥੀਮ ਚੁਣੋ + enabled: ਸਮਰਥਿਤ ਥੀਮ + add: ਥੀਮ ਸ਼ਾਮਲ ਕਰੋ + tags: ਟੈਗਸ + author: ਲੇਖਕ + added: ਥੀਮ ਪਹਿਲਾਂ ਹੀ ਸ਼ਾਮਲ ਕੀਤੀ ਗਈ ਹੈ + label: ਥੀਮ ਜਾਣਕਾਰੀ + available: ਉਪਲੱਬਧ + selected: ਚੁਣਿਆ ਹੋਇਆ + language: ਭਾਸ਼ਾ + startup: ਸਟਾਰਟਅੱਪ 'ਤੇ ਚਲਾਉਣਾ? + icon_pack: + label: ਆਈਕਾਨ ਪੈਕ + accent_color: ਲਹਿਜ਼ਾ ਰੰਗ ਦਾ ਰੰਗ +toolbar: + placeholder: + description: ਵਰਣਨ + select: ਟੂਲਬਾਰ ਢਾਂਚਾ + author: ਲੇਖਕ + height: ਉਚਾਈ + enable: ਫੈਂਸੀ ਟੂਲਬਾਰ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ +wm: + border: + offset: ਬਾਰਡਰ ਆਫਸੈੱਟ + enable: ਵਿੰਡੋ ਦੇ ਬਾਰਡਰ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ + width: ਬਾਰਡਰ ਚੌੜਾਈ + description: ਵਰਣਨ + workspace_offset: ਵਰਕਸਪੇਸ ਆਫਸੈੱਟ (ਮਾਰਜਿਨ) + author: ਲੇਖਕ + space_between_containers: ਕੰਟੇਨਰਾਂ ਵਿਚਕਾਰ ਸਪੇਸ + resize_delta: ਡੈਲਟਾ ਦਾ ਆਕਾਰ ਬਦਲੋ (%) + enable: ਵਿੰਡੋ ਮੈਨੇਜਰ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ + workspace_padding: ਵਰਕਸਪੇਸ ਪੈਡਿੰਗ + disabled_windows10: ਵਿੰਡੋ ਮੈਨੇਜਰ ਵਿੰਡੋਜ਼ 10 ਲਈ ਉਪਲਬਧ ਨਹੀਂ ਹੈ। + layout: ਖਾਕਾ +weg: + items: + label: ਇਕਾਈ + gap: ਆਈਟਮਾਂ ਵਿਚਕਾਰ ਸਪੇਸ + size: ਆਈਟਮ ਦਾ ਆਕਾਰ + zoom_size: ਜ਼ੂਮ ਕੀਤਾ ਆਕਾਰ (ਥੀਮਾਂ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ) + visible_separators: ਦਿਖਣਯੋਗ ਵਿਭਾਜਕ + enable: ਡੌਕ/ਟਾਸਕਬਾਰ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ + padding: ਪੈਡਿੰਗ + dock_side: ਡੌਕ ਸਾਈਡ + auto_hide: ਆਟੋ ਓਹਲੇ + gap: ਪਾੜਾ + width: ਚੌੜਾਈ + margin: ਹਾਸ਼ੀਏ + label: ਡੌਕ/ਟਾਸਕਬਾਰ +devtools: + load: ਲੋਡ ਕਰੋ + settings_file: ਸੈਟਿੰਗਜ਼ ਫਾਈਲ + enable: ਡਿਵੈਲਪਰ ਟੂਲਸ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ + data_folder: ਡਾਟਾ ਫੋਲਡਰ + app_folders: ਐਪ ਫੋਲਡਰ + custom_config_file: ਕਸਟਮ ਕੌਂਫਿਗ ਫਾਈਲ ਲੋਡ ਕਰੋ + install_folder: ਇੰਸਟਾਲੇਸ਼ਨ ਫੋਲਡਰ +apps_configurations: + app: + options: + float: ਫਲੋਟ + pinned: ਪਿੰਨ ਕੀਤਾ + unmanage: ਅਪ੍ਰਬੰਧਿਤ ਕਰੋ + force: ਫੋਰਸ ਪ੍ਰਬੰਧਨ + category: ਸ਼੍ਰੇਣੀ + bindings: ਬਾਈਡਿੰਗ (ਨੋਟ ਕਰੋ ਕਿ ਦੋਵੇਂ ਵਿਕਲਪ ਲੋੜੀਂਦੇ ਹਨ) + monitor_placeholder: ਕੋਈ ਨਹੀਂ + title_readonly: '{{name}} ਦੇਖ ਰਹੇ ਹਾਂ' + ok_readonly: ਨਵੇਂ ਵਜੋਂ ਸੰਪਾਦਿਤ ਕਰੋ + workspace: ਵਰਕਸਪੇਸ + name: ਨਾਮ + workspace_placeholder: ਕੋਈ ਨਹੀਂ + title_edit: ਸੰਪਾਦਨ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ {{name}} + ok_create: ਬਣਾਓ + category_placeholder: ਕੋਈ ਨਹੀਂ + ok_edit: ਅਪਡੇਟ + monitor: ਮਾਨੀਟਰ + title_create: '{{name}} ਬਣਾਉਣਾ' + options_label: ਵਾਧੂ ਵਿਕਲਪ + identifier: + kind: ਦੁਆਰਾ ਪਛਾਣੋ + id: ਪਛਾਣਕਰਤਾ + or: ਜਾਂ + and: ਅਤੇ + matching_strategy: ਮੈਚਿੰਗ ਰਣਨੀਤੀ + remove: ਬਲਾਕ ਮਿਟਾਓ + negation: ਨੈਗੇਟ ਮੈਚਿੰਗ + add_block: ਬਲਾਕ ਸ਼ਾਮਲ ਕਰੋ + confirm_delete: ਕੀ ਤੁਸੀਂ ਯਕੀਨੀ ਤੌਰ 'ਤੇ ਇਸ ਸੰਰਚਨਾ/s ਨੂੰ ਮਿਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? + export: ਨਿਰਯਾਤ + confirm_delete_title: ਮਿਟਾਉਣ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ + bundled_msg: >- + ਇਹ ਬੰਡਲ ਕੀਤੀਆਂ ਸੰਰਚਨਾਵਾਂ ਸੰਪਾਦਨਯੋਗ ਨਹੀਂ ਹਨ ਅਤੇ ਤੁਹਾਨੂੰ ਅਨੁਕੂਲਿਤ ਕੀਤੇ ਬਿਨਾਂ + ਵਧੀਆ ਅਨੁਭਵ ਪ੍ਰਦਾਨ ਕਰਨ ਲਈ ਤਿਆਰ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ। ਉਹ ਤੁਹਾਡੇ ਲਈ ਸਭ ਤੋਂ ਆਮ + ਐਪਲੀਕੇਸ਼ਨਾਂ ਨੂੰ ਸਵੈਚਲਿਤ ਤੌਰ 'ਤੇ ਕੌਂਫਿਗਰ ਕਰਦੇ ਹਨ। + delete: ਮਿਟਾਓ + swap: ਸਵੈਪ + search: ਖੋਜ + new: ਨਵਾਂ + bundled_title: ਐਪ ਕੌਂਫਿਗ ਸੀਲੇਨ ਨਾਲ ਬੰਡਲ ਕੀਤੀ ਗਈ + import: ਆਯਾਤ ਕਰੋ +extras: + discord: ਵਿਵਾਦ + links: ਅਧਿਕਾਰਤ ਲਿੰਕ + exit: ਛੱਡੋ/ਬਾਹਰ ਨਿਕਲੋ + relaunch: ਮੁੜ-ਲਾਂਚ ਕਰੋ + github: GitHub + version: ਸੰਸਕਰਣ +shortcuts: + labels: + switch_workspace_7: ਵਰਕਸਪੇਸ 7 'ਤੇ ਜਾਓ + reserve_stack: ਰਿਜ਼ਰਵ ਸਟੈਕ + decrease_width: ਚੌੜਾਈ ਘਟਾਓ + decrease_height: ਉਚਾਈ ਘਟਾਓ + reserve_right: ਰਾਖਵਾਂ ਅਧਿਕਾਰ + reserve_top: ਰਿਜ਼ਰਵ ਸਿਖਰ + switch_workspace_9: ਵਰਕਸਪੇਸ 9 'ਤੇ ਜਾਓ + switch_workspace_8: ਵਰਕਸਪੇਸ 8 'ਤੇ ਜਾਓ + reserve_left: ਖੱਬੇ ਪਾਸੇ ਰਾਖਵਾਂ ਕਰੋ + switch_workspace_5: ਵਰਕਸਪੇਸ 5 'ਤੇ ਜਾਓ + increase_width: ਚੌੜਾਈ ਵਧਾਓ + send_to_workspace_8: ਵਰਕਸਪੇਸ 8 'ਤੇ ਭੇਜੋ + switch_workspace_4: ਵਰਕਸਪੇਸ 4 'ਤੇ ਜਾਓ + move_to_workspace_3: ਵਰਕਸਪੇਸ 3 'ਤੇ ਜਾਓ + focus_bottom: ਹੇਠਾਂ ਫੋਕਸ ਕਰੋ + switch_workspace_3: ਵਰਕਸਪੇਸ 3 'ਤੇ ਜਾਓ + focus_top: ਫੋਕਸ ਸਿਖਰ + move_to_workspace_8: ਵਰਕਸਪੇਸ 8 'ਤੇ ਜਾਓ + send_to_workspace_6: ਵਰਕਸਪੇਸ 6 'ਤੇ ਭੇਜੋ + reserve_bottom: ਹੇਠਾਂ ਰਿਜ਼ਰਵ ਕਰੋ + switch_workspace_2: ਵਰਕਸਪੇਸ 2 'ਤੇ ਜਾਓ + move_to_workspace_0: ਵਰਕਸਪੇਸ 0 'ਤੇ ਜਾਓ + send_to_workspace_1: ਵਰਕਸਪੇਸ 1 'ਤੇ ਭੇਜੋ + switch_workspace_0: ਵਰਕਸਪੇਸ 0 'ਤੇ ਜਾਓ + send_to_workspace_7: ਵਰਕਸਪੇਸ 7 'ਤੇ ਭੇਜੋ + send_to_workspace_3: ਵਰਕਸਪੇਸ 3 'ਤੇ ਭੇਜੋ + move_to_workspace_1: ਵਰਕਸਪੇਸ 1 ਤੇ ਜਾਓ + move_to_workspace_6: ਵਰਕਸਪੇਸ 6 ਤੇ ਜਾਓ + move_to_workspace_7: ਵਰਕਸਪੇਸ 7 'ਤੇ ਜਾਓ + restore_sizes: ਆਕਾਰ ਰੀਸਟੋਰ ਕਰੋ + increase_height: ਉਚਾਈ ਵਧਾਓ + send_to_workspace_5: ਵਰਕਸਪੇਸ 5 'ਤੇ ਭੇਜੋ + switch_workspace_1: ਵਰਕਸਪੇਸ 1 'ਤੇ ਜਾਓ + focus_left: ਖੱਬੇ ਪਾਸੇ ਫੋਕਸ ਕਰੋ + move_to_workspace_4: ਵਰਕਸਪੇਸ 4 'ਤੇ ਜਾਓ + send_to_workspace_0: ਵਰਕਸਪੇਸ 0 'ਤੇ ਭੇਜੋ + focus_right: ਸੱਜੇ ਫੋਕਸ ਕਰੋ + send_to_workspace_2: ਵਰਕਸਪੇਸ 2 'ਤੇ ਭੇਜੋ + send_to_workspace_9: ਵਰਕਸਪੇਸ 9 'ਤੇ ਭੇਜੋ + move_to_workspace_5: ਵਰਕਸਪੇਸ 5 'ਤੇ ਜਾਓ + move_to_workspace_9: ਵਰਕਸਪੇਸ 9 'ਤੇ ਜਾਓ + send_to_workspace_4: ਵਰਕਸਪੇਸ 4 'ਤੇ ਭੇਜੋ + reserve_float: ਰਿਜ਼ਰਵ ਫਲੋਟ + move_to_workspace_2: ਵਰਕਸਪੇਸ 2 'ਤੇ ਜਾਓ + focus_latest: ਫੋਕਸ ਤਾਜ਼ਾ + switch_workspace_6: ਵਰਕਸਪੇਸ 6 'ਤੇ ਜਾਓ + enable_tooltip: >- + ਅਸਮਰੱਥ ਕਰੋ ਜੇਕਰ ਤੁਸੀਂ ਸੀਲੇਨ ਕੋਰ ਏਪੀਆਈ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਆਪਣੇ ਖੁਦ ਦੇ ਸ਼ਾਰਟਕੱਟ + ਲਾਗੂ ਕਰਦੇ ਹੋ + enable: ਏਕੀਕ੍ਰਿਤ ਸ਼ਾਰਟਕੱਟ (ahk) ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ +open: ਖੋਲ੍ਹੋ +loading: ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ... +save: ਸੇਵ ਕਰੋ +delete: ਮਿਟਾਓ +inProgress: ਤਰੱਕੀ ਹੋ ਰਹੀ ਹੈ... +cancel: ਰੱਦ ਕਰੋ +quit: ਛੱਡੋ diff --git a/src/apps/settings/i18n/translations/pl.yml b/src/apps/settings/i18n/translations/pl.yml index 7ccb2600..4c2fe78f 100644 --- a/src/apps/settings/i18n/translations/pl.yml +++ b/src/apps/settings/i18n/translations/pl.yml @@ -1,193 +1,193 @@ -sides: - left: Lewy - right: Prawidłowy - top: Szczyt - bottom: Spód -header: - labels: - general: Ogólny - info: Informacja - developer: Deweloper - monitors: Monitory - seelen_weg: Dock/Pasek zadań - specific_apps: Określone aplikacje - seelen_bar: Fancy narzędzi - shortcuts: Skróty - seelen_wm: Menedżer okien -start: - title: Powitanie! - message: >- - Witamy w Seelen UI, ostatecznym środowisku komputerowym z włączonym - menedżerem Windows Windows, aby poprawić Twoje wrażenia z systemu Windows - 11! Przeglądaj nową erę wydajności i wielozadaniowości z naszym intuicyjnym - interfejsem i zaawansowanymi funkcjami. - message_accent: Zoptymalizuj swoją wydajność za pomocą stylu! -general: - theme: - description: Opis - author: Autor - enabled: Włączone motywy - placeholder: Wybierz motyw - added: Motyw już dodany - add: Dodaj motyw - tags: Tagi - label: Informacje o motywie - selected: Wybrany - available: Dostępny - language: Język - startup: Biegać na startup? - icon_pack: - label: Pakiety ikony - accent_color: Kolor akcentu -toolbar: - placeholder: - author: Autor - description: Opis - select: Struktura paska narzędzi - height: Wysokość - enable: Włącz fantazyjny pasek narzędzi -wm: - border: - width: Szerokość granicy - enable: Włącz granicę okna - offset: Przesunięcie granic - author: Autor - layout: Układ - description: Opis - disabled_windows10: Menedżer okien nie jest dostępny dla systemu Windows 10. - space_between_containers: Przestrzeń między pojemnikami - enable: Włącz menedżer okien - workspace_padding: Wypadki przestrzeni roboczej - resize_delta: Zmień rozmiar Delta (%) - workspace_offset: Przestrzenie robocze przesunięte (marginesy) -weg: - items: - label: Rzeczy - zoom_size: Powiększony rozmiar (używany do motywów) - gap: Przestrzeń między przedmiotami - size: Rozmiar elementu - visible_separators: Widoczne separatory - auto_hide: Automatyczne chowanie - padding: Wyściółka - gap: Luka - width: Szerokość - enable: Włącz dok/pasek zadań - margin: Margines - label: Dock/Pasek zadań - dock_side: Strona dokująca -devtools: - load: Obciążenie - custom_config_file: Załaduj niestandardowy plik konfiguracyjny - app_folders: Foldery aplikacji - settings_file: Plik ustawień - enable: Włącz narzędzia programistów - data_folder: Folder danych - install_folder: Folder instalacyjny -apps_configurations: - app: - options: - float: Platforma - force: Siła zarządza - pinned: Przypięty - unmanage: Niezarządzanie - name: Nazwa - category_placeholder: Nic - ok_edit: Aktualizacja - ok_create: Tworzyć - category: Kategoria - monitor_placeholder: Nic - title_readonly: Przeglądanie {{Nazwa}} - workspace_placeholder: Nic - ok_readonly: Edytuj jako nowy - title_edit: Edycja {{nazwa}} - monitor: Monitor - options_label: Dodatkowe opcje - workspace: Obszar roboczy - bindings: Wiązanie (wymagane są obie opcje) - title_create: Tworzenie {{nazwa}} - identifier: - and: I - or: LUB - id: Identyfikator - remove: Usuń blok - matching_strategy: Strategia dopasowywania - add_block: Dodaj blok - negation: Negate dopasowanie - kind: Identyfikować się przez - swap: Zamieniać - export: Eksport - new: Nowy - delete: Usuwać - confirm_delete_title: Potwierdź usunięcie - import: Import - search: Szukaj - confirm_delete: Czy na pewno chcesz usunąć tę konfigurację/s? - bundled_title: App Config w pakiecie z Seelen - bundled_msg: >- - Te konfiguracje pakietowe nie są edytowalne i mają na celu zapewnienie - najlepszych wrażeń bez dostosowywania. Automatycznie konfigurują dla Ciebie - najczęstsze aplikacje. -extras: - relaunch: Wznowienie - version: Wersja - github: Github - discord: Niezgoda - exit: Wyjdź/wyjdź - links: Oficjalne linki -shortcuts: - labels: - focus_latest: Focus najnowszy - switch_workspace_6: Przejdź na przestrzeń roboczą 6 - switch_workspace_7: Przełącz się na przestrzeń roboczą 7 - send_to_workspace_2: Wyślij na przestrzeń roboczą 2 - reserve_stack: Stos rezerwowy - increase_height: Zwiększyć wysokość - decrease_height: Zmniejszyć wysokość - move_to_workspace_6: Przenieś się do obszaru roboczego 6 - move_to_workspace_1: Przenieś się do obszaru roboczego 1 - switch_workspace_5: Przełącz się na przestrzeń roboczą 5 - move_to_workspace_0: Przenieś się do obszaru roboczego 0 - move_to_workspace_3: Przenieś się do obszaru roboczego 3 - move_to_workspace_4: Przenieś się do obszaru roboczego 4 - send_to_workspace_9: Wyślij do obszaru roboczego 9 - send_to_workspace_8: Wyślij na przestrzeń roboczą 8 - move_to_workspace_2: Przenieś się do obszaru roboczego 2 - decrease_width: Zmniejszyć szerokość - send_to_workspace_3: Wyślij do obszaru roboczego 3 - switch_workspace_4: Przełącz się na przestrzeń roboczą 4 - focus_right: Skup się dobrze - send_to_workspace_6: Wyślij do obszaru roboczego 6 - send_to_workspace_0: Wyślij do obszaru roboczego 0 - focus_bottom: Focus Dim - send_to_workspace_5: Wyślij do obszaru roboczego 5 - switch_workspace_0: Przejdź na obszar roboczy 0 - reserve_bottom: Rezerwować dno - send_to_workspace_4: Wyślij na przestrzeń roboczą 4 - reserve_top: Rezerwuj top - focus_left: Skup się na lewej - move_to_workspace_7: Przenieś się do obszaru roboczego 7 - switch_workspace_8: Przełącz się na przestrzeń roboczą 8 - switch_workspace_9: Przejdź na obszar roboczy 9 - switch_workspace_2: Przełącz się na przestrzeń roboczą 2 - switch_workspace_1: Przejdź na obszar roboczy 1 - reserve_float: Rezerwować pływak - move_to_workspace_5: Przenieś się do obszaru roboczego 5 - move_to_workspace_8: Przenieś się do obszaru roboczego 8 - restore_sizes: Przywróć rozmiary - reserve_right: Rezerwuj prawnie - reserve_left: Rezerwa w lewo - switch_workspace_3: Przełącz się na przestrzeń roboczą 3 - increase_width: Zwiększyć szerokość - focus_top: Focus Top - move_to_workspace_9: Przenieś się do obszaru roboczego 9 - send_to_workspace_1: Wyślij do obszaru roboczego 1 - send_to_workspace_7: Wyślij na przestrzeń roboczą 7 - enable_tooltip: Wyłącz, jeśli zaimplementujesz własne skróty za pomocą API Seelen Core - enable: Włącz zintegrowane skróty (AHK) -loading: Ładowanie... -quit: Zrezygnować -inProgress: W trakcie... -delete: Usuwać -cancel: Anulować -save: Ratować -open: otwarty +sides: + left: Lewy + right: Prawidłowy + top: Szczyt + bottom: Spód +header: + labels: + general: Ogólny + info: Informacja + developer: Deweloper + monitors: Monitory + seelen_weg: Dock/Pasek zadań + specific_apps: Określone aplikacje + seelen_bar: Fancy narzędzi + shortcuts: Skróty + seelen_wm: Menedżer okien +start: + title: Powitanie! + message: >- + Witamy w Seelen UI, ostatecznym środowisku komputerowym z włączonym + menedżerem Windows Windows, aby poprawić Twoje wrażenia z systemu Windows + 11! Przeglądaj nową erę wydajności i wielozadaniowości z naszym intuicyjnym + interfejsem i zaawansowanymi funkcjami. + message_accent: Zoptymalizuj swoją wydajność za pomocą stylu! +general: + theme: + description: Opis + author: Autor + enabled: Włączone motywy + placeholder: Wybierz motyw + added: Motyw już dodany + add: Dodaj motyw + tags: Tagi + label: Informacje o motywie + selected: Wybrany + available: Dostępny + language: Język + startup: Biegać na startup? + icon_pack: + label: Pakiety ikony + accent_color: Kolor akcentu +toolbar: + placeholder: + author: Autor + description: Opis + select: Struktura paska narzędzi + height: Wysokość + enable: Włącz fantazyjny pasek narzędzi +wm: + border: + width: Szerokość granicy + enable: Włącz granicę okna + offset: Przesunięcie granic + author: Autor + layout: Układ + description: Opis + disabled_windows10: Menedżer okien nie jest dostępny dla systemu Windows 10. + space_between_containers: Przestrzeń między pojemnikami + enable: Włącz menedżer okien + workspace_padding: Wypadki przestrzeni roboczej + resize_delta: Zmień rozmiar Delta (%) + workspace_offset: Przestrzenie robocze przesunięte (marginesy) +weg: + items: + label: Rzeczy + zoom_size: Powiększony rozmiar (używany do motywów) + gap: Przestrzeń między przedmiotami + size: Rozmiar elementu + visible_separators: Widoczne separatory + auto_hide: Automatyczne chowanie + padding: Wyściółka + gap: Luka + width: Szerokość + enable: Włącz dok/pasek zadań + margin: Margines + label: Dock/Pasek zadań + dock_side: Strona dokująca +devtools: + load: Obciążenie + custom_config_file: Załaduj niestandardowy plik konfiguracyjny + app_folders: Foldery aplikacji + settings_file: Plik ustawień + enable: Włącz narzędzia programistów + data_folder: Folder danych + install_folder: Folder instalacyjny +apps_configurations: + app: + options: + float: Platforma + force: Siła zarządza + pinned: Przypięty + unmanage: Niezarządzanie + name: Nazwa + category_placeholder: Nic + ok_edit: Aktualizacja + ok_create: Tworzyć + category: Kategoria + monitor_placeholder: Nic + title_readonly: Przeglądanie {{Nazwa}} + workspace_placeholder: Nic + ok_readonly: Edytuj jako nowy + title_edit: Edycja {{nazwa}} + monitor: Monitor + options_label: Dodatkowe opcje + workspace: Obszar roboczy + bindings: Wiązanie (wymagane są obie opcje) + title_create: Tworzenie {{nazwa}} + identifier: + and: I + or: LUB + id: Identyfikator + remove: Usuń blok + matching_strategy: Strategia dopasowywania + add_block: Dodaj blok + negation: Negate dopasowanie + kind: Identyfikować się przez + swap: Zamieniać + export: Eksport + new: Nowy + delete: Usuwać + confirm_delete_title: Potwierdź usunięcie + import: Import + search: Szukaj + confirm_delete: Czy na pewno chcesz usunąć tę konfigurację/s? + bundled_title: App Config w pakiecie z Seelen + bundled_msg: >- + Te konfiguracje pakietowe nie są edytowalne i mają na celu zapewnienie + najlepszych wrażeń bez dostosowywania. Automatycznie konfigurują dla Ciebie + najczęstsze aplikacje. +extras: + relaunch: Wznowienie + version: Wersja + github: Github + discord: Niezgoda + exit: Wyjdź/wyjdź + links: Oficjalne linki +shortcuts: + labels: + focus_latest: Focus najnowszy + switch_workspace_6: Przejdź na przestrzeń roboczą 6 + switch_workspace_7: Przełącz się na przestrzeń roboczą 7 + send_to_workspace_2: Wyślij na przestrzeń roboczą 2 + reserve_stack: Stos rezerwowy + increase_height: Zwiększyć wysokość + decrease_height: Zmniejszyć wysokość + move_to_workspace_6: Przenieś się do obszaru roboczego 6 + move_to_workspace_1: Przenieś się do obszaru roboczego 1 + switch_workspace_5: Przełącz się na przestrzeń roboczą 5 + move_to_workspace_0: Przenieś się do obszaru roboczego 0 + move_to_workspace_3: Przenieś się do obszaru roboczego 3 + move_to_workspace_4: Przenieś się do obszaru roboczego 4 + send_to_workspace_9: Wyślij do obszaru roboczego 9 + send_to_workspace_8: Wyślij na przestrzeń roboczą 8 + move_to_workspace_2: Przenieś się do obszaru roboczego 2 + decrease_width: Zmniejszyć szerokość + send_to_workspace_3: Wyślij do obszaru roboczego 3 + switch_workspace_4: Przełącz się na przestrzeń roboczą 4 + focus_right: Skup się dobrze + send_to_workspace_6: Wyślij do obszaru roboczego 6 + send_to_workspace_0: Wyślij do obszaru roboczego 0 + focus_bottom: Focus Dim + send_to_workspace_5: Wyślij do obszaru roboczego 5 + switch_workspace_0: Przejdź na obszar roboczy 0 + reserve_bottom: Rezerwować dno + send_to_workspace_4: Wyślij na przestrzeń roboczą 4 + reserve_top: Rezerwuj top + focus_left: Skup się na lewej + move_to_workspace_7: Przenieś się do obszaru roboczego 7 + switch_workspace_8: Przełącz się na przestrzeń roboczą 8 + switch_workspace_9: Przejdź na obszar roboczy 9 + switch_workspace_2: Przełącz się na przestrzeń roboczą 2 + switch_workspace_1: Przejdź na obszar roboczy 1 + reserve_float: Rezerwować pływak + move_to_workspace_5: Przenieś się do obszaru roboczego 5 + move_to_workspace_8: Przenieś się do obszaru roboczego 8 + restore_sizes: Przywróć rozmiary + reserve_right: Rezerwuj prawnie + reserve_left: Rezerwa w lewo + switch_workspace_3: Przełącz się na przestrzeń roboczą 3 + increase_width: Zwiększyć szerokość + focus_top: Focus Top + move_to_workspace_9: Przenieś się do obszaru roboczego 9 + send_to_workspace_1: Wyślij do obszaru roboczego 1 + send_to_workspace_7: Wyślij na przestrzeń roboczą 7 + enable_tooltip: Wyłącz, jeśli zaimplementujesz własne skróty za pomocą API Seelen Core + enable: Włącz zintegrowane skróty (AHK) +loading: Ładowanie... +quit: Zrezygnować +inProgress: W trakcie... +delete: Usuwać +cancel: Anulować +save: Ratować +open: otwarty diff --git a/src/apps/settings/i18n/translations/ps.yml b/src/apps/settings/i18n/translations/ps.yml index 024dae30..dd096fa9 100644 --- a/src/apps/settings/i18n/translations/ps.yml +++ b/src/apps/settings/i18n/translations/ps.yml @@ -1,192 +1,192 @@ -sides: - right: ښي - bottom: ښکته - top: سر - left: کیڼ -header: - labels: - developer: پراختیا کونکی - general: عمومي - seelen_bar: د فینسي توکپټه - seelen_wm: د کړکۍ مدیر - seelen_weg: ډیک / ټاسک بار - specific_apps: ځانګړي اطلاقات - info: معلومات - monitors: څارونکي - shortcuts: لنډوکونه -start: - title: ښه راغلاست! - message_accent: د سټایل سره خپل محصول غوره کړئ! - message: >- - د زنګ وهلو ته ښه راغلاست، حتمي ډیسټاپ چاپیریال د خپل وینډوز 11 تجربې ته وده - ورکولو لپاره د شامل شوي ټایټاپ وینډوز چاپیریال سره! زموږ د استثنایی بیرونځای - او پرمختللي ب shape و سره د اغیزمنتیا او ضرباتو نوې دوره وپلټئ. -general: - theme: - description: تفصیل - label: د موضوع معلومات - added: موضوع لا دمخه اضافه شوې - tags: ټاګز - author: لیکوال - enabled: د لاسرسي وړ - add: موضوع اضافه کړئ - placeholder: موضوع وټاکئ - available: شتون لري - selected: ټاکل شوی - startup: په پیل کې چلول؟ - language: ژبه - icon_pack: - label: آیکون کڅوړه - accent_color: تیزس رنګ -toolbar: - placeholder: - description: تفصیل - select: د توکپټې جوړښت - author: لیکوال - enable: د فینسي تورې پټه وړتیا وړ کړئ - height: لوړوالی -wm: - border: - width: د بريد سور - enable: د کړکۍ پوله فعال کړئ - offset: پوله - description: تفصیل - resize_delta: د ډیلټا (٪) ریموټ کړئ - workspace_offset: د کاري ځای ځایونه (مارجینز) - enable: د کړکۍ مدیر ته وړ کړئ - workspace_padding: د کارډا ریسس - space_between_containers: د کانتینرونو ترمینځ ځای - author: لیکوال - disabled_windows10: د کړکۍ مدیر د وینډوز 10 لپاره شتون نلري. - layout: ترتیب -weg: - items: - size: د توکي اندازه - gap: د توکو تر مینځ فضا - label: توکي - zoom_size: زوم شوی اندازه (د موضوعاتو لپاره کارول کیږي) - visible_separators: لیدلي جلا کونکي - margin: حاشیه - padding: غالۍ - label: ډیک / ټاسک بار - width: پلنوالی - gap: تشې - enable: دوک / ټاسک بار فعال کړئ - auto_hide: آٹو پټول - dock_side: ډیک اړخ -devtools: - custom_config_file: د دودیز ترتیب فایل پورته کړئ - enable: د پراختیا کونکي وسیلې فعال کړئ - settings_file: د امستنې دوتنه - data_folder: د معلوماتو فولډر - install_folder: لګول فولډر - app_folders: د ایپ فولډرونه - load: بار -apps_configurations: - app: - options: - unmanage: بې وسلې کول - pinned: پینټ شوی - force: د ځواک اداره کول - float: فلوټ - ok_readonly: د نوي په توګه - title_edit: د {{{{}} ترمیم کول - category_placeholder: هیڅ نه - category: کټګورۍ - ok_create: جوړول - monitor_placeholder: هیڅ نه - monitor: څارونکی - ok_edit: تازه کول - title_readonly: لیدنه. یو {علی}} - name: نوم - workspace: کاري ځای - title_create: '{{}} رامینځته کول' - options_label: اضافي اختیارونه - bindings: تړل (په یادداشت کې دواړه اختیارونه اړین دي) - workspace_placeholder: هیڅ نه - identifier: - or: یا - id: پېژنيزه - and: او - remove: بلاک ړنګ کړئ - add_block: بلاک اضافه کړئ - kind: د - matching_strategy: برابرول - negation: غفلت کول - new: نوی - import: واردول - search: لټون - confirm_delete: ایا ته باوري یې چې دا جوړښتونه ړنګول غواړې؟ - bundled_msg: >- - دا بنډل تشکیلات د ترمیم وړ ندي او ډیزاین شوي چې تاسو ته د دودیز کولو پرته - غوره تجربه چمتو کړي. دوی په اوتومات ډول ستاسو لپاره خورا عام غوښتنلیکونه - تنظیموي. - delete: حذف کول - swap: سویپ - confirm_delete_title: ړنګول تایید کړئ - export: صادرات - bundled_title: د اپلیکیشن سره ایپ بنډل شوی -extras: - links: رسمي اړیکې - exit: پریښودل / وتل - github: ګیتوب - version: نسخه - relaunch: بیا پیل کول - discord: ډارول -shortcuts: - labels: - send_to_workspace_9: کارځای ته واستوئ - decrease_height: لوړوالی کمول - reserve_left: ساتل شوی - focus_right: سم تمرکز - send_to_workspace_5: د کارځای 5 ته واستوئ - move_to_workspace_9: د کارځای 9 ته لاړشئ - send_to_workspace_6: کارځای ته واستوئ - switch_workspace_6: د کارځای 6 ته وګرځئ - send_to_workspace_1: کارځای ته واستوئ - switch_workspace_9: د کارځای شمیره 9 - focus_left: کي left ه تمرکز - move_to_workspace_3: د کارځای 3 ته لاړشئ - send_to_workspace_4: کارځای ته واستوئ - switch_workspace_4: د کارځای ته وسپارئ - switch_workspace_5: د کارځای 5 ته لاړشئ - switch_workspace_1: د کارځای 1 ته لاړشئ - move_to_workspace_8: د کارځای ته لاړشئ - send_to_workspace_7: کارځای ته واستوئ - reserve_top: خوندي پټی - send_to_workspace_2: کارځای ته واستوئ - focus_latest: وروستی تمرکز وکړئ - move_to_workspace_4: د کارځای ته لاړشئ - send_to_workspace_3: کارځای ته واستوئ - move_to_workspace_7: د کارځای 7 ته لاړشئ - switch_workspace_2: د کارځای 2 ته لاړشئ - reserve_float: ریزرو فلوټ - switch_workspace_3: د کارځای 3 ته وګرځئ - move_to_workspace_5: د کارځای 5 ته لاړشئ - reserve_bottom: د - decrease_width: د سوری کمول - move_to_workspace_0: د کارځای 0 ته لاړشئ - send_to_workspace_0: کارځای ته واستوئ - focus_top: فوکس سر - switch_workspace_0: د کارځای 0 ته لاړشئ - focus_bottom: ښکته - reserve_stack: ریزرو سټیک - switch_workspace_7: د کارځای ته لاړشئ - move_to_workspace_1: د کارځای 1 ته لاړشئ - move_to_workspace_6: د کارځای ته لاړشئ - switch_workspace_8: د کارځای 8 ته وګرځئ - reserve_right: سم ساتل - move_to_workspace_2: د کارځای 2 ته لاړشئ - increase_width: پلنوالی زیات کړئ - send_to_workspace_8: کارځای ته واستوئ - restore_sizes: اندازونه بحال کړئ - increase_height: قد زیاتول - enable_tooltip: غیر فعال کړئ که تاسو خپل لنډلارې د سیرلین اصلي API په کارولو سره پلي کړئ - enable: مدغم شوي لنډیزونه (اه) -inProgress: د پرمختګ په حال کې... -quit: پرېښودل -delete: حذف کول -cancel: لغوه کول -loading: بارول ... -save: خوندي کړئ -open: خلاص +sides: + right: ښي + bottom: ښکته + top: سر + left: کیڼ +header: + labels: + developer: پراختیا کونکی + general: عمومي + seelen_bar: د فینسي توکپټه + seelen_wm: د کړکۍ مدیر + seelen_weg: ډیک / ټاسک بار + specific_apps: ځانګړي اطلاقات + info: معلومات + monitors: څارونکي + shortcuts: لنډوکونه +start: + title: ښه راغلاست! + message_accent: د سټایل سره خپل محصول غوره کړئ! + message: >- + د زنګ وهلو ته ښه راغلاست، حتمي ډیسټاپ چاپیریال د خپل وینډوز 11 تجربې ته وده + ورکولو لپاره د شامل شوي ټایټاپ وینډوز چاپیریال سره! زموږ د استثنایی بیرونځای + او پرمختللي ب shape و سره د اغیزمنتیا او ضرباتو نوې دوره وپلټئ. +general: + theme: + description: تفصیل + label: د موضوع معلومات + added: موضوع لا دمخه اضافه شوې + tags: ټاګز + author: لیکوال + enabled: د لاسرسي وړ + add: موضوع اضافه کړئ + placeholder: موضوع وټاکئ + available: شتون لري + selected: ټاکل شوی + startup: په پیل کې چلول؟ + language: ژبه + icon_pack: + label: آیکون کڅوړه + accent_color: تیزس رنګ +toolbar: + placeholder: + description: تفصیل + select: د توکپټې جوړښت + author: لیکوال + enable: د فینسي تورې پټه وړتیا وړ کړئ + height: لوړوالی +wm: + border: + width: د بريد سور + enable: د کړکۍ پوله فعال کړئ + offset: پوله + description: تفصیل + resize_delta: د ډیلټا (٪) ریموټ کړئ + workspace_offset: د کاري ځای ځایونه (مارجینز) + enable: د کړکۍ مدیر ته وړ کړئ + workspace_padding: د کارډا ریسس + space_between_containers: د کانتینرونو ترمینځ ځای + author: لیکوال + disabled_windows10: د کړکۍ مدیر د وینډوز 10 لپاره شتون نلري. + layout: ترتیب +weg: + items: + size: د توکي اندازه + gap: د توکو تر مینځ فضا + label: توکي + zoom_size: زوم شوی اندازه (د موضوعاتو لپاره کارول کیږي) + visible_separators: لیدلي جلا کونکي + margin: حاشیه + padding: غالۍ + label: ډیک / ټاسک بار + width: پلنوالی + gap: تشې + enable: دوک / ټاسک بار فعال کړئ + auto_hide: آٹو پټول + dock_side: ډیک اړخ +devtools: + custom_config_file: د دودیز ترتیب فایل پورته کړئ + enable: د پراختیا کونکي وسیلې فعال کړئ + settings_file: د امستنې دوتنه + data_folder: د معلوماتو فولډر + install_folder: لګول فولډر + app_folders: د ایپ فولډرونه + load: بار +apps_configurations: + app: + options: + unmanage: بې وسلې کول + pinned: پینټ شوی + force: د ځواک اداره کول + float: فلوټ + ok_readonly: د نوي په توګه + title_edit: د {{{{}} ترمیم کول + category_placeholder: هیڅ نه + category: کټګورۍ + ok_create: جوړول + monitor_placeholder: هیڅ نه + monitor: څارونکی + ok_edit: تازه کول + title_readonly: لیدنه. یو {علی}} + name: نوم + workspace: کاري ځای + title_create: '{{}} رامینځته کول' + options_label: اضافي اختیارونه + bindings: تړل (په یادداشت کې دواړه اختیارونه اړین دي) + workspace_placeholder: هیڅ نه + identifier: + or: یا + id: پېژنيزه + and: او + remove: بلاک ړنګ کړئ + add_block: بلاک اضافه کړئ + kind: د + matching_strategy: برابرول + negation: غفلت کول + new: نوی + import: واردول + search: لټون + confirm_delete: ایا ته باوري یې چې دا جوړښتونه ړنګول غواړې؟ + bundled_msg: >- + دا بنډل تشکیلات د ترمیم وړ ندي او ډیزاین شوي چې تاسو ته د دودیز کولو پرته + غوره تجربه چمتو کړي. دوی په اوتومات ډول ستاسو لپاره خورا عام غوښتنلیکونه + تنظیموي. + delete: حذف کول + swap: سویپ + confirm_delete_title: ړنګول تایید کړئ + export: صادرات + bundled_title: د اپلیکیشن سره ایپ بنډل شوی +extras: + links: رسمي اړیکې + exit: پریښودل / وتل + github: ګیتوب + version: نسخه + relaunch: بیا پیل کول + discord: ډارول +shortcuts: + labels: + send_to_workspace_9: کارځای ته واستوئ + decrease_height: لوړوالی کمول + reserve_left: ساتل شوی + focus_right: سم تمرکز + send_to_workspace_5: د کارځای 5 ته واستوئ + move_to_workspace_9: د کارځای 9 ته لاړشئ + send_to_workspace_6: کارځای ته واستوئ + switch_workspace_6: د کارځای 6 ته وګرځئ + send_to_workspace_1: کارځای ته واستوئ + switch_workspace_9: د کارځای شمیره 9 + focus_left: کي left ه تمرکز + move_to_workspace_3: د کارځای 3 ته لاړشئ + send_to_workspace_4: کارځای ته واستوئ + switch_workspace_4: د کارځای ته وسپارئ + switch_workspace_5: د کارځای 5 ته لاړشئ + switch_workspace_1: د کارځای 1 ته لاړشئ + move_to_workspace_8: د کارځای ته لاړشئ + send_to_workspace_7: کارځای ته واستوئ + reserve_top: خوندي پټی + send_to_workspace_2: کارځای ته واستوئ + focus_latest: وروستی تمرکز وکړئ + move_to_workspace_4: د کارځای ته لاړشئ + send_to_workspace_3: کارځای ته واستوئ + move_to_workspace_7: د کارځای 7 ته لاړشئ + switch_workspace_2: د کارځای 2 ته لاړشئ + reserve_float: ریزرو فلوټ + switch_workspace_3: د کارځای 3 ته وګرځئ + move_to_workspace_5: د کارځای 5 ته لاړشئ + reserve_bottom: د + decrease_width: د سوری کمول + move_to_workspace_0: د کارځای 0 ته لاړشئ + send_to_workspace_0: کارځای ته واستوئ + focus_top: فوکس سر + switch_workspace_0: د کارځای 0 ته لاړشئ + focus_bottom: ښکته + reserve_stack: ریزرو سټیک + switch_workspace_7: د کارځای ته لاړشئ + move_to_workspace_1: د کارځای 1 ته لاړشئ + move_to_workspace_6: د کارځای ته لاړشئ + switch_workspace_8: د کارځای 8 ته وګرځئ + reserve_right: سم ساتل + move_to_workspace_2: د کارځای 2 ته لاړشئ + increase_width: پلنوالی زیات کړئ + send_to_workspace_8: کارځای ته واستوئ + restore_sizes: اندازونه بحال کړئ + increase_height: قد زیاتول + enable_tooltip: غیر فعال کړئ که تاسو خپل لنډلارې د سیرلین اصلي API په کارولو سره پلي کړئ + enable: مدغم شوي لنډیزونه (اه) +inProgress: د پرمختګ په حال کې... +quit: پرېښودل +delete: حذف کول +cancel: لغوه کول +loading: بارول ... +save: خوندي کړئ +open: خلاص diff --git a/src/apps/settings/i18n/translations/pt.yml b/src/apps/settings/i18n/translations/pt.yml index 339cbd86..5cd30bdc 100644 --- a/src/apps/settings/i18n/translations/pt.yml +++ b/src/apps/settings/i18n/translations/pt.yml @@ -1,193 +1,193 @@ -loading: Carregando... -inProgress: Em andamento... -cancel: Cancelar -save: Salvar -quit: Desistir -open: Abrir -delete: Excluir -sides: - left: Esquerda - right: Certo - top: Principal - bottom: Fundo -header: - labels: - general: Em geral - seelen_bar: Barra de ferramentas sofisticada - seelen_wm: Gerenciador de janelas - seelen_weg: Dock/barra de tarefas - monitors: Monitores - specific_apps: Aplicativos específicos - shortcuts: Atalhos - developer: Desenvolvedor - info: Informação -start: - title: Bem-vindo! - message: >- - Bem-vindo ao Seelen UI, o melhor ambiente de área de trabalho com um - gerenciador de janelas lado a lado incorporado para aprimorar sua - experiência com o Windows 11! Explore uma nova era de eficiência e - multitarefa com nossa interface intuitiva e recursos avançados. - message_accent: Otimize sua produtividade com estilo! -general: - startup: Executar ao iniciar? - language: Linguagem - theme: - label: Informações do tema - placeholder: Selecione o tema - author: Autor - description: Descrição - add: Adicionar tema - added: Tema já adicionado - enabled: Temas habilitados - tags: Tag - selected: Selecionada - available: Disponível - icon_pack: - label: Pacotes de ícones - accent_color: Cor de destaque -toolbar: - enable: Ativar barra de ferramentas sofisticada - placeholder: - select: Estrutura da barra de ferramentas - author: Autor - description: Descrição - height: Altura -wm: - enable: Habilitar Gerenciador de Janelas - disabled_windows10: O Gerenciador de janelas não está disponível para Windows 10. - layout: Disposição - author: Autor - description: Descrição - space_between_containers: Espaço entre contêineres - workspace_padding: Preenchimento de espaços de trabalho - workspace_offset: Deslocamento de espaços de trabalho (margens) - resize_delta: Redimensionar Delta (%) - border: - enable: Habilitar borda da janela - width: Largura da borda - offset: Deslocamento de borda -weg: - label: Dock/barra de tarefas - enable: Habilitar Dock/Barra de Tarefas - width: Largura - auto_hide: Ocultar automaticamente - dock_side: Lado da doca - padding: Preenchimento - margin: Margem - gap: Brecha - items: - label: Unid - size: Tamanho do item - zoom_size: Tamanho ampliado (usado para temas) - gap: Espaço entre itens - visible_separators: Separadores Visíveis -devtools: - enable: Habilitar ferramentas para desenvolvedores - app_folders: Pastas de aplicativos - install_folder: Pasta de instalação - data_folder: Pasta de dados - settings_file: Arquivo de configurações - custom_config_file: Carregar arquivo de configuração personalizado - load: Carregar -apps_configurations: - import: Importar - export: Exportar - delete: Excluir - swap: Trocar - new: Novo - bundled_title: Configuração do aplicativo incluída no Seelen - bundled_msg: >- - Essas configurações agrupadas não são editáveis ​​e foram projetadas para - fornecer a melhor experiência sem personalização. Eles configuram - automaticamente os aplicativos mais comuns para você. - confirm_delete_title: Confirmar exclusão - confirm_delete: Tem certeza de que deseja excluir esta(s) configuração(ões)? - search: Procurar - app: - name: Nome - category: Categoria - category_placeholder: Nenhum - bindings: Vinculação (observe que ambas as opções são obrigatórias) - monitor: Monitor - monitor_placeholder: Nenhum - workspace: Área de trabalho - workspace_placeholder: Nenhum - title_edit: Editando {{nome}} - title_create: Criando {{nome}} - title_readonly: Visualizando {{nome}} - ok_edit: Atualizar - ok_create: Criar - ok_readonly: Editar como novo - options_label: Opções extras - options: - float: Flutuador - unmanage: Não gerenciar - force: Forçar gerenciamento - pinned: Fixado - identifier: - remove: Excluir bloco - id: Identificador - kind: Identificar por - matching_strategy: Estratégia de correspondência - negation: Negar correspondência - and: E - or: OU - add_block: Adicionar bloco -extras: - version: Versão - links: Links Oficiais - github: GitHub - discord: Discórdia - relaunch: Relançar - exit: Sair/Sair -shortcuts: - enable: Habilitar atalhos integrados (ahk) - enable_tooltip: Desative se você implementar seus próprios atalhos usando a API Seelen Core - labels: - reserve_top: Reserva Superior - reserve_bottom: Reserva Inferior - reserve_left: Reserva à Esquerda - reserve_right: Direito de reserva - reserve_float: Reserva Flutuante - reserve_stack: Pilha de Reserva - focus_top: Foco Superior - focus_bottom: Foco Inferior - focus_left: Foco à esquerda - focus_right: Foco certo - focus_latest: Foco mais recente - increase_width: Aumentar largura - decrease_width: Diminuir largura - increase_height: Aumentar a altura - decrease_height: Diminuir Altura - restore_sizes: Restaurar tamanhos - switch_workspace_0: Mudar para o espaço de trabalho 0 - switch_workspace_1: Mudar para o espaço de trabalho 1 - switch_workspace_2: Mudar para o espaço de trabalho 2 - switch_workspace_3: Mudar para o espaço de trabalho 3 - switch_workspace_4: Mudar para o espaço de trabalho 4 - switch_workspace_5: Mudar para o espaço de trabalho 5 - switch_workspace_6: Mudar para o espaço de trabalho 6 - switch_workspace_7: Mudar para o espaço de trabalho 7 - switch_workspace_8: Mudar para o espaço de trabalho 8 - switch_workspace_9: Mudar para o espaço de trabalho 9 - move_to_workspace_0: Mover para o espaço de trabalho 0 - move_to_workspace_1: Mover para o espaço de trabalho 1 - move_to_workspace_2: Mover para o espaço de trabalho 2 - move_to_workspace_3: Mover para o espaço de trabalho 3 - move_to_workspace_4: Mover para o espaço de trabalho 4 - move_to_workspace_5: Mover para o espaço de trabalho 5 - move_to_workspace_6: Mover para o espaço de trabalho 6 - move_to_workspace_7: Mover para o espaço de trabalho 7 - move_to_workspace_8: Mover para o espaço de trabalho 8 - move_to_workspace_9: Mover para o espaço de trabalho 9 - send_to_workspace_0: Enviar para o espaço de trabalho 0 - send_to_workspace_1: Enviar para o espaço de trabalho 1 - send_to_workspace_2: Enviar para o espaço de trabalho 2 - send_to_workspace_3: Enviar para o espaço de trabalho 3 - send_to_workspace_4: Enviar para o espaço de trabalho 4 - send_to_workspace_5: Enviar para o espaço de trabalho 5 - send_to_workspace_6: Enviar para o espaço de trabalho 6 - send_to_workspace_7: Enviar para o espaço de trabalho 7 - send_to_workspace_8: Enviar para o espaço de trabalho 8 - send_to_workspace_9: Enviar para o espaço de trabalho 9 +loading: Carregando... +inProgress: Em andamento... +cancel: Cancelar +save: Salvar +quit: Desistir +open: Abrir +delete: Excluir +sides: + left: Esquerda + right: Certo + top: Principal + bottom: Fundo +header: + labels: + general: Em geral + seelen_bar: Barra de ferramentas sofisticada + seelen_wm: Gerenciador de janelas + seelen_weg: Dock/barra de tarefas + monitors: Monitores + specific_apps: Aplicativos específicos + shortcuts: Atalhos + developer: Desenvolvedor + info: Informação +start: + title: Bem-vindo! + message: >- + Bem-vindo ao Seelen UI, o melhor ambiente de área de trabalho com um + gerenciador de janelas lado a lado incorporado para aprimorar sua + experiência com o Windows 11! Explore uma nova era de eficiência e + multitarefa com nossa interface intuitiva e recursos avançados. + message_accent: Otimize sua produtividade com estilo! +general: + startup: Executar ao iniciar? + language: Linguagem + theme: + label: Informações do tema + placeholder: Selecione o tema + author: Autor + description: Descrição + add: Adicionar tema + added: Tema já adicionado + enabled: Temas habilitados + tags: Tag + selected: Selecionada + available: Disponível + icon_pack: + label: Pacotes de ícones + accent_color: Cor de destaque +toolbar: + enable: Ativar barra de ferramentas sofisticada + placeholder: + select: Estrutura da barra de ferramentas + author: Autor + description: Descrição + height: Altura +wm: + enable: Habilitar Gerenciador de Janelas + disabled_windows10: O Gerenciador de janelas não está disponível para Windows 10. + layout: Disposição + author: Autor + description: Descrição + space_between_containers: Espaço entre contêineres + workspace_padding: Preenchimento de espaços de trabalho + workspace_offset: Deslocamento de espaços de trabalho (margens) + resize_delta: Redimensionar Delta (%) + border: + enable: Habilitar borda da janela + width: Largura da borda + offset: Deslocamento de borda +weg: + label: Dock/barra de tarefas + enable: Habilitar Dock/Barra de Tarefas + width: Largura + auto_hide: Ocultar automaticamente + dock_side: Lado da doca + padding: Preenchimento + margin: Margem + gap: Brecha + items: + label: Unid + size: Tamanho do item + zoom_size: Tamanho ampliado (usado para temas) + gap: Espaço entre itens + visible_separators: Separadores Visíveis +devtools: + enable: Habilitar ferramentas para desenvolvedores + app_folders: Pastas de aplicativos + install_folder: Pasta de instalação + data_folder: Pasta de dados + settings_file: Arquivo de configurações + custom_config_file: Carregar arquivo de configuração personalizado + load: Carregar +apps_configurations: + import: Importar + export: Exportar + delete: Excluir + swap: Trocar + new: Novo + bundled_title: Configuração do aplicativo incluída no Seelen + bundled_msg: >- + Essas configurações agrupadas não são editáveis ​​e foram projetadas para + fornecer a melhor experiência sem personalização. Eles configuram + automaticamente os aplicativos mais comuns para você. + confirm_delete_title: Confirmar exclusão + confirm_delete: Tem certeza de que deseja excluir esta(s) configuração(ões)? + search: Procurar + app: + name: Nome + category: Categoria + category_placeholder: Nenhum + bindings: Vinculação (observe que ambas as opções são obrigatórias) + monitor: Monitor + monitor_placeholder: Nenhum + workspace: Área de trabalho + workspace_placeholder: Nenhum + title_edit: Editando {{nome}} + title_create: Criando {{nome}} + title_readonly: Visualizando {{nome}} + ok_edit: Atualizar + ok_create: Criar + ok_readonly: Editar como novo + options_label: Opções extras + options: + float: Flutuador + unmanage: Não gerenciar + force: Forçar gerenciamento + pinned: Fixado + identifier: + remove: Excluir bloco + id: Identificador + kind: Identificar por + matching_strategy: Estratégia de correspondência + negation: Negar correspondência + and: E + or: OU + add_block: Adicionar bloco +extras: + version: Versão + links: Links Oficiais + github: GitHub + discord: Discórdia + relaunch: Relançar + exit: Sair/Sair +shortcuts: + enable: Habilitar atalhos integrados (ahk) + enable_tooltip: Desative se você implementar seus próprios atalhos usando a API Seelen Core + labels: + reserve_top: Reserva Superior + reserve_bottom: Reserva Inferior + reserve_left: Reserva à Esquerda + reserve_right: Direito de reserva + reserve_float: Reserva Flutuante + reserve_stack: Pilha de Reserva + focus_top: Foco Superior + focus_bottom: Foco Inferior + focus_left: Foco à esquerda + focus_right: Foco certo + focus_latest: Foco mais recente + increase_width: Aumentar largura + decrease_width: Diminuir largura + increase_height: Aumentar a altura + decrease_height: Diminuir Altura + restore_sizes: Restaurar tamanhos + switch_workspace_0: Mudar para o espaço de trabalho 0 + switch_workspace_1: Mudar para o espaço de trabalho 1 + switch_workspace_2: Mudar para o espaço de trabalho 2 + switch_workspace_3: Mudar para o espaço de trabalho 3 + switch_workspace_4: Mudar para o espaço de trabalho 4 + switch_workspace_5: Mudar para o espaço de trabalho 5 + switch_workspace_6: Mudar para o espaço de trabalho 6 + switch_workspace_7: Mudar para o espaço de trabalho 7 + switch_workspace_8: Mudar para o espaço de trabalho 8 + switch_workspace_9: Mudar para o espaço de trabalho 9 + move_to_workspace_0: Mover para o espaço de trabalho 0 + move_to_workspace_1: Mover para o espaço de trabalho 1 + move_to_workspace_2: Mover para o espaço de trabalho 2 + move_to_workspace_3: Mover para o espaço de trabalho 3 + move_to_workspace_4: Mover para o espaço de trabalho 4 + move_to_workspace_5: Mover para o espaço de trabalho 5 + move_to_workspace_6: Mover para o espaço de trabalho 6 + move_to_workspace_7: Mover para o espaço de trabalho 7 + move_to_workspace_8: Mover para o espaço de trabalho 8 + move_to_workspace_9: Mover para o espaço de trabalho 9 + send_to_workspace_0: Enviar para o espaço de trabalho 0 + send_to_workspace_1: Enviar para o espaço de trabalho 1 + send_to_workspace_2: Enviar para o espaço de trabalho 2 + send_to_workspace_3: Enviar para o espaço de trabalho 3 + send_to_workspace_4: Enviar para o espaço de trabalho 4 + send_to_workspace_5: Enviar para o espaço de trabalho 5 + send_to_workspace_6: Enviar para o espaço de trabalho 6 + send_to_workspace_7: Enviar para o espaço de trabalho 7 + send_to_workspace_8: Enviar para o espaço de trabalho 8 + send_to_workspace_9: Enviar para o espaço de trabalho 9 diff --git a/src/apps/settings/i18n/translations/ro.yml b/src/apps/settings/i18n/translations/ro.yml index 0c2fc88d..594abaab 100644 --- a/src/apps/settings/i18n/translations/ro.yml +++ b/src/apps/settings/i18n/translations/ro.yml @@ -1,195 +1,195 @@ -sides: - left: Stânga - top: Top - right: Dreapta - bottom: Fund -header: - labels: - developer: Dezvoltator - info: informație - general: General - seelen_weg: Dock/Bara de activități - shortcuts: Comitete rapide - seelen_wm: Manager de ferestre - specific_apps: Aplicații specifice - seelen_bar: Bara de instrumente fantezistă - monitors: Monitoare -start: - title: Bine ati venit! - message_accent: Optimizează -ți productivitatea cu stil! - message: >- - Bine ați venit la Seelen UI, mediul de desktop final cu un manager Windows - de gresie încorporat pentru a vă îmbunătăți experiența Windows 11! Explorați - o nouă eră de eficiență și multitasking cu interfața noastră intuitivă și - caracteristicile avansate. -general: - theme: - placeholder: Selectează tema - author: Autor - description: Descriere - tags: Etichete - enabled: Teme activate - add: Adăugați tema - label: Informații despre temă - added: Tema deja adăugată - selected: Selectat - available: Disponibil - language: Limba - startup: Rulați la pornire? - icon_pack: - label: Pachete de pictograme - accent_color: Culoare de accent -toolbar: - placeholder: - select: Structura barei de instrumente - author: Autor - description: Descriere - height: Înălţime - enable: Activați bara de instrumente fantezistă -wm: - border: - enable: Activați granița ferestrei - width: Lățimea graniței - offset: Offset de frontieră - description: Descriere - author: Autor - layout: Aspect - resize_delta: Redimensionați delta (%) - workspace_offset: Spații de lucru Offset (marje) - space_between_containers: Spațiu între containere - enable: Activați managerul de ferestre - workspace_padding: Padding spații de lucru - disabled_windows10: Managerul de ferestre nu este disponibil pentru Windows 10. -weg: - items: - size: Dimensiunea articolului - label: Articole - zoom_size: Dimensiunea zoomată (folosită pentru teme) - gap: Spațiu între articole - visible_separators: Separatoare vizibile - width: Lăţime - gap: Decalaj - label: Dock/Bara de activități - auto_hide: Ascundere automată - margin: Marjă - enable: Activați Dock/Bara de activități - padding: Căptușeală - dock_side: Partea de doc -devtools: - load: Sarcină - data_folder: Folder de date - custom_config_file: Încărcați fișierul de configurare personalizat - enable: Activați instrumentele pentru dezvoltatori - app_folders: Foldere de aplicații - settings_file: Fișier de setări - install_folder: Folder de instalare -apps_configurations: - app: - options: - force: Forța gestionează - float: Pluti - unmanage: Ne gestionare - pinned: Fixat - ok_create: Crea - ok_edit: Actualizați - category_placeholder: Nici unul - bindings: Legare (notă ambele opțiuni sunt necesare) - monitor_placeholder: Nici unul - workspace_placeholder: Nici unul - category: Categorie - options_label: Opțiuni suplimentare - name: Nume - title_create: Crearea {{nume}} - workspace: Spațiu de lucru - title_readonly: Vizualizare {{nume}} - title_edit: Editt {{nume}} - ok_readonly: Editați ca nou - monitor: Monitor - identifier: - and: ȘI - or: SAU - negation: Negate potrivire - remove: Ștergeți blocul - matching_strategy: Strategia de potrivire - add_block: Adăugați bloc - kind: Identifică de - id: Identificator - export: Export - search: Căutare - import: Import - new: Nou - confirm_delete_title: Confirmă ștergerea - bundled_title: App Config Bundled cu Seelen - delete: Șterge - bundled_msg: >- - Aceste configurații în pachet nu sunt editabile și sunt concepute pentru a - vă oferi cea mai bună experiență fără personalizare. Acestea configurează - automat cele mai frecvente aplicații pentru dvs. - swap: Swap - confirm_delete: Ești sigur că vrei să ștergi această configurație/s? -extras: - github: Github - relaunch: Relansare - discord: Discordie - version: Versiune - links: Link -uri oficiale - exit: Renunță/ieșire -shortcuts: - labels: - move_to_workspace_8: Mutați -vă la spațiul de lucru 8 - switch_workspace_1: Treceți la spațiul de lucru 1 - switch_workspace_0: Treceți la spațiul de lucru 0 - switch_workspace_3: Treceți la spațiul de lucru 3 - send_to_workspace_0: Trimiteți la spațiul de lucru 0 - send_to_workspace_5: Trimiteți la spațiul de lucru 5 - send_to_workspace_8: Trimiteți la spațiul de lucru 8 - send_to_workspace_4: Trimiteți la Workspace 4 - switch_workspace_4: Treceți la spațiul de lucru 4 - reserve_bottom: Rezervați fundul - reserve_left: Rezerva stânga - focus_bottom: Focus Fund - send_to_workspace_9: Trimiteți la spațiul de lucru 9 - send_to_workspace_3: Trimiteți la Workspace 3 - send_to_workspace_7: Trimiteți la Workspace 7 - send_to_workspace_6: Trimiteți la spațiul de lucru 6 - switch_workspace_7: Treceți la spațiul de lucru 7 - send_to_workspace_2: Trimiteți la Workspace 2 - move_to_workspace_4: Treceți la spațiul de lucru 4 - increase_width: Creșteți lățimea - reserve_float: Rezervați plutitorul - move_to_workspace_6: Treceți la spațiul de lucru 6 - decrease_width: Scăderea lățimii - decrease_height: Scăderea înălțimii - restore_sizes: Restaurați dimensiunile - move_to_workspace_3: Treceți la spațiul de lucru 3 - focus_latest: Concentrați -vă cel mai recent - focus_left: Concentrați -vă la stânga - switch_workspace_2: Treceți la spațiul de lucru 2 - switch_workspace_9: Treceți la spațiul de lucru 9 - switch_workspace_5: Treceți la spațiul de lucru 5 - send_to_workspace_1: Trimiteți la spațiul de lucru 1 - reserve_right: Rezervați drept - move_to_workspace_9: Treceți la spațiul de lucru 9 - move_to_workspace_2: Treceți la spațiul de lucru 2 - reserve_stack: Rezerva stivă - increase_height: Crește înălțimea - focus_right: Concentrați -vă corect - reserve_top: Rezervați vârful - move_to_workspace_1: Treceți la spațiul de lucru 1 - switch_workspace_6: Treceți la spațiul de lucru 6 - move_to_workspace_5: Treceți la spațiul de lucru 5 - move_to_workspace_0: Treceți la spațiul de lucru 0 - switch_workspace_8: Treceți la spațiul de lucru 8 - focus_top: Focus top - move_to_workspace_7: Mutați -vă la spațiul de lucru 7 - enable: Activați comenzi rapide integrate (AHK) - enable_tooltip: >- - Dezactivați dacă veți implementa propriile comenzi rapide folosind API -ul - Seelen Core -delete: Șterge -inProgress: În curs... -loading: Se încarcă... -quit: Părăsi -save: Salvați -open: Deschis -cancel: Anulare +sides: + left: Stânga + top: Top + right: Dreapta + bottom: Fund +header: + labels: + developer: Dezvoltator + info: informație + general: General + seelen_weg: Dock/Bara de activități + shortcuts: Comitete rapide + seelen_wm: Manager de ferestre + specific_apps: Aplicații specifice + seelen_bar: Bara de instrumente fantezistă + monitors: Monitoare +start: + title: Bine ati venit! + message_accent: Optimizează -ți productivitatea cu stil! + message: >- + Bine ați venit la Seelen UI, mediul de desktop final cu un manager Windows + de gresie încorporat pentru a vă îmbunătăți experiența Windows 11! Explorați + o nouă eră de eficiență și multitasking cu interfața noastră intuitivă și + caracteristicile avansate. +general: + theme: + placeholder: Selectează tema + author: Autor + description: Descriere + tags: Etichete + enabled: Teme activate + add: Adăugați tema + label: Informații despre temă + added: Tema deja adăugată + selected: Selectat + available: Disponibil + language: Limba + startup: Rulați la pornire? + icon_pack: + label: Pachete de pictograme + accent_color: Culoare de accent +toolbar: + placeholder: + select: Structura barei de instrumente + author: Autor + description: Descriere + height: Înălţime + enable: Activați bara de instrumente fantezistă +wm: + border: + enable: Activați granița ferestrei + width: Lățimea graniței + offset: Offset de frontieră + description: Descriere + author: Autor + layout: Aspect + resize_delta: Redimensionați delta (%) + workspace_offset: Spații de lucru Offset (marje) + space_between_containers: Spațiu între containere + enable: Activați managerul de ferestre + workspace_padding: Padding spații de lucru + disabled_windows10: Managerul de ferestre nu este disponibil pentru Windows 10. +weg: + items: + size: Dimensiunea articolului + label: Articole + zoom_size: Dimensiunea zoomată (folosită pentru teme) + gap: Spațiu între articole + visible_separators: Separatoare vizibile + width: Lăţime + gap: Decalaj + label: Dock/Bara de activități + auto_hide: Ascundere automată + margin: Marjă + enable: Activați Dock/Bara de activități + padding: Căptușeală + dock_side: Partea de doc +devtools: + load: Sarcină + data_folder: Folder de date + custom_config_file: Încărcați fișierul de configurare personalizat + enable: Activați instrumentele pentru dezvoltatori + app_folders: Foldere de aplicații + settings_file: Fișier de setări + install_folder: Folder de instalare +apps_configurations: + app: + options: + force: Forța gestionează + float: Pluti + unmanage: Ne gestionare + pinned: Fixat + ok_create: Crea + ok_edit: Actualizați + category_placeholder: Nici unul + bindings: Legare (notă ambele opțiuni sunt necesare) + monitor_placeholder: Nici unul + workspace_placeholder: Nici unul + category: Categorie + options_label: Opțiuni suplimentare + name: Nume + title_create: Crearea {{nume}} + workspace: Spațiu de lucru + title_readonly: Vizualizare {{nume}} + title_edit: Editt {{nume}} + ok_readonly: Editați ca nou + monitor: Monitor + identifier: + and: ȘI + or: SAU + negation: Negate potrivire + remove: Ștergeți blocul + matching_strategy: Strategia de potrivire + add_block: Adăugați bloc + kind: Identifică de + id: Identificator + export: Export + search: Căutare + import: Import + new: Nou + confirm_delete_title: Confirmă ștergerea + bundled_title: App Config Bundled cu Seelen + delete: Șterge + bundled_msg: >- + Aceste configurații în pachet nu sunt editabile și sunt concepute pentru a + vă oferi cea mai bună experiență fără personalizare. Acestea configurează + automat cele mai frecvente aplicații pentru dvs. + swap: Swap + confirm_delete: Ești sigur că vrei să ștergi această configurație/s? +extras: + github: Github + relaunch: Relansare + discord: Discordie + version: Versiune + links: Link -uri oficiale + exit: Renunță/ieșire +shortcuts: + labels: + move_to_workspace_8: Mutați -vă la spațiul de lucru 8 + switch_workspace_1: Treceți la spațiul de lucru 1 + switch_workspace_0: Treceți la spațiul de lucru 0 + switch_workspace_3: Treceți la spațiul de lucru 3 + send_to_workspace_0: Trimiteți la spațiul de lucru 0 + send_to_workspace_5: Trimiteți la spațiul de lucru 5 + send_to_workspace_8: Trimiteți la spațiul de lucru 8 + send_to_workspace_4: Trimiteți la Workspace 4 + switch_workspace_4: Treceți la spațiul de lucru 4 + reserve_bottom: Rezervați fundul + reserve_left: Rezerva stânga + focus_bottom: Focus Fund + send_to_workspace_9: Trimiteți la spațiul de lucru 9 + send_to_workspace_3: Trimiteți la Workspace 3 + send_to_workspace_7: Trimiteți la Workspace 7 + send_to_workspace_6: Trimiteți la spațiul de lucru 6 + switch_workspace_7: Treceți la spațiul de lucru 7 + send_to_workspace_2: Trimiteți la Workspace 2 + move_to_workspace_4: Treceți la spațiul de lucru 4 + increase_width: Creșteți lățimea + reserve_float: Rezervați plutitorul + move_to_workspace_6: Treceți la spațiul de lucru 6 + decrease_width: Scăderea lățimii + decrease_height: Scăderea înălțimii + restore_sizes: Restaurați dimensiunile + move_to_workspace_3: Treceți la spațiul de lucru 3 + focus_latest: Concentrați -vă cel mai recent + focus_left: Concentrați -vă la stânga + switch_workspace_2: Treceți la spațiul de lucru 2 + switch_workspace_9: Treceți la spațiul de lucru 9 + switch_workspace_5: Treceți la spațiul de lucru 5 + send_to_workspace_1: Trimiteți la spațiul de lucru 1 + reserve_right: Rezervați drept + move_to_workspace_9: Treceți la spațiul de lucru 9 + move_to_workspace_2: Treceți la spațiul de lucru 2 + reserve_stack: Rezerva stivă + increase_height: Crește înălțimea + focus_right: Concentrați -vă corect + reserve_top: Rezervați vârful + move_to_workspace_1: Treceți la spațiul de lucru 1 + switch_workspace_6: Treceți la spațiul de lucru 6 + move_to_workspace_5: Treceți la spațiul de lucru 5 + move_to_workspace_0: Treceți la spațiul de lucru 0 + switch_workspace_8: Treceți la spațiul de lucru 8 + focus_top: Focus top + move_to_workspace_7: Mutați -vă la spațiul de lucru 7 + enable: Activați comenzi rapide integrate (AHK) + enable_tooltip: >- + Dezactivați dacă veți implementa propriile comenzi rapide folosind API -ul + Seelen Core +delete: Șterge +inProgress: În curs... +loading: Se încarcă... +quit: Părăsi +save: Salvați +open: Deschis +cancel: Anulare diff --git a/src/apps/settings/i18n/translations/ru.yml b/src/apps/settings/i18n/translations/ru.yml index 01295021..58480093 100644 --- a/src/apps/settings/i18n/translations/ru.yml +++ b/src/apps/settings/i18n/translations/ru.yml @@ -1,196 +1,196 @@ -loading: Загрузка... -inProgress: В ходе выполнения... -cancel: Отмена -save: Сохранять -quit: Покидать -open: Открыть -delete: Удалить -sides: - left: Левый - right: Верно - top: Вершина - bottom: Нижний -header: - labels: - general: Общий - seelen_bar: Необычная панель инструментов - seelen_wm: Оконный менеджер - seelen_weg: Док/Панель задач - monitors: Мониторы - specific_apps: Конкретные приложения - shortcuts: Ярлыки - developer: Разработчик - info: Информация -start: - title: Добро пожаловать! - message: >- - Добро пожаловать в пользовательский интерфейс Seelen, идеальную среду - рабочего стола со встроенным тайловым менеджером окон, который улучшит вашу - работу с Windows 11! Откройте для себя новую эру эффективности и - многозадачности благодаря нашему интуитивно понятному интерфейсу и - расширенным функциям. - message_accent: Оптимизируйте свою производительность стильно! -general: - startup: Выполняться при запуске? - language: Язык - theme: - label: Информация о теме - placeholder: Выберите тему - author: Автор - description: Описание - add: Добавить тему - added: Тема уже добавлена - enabled: Включенные темы - tags: Теги - available: Доступный - selected: Выбран - icon_pack: - label: Иконы пакеты - accent_color: Акцентный цвет -toolbar: - enable: Включить необычную панель инструментов - placeholder: - select: Структура панели инструментов - author: Автор - description: Описание - height: Высота -wm: - enable: Включить диспетчер окон - disabled_windows10: Диспетчер окон недоступен для Windows 10. - layout: Макет - author: Автор - description: Описание - space_between_containers: Пространство между контейнерами - workspace_padding: Заполнение рабочих пространств - workspace_offset: Смещение рабочих пространств (поля) - resize_delta: Изменение размера Дельты (%) - border: - enable: Включить границу окна - width: Ширина рамки - offset: Смещение границы -weg: - label: Док/Панель задач - enable: Включить док/панель задач - width: Ширина - auto_hide: Авто-скрытие - dock_side: Док-сайд - padding: Заполнение - margin: Допуск - gap: Зазор - items: - label: Предметы - size: Размер товара - zoom_size: Увеличенный размер (используется для тем) - gap: Пространство между элементами - visible_separators: Видимые разделители -devtools: - enable: Включить инструменты разработчика - app_folders: Папки приложений - install_folder: Папка установки - data_folder: Папка данных - settings_file: Файл настроек - custom_config_file: Загрузить пользовательский файл конфигурации - load: Нагрузка -apps_configurations: - import: Импортировать - export: Экспорт - delete: Удалить - swap: Менять - new: Новый - bundled_title: Конфигурация приложения в комплекте с Seelen - bundled_msg: >- - Эти связанные конфигурации не подлежат редактированию и предназначены для - обеспечения максимального удобства без настройки. Они автоматически - настраивают для вас наиболее распространенные приложения. - confirm_delete_title: Подтвердите удаление - confirm_delete: Вы уверены, что хотите удалить эту конфигурацию? - search: Поиск - app: - name: Имя - category: Категория - category_placeholder: Никто - bindings: Привязка (обратите внимание, что необходимы оба параметра) - monitor: Монитор - monitor_placeholder: Никто - workspace: Рабочая среда - workspace_placeholder: Никто - title_edit: Редактирование {{name}} - title_create: Создание {{name}} - title_readonly: Просмотр {{name}} - ok_edit: Обновлять - ok_create: Создавать - ok_readonly: Редактировать как новый - options_label: Дополнительные опции - options: - float: Плавать - unmanage: Отменить управление - force: Принудительное управление - pinned: Закреплено - identifier: - remove: Удалить блок - id: Идентификатор - kind: Определить по - matching_strategy: Соответствующая стратегия - negation: Отрицательное соответствие - and: И - or: ИЛИ - add_block: Добавить блок -extras: - version: Версия - links: Официальные ссылки - github: GitHub - discord: Раздор - relaunch: Перезапуск - exit: Выйти/выйти -shortcuts: - enable: Включить встроенные ярлыки (ahk) - enable_tooltip: >- - Отключите, если вы будете реализовывать свои собственные ярлыки с помощью - API Seelen Core. - labels: - reserve_top: Резервный топ - reserve_bottom: Резервное дно - reserve_left: Резервный левый - reserve_right: Резервное право - reserve_float: Резервный плавающий - reserve_stack: Резервный стек - focus_top: Фокус Топ - focus_bottom: Фокус внизу - focus_left: Фокус влево - focus_right: Фокус вправо - focus_latest: Фокус последних - increase_width: Увеличить ширину - decrease_width: Уменьшить ширину - increase_height: Увеличение высоты - decrease_height: Уменьшить высоту - restore_sizes: Восстановить размеры - switch_workspace_0: Переключиться на рабочую область 0 - switch_workspace_1: Переключиться на рабочую область 1 - switch_workspace_2: Переключиться на рабочую область 2 - switch_workspace_3: Переключиться на рабочую область 3 - switch_workspace_4: Переключиться на рабочую область 4 - switch_workspace_5: Переключиться на рабочую область 5 - switch_workspace_6: Переключиться на рабочую область 6 - switch_workspace_7: Переключиться на рабочую область 7 - switch_workspace_8: Переключиться на рабочую область 8 - switch_workspace_9: Переключиться на рабочую область 9 - move_to_workspace_0: Перейти в рабочую область 0 - move_to_workspace_1: Перейти в рабочую область 1 - move_to_workspace_2: Перейти в рабочую область 2 - move_to_workspace_3: Перейти в рабочую область 3 - move_to_workspace_4: Перейти в рабочую область 4 - move_to_workspace_5: Перейти в рабочую область 5 - move_to_workspace_6: Перейти в рабочую область 6 - move_to_workspace_7: Перейти в рабочую область 7 - move_to_workspace_8: Перейти в рабочую область 8 - move_to_workspace_9: Перейти в рабочую область 9 - send_to_workspace_0: Отправить в рабочую область 0 - send_to_workspace_1: Отправить в рабочую область 1 - send_to_workspace_2: Отправить в рабочую область 2 - send_to_workspace_3: Отправить в рабочую область 3 - send_to_workspace_4: Отправить в рабочую область 4 - send_to_workspace_5: Отправить в рабочую область 5 - send_to_workspace_6: Отправить в рабочую область 6 - send_to_workspace_7: Отправить в рабочую область 7 - send_to_workspace_8: Отправить в рабочую область 8 - send_to_workspace_9: Отправить в рабочую область 9 +loading: Загрузка... +inProgress: В ходе выполнения... +cancel: Отмена +save: Сохранять +quit: Покидать +open: Открыть +delete: Удалить +sides: + left: Левый + right: Верно + top: Вершина + bottom: Нижний +header: + labels: + general: Общий + seelen_bar: Необычная панель инструментов + seelen_wm: Оконный менеджер + seelen_weg: Док/Панель задач + monitors: Мониторы + specific_apps: Конкретные приложения + shortcuts: Ярлыки + developer: Разработчик + info: Информация +start: + title: Добро пожаловать! + message: >- + Добро пожаловать в пользовательский интерфейс Seelen, идеальную среду + рабочего стола со встроенным тайловым менеджером окон, который улучшит вашу + работу с Windows 11! Откройте для себя новую эру эффективности и + многозадачности благодаря нашему интуитивно понятному интерфейсу и + расширенным функциям. + message_accent: Оптимизируйте свою производительность стильно! +general: + startup: Выполняться при запуске? + language: Язык + theme: + label: Информация о теме + placeholder: Выберите тему + author: Автор + description: Описание + add: Добавить тему + added: Тема уже добавлена + enabled: Включенные темы + tags: Теги + available: Доступный + selected: Выбран + icon_pack: + label: Иконы пакеты + accent_color: Акцентный цвет +toolbar: + enable: Включить необычную панель инструментов + placeholder: + select: Структура панели инструментов + author: Автор + description: Описание + height: Высота +wm: + enable: Включить диспетчер окон + disabled_windows10: Диспетчер окон недоступен для Windows 10. + layout: Макет + author: Автор + description: Описание + space_between_containers: Пространство между контейнерами + workspace_padding: Заполнение рабочих пространств + workspace_offset: Смещение рабочих пространств (поля) + resize_delta: Изменение размера Дельты (%) + border: + enable: Включить границу окна + width: Ширина рамки + offset: Смещение границы +weg: + label: Док/Панель задач + enable: Включить док/панель задач + width: Ширина + auto_hide: Авто-скрытие + dock_side: Док-сайд + padding: Заполнение + margin: Допуск + gap: Зазор + items: + label: Предметы + size: Размер товара + zoom_size: Увеличенный размер (используется для тем) + gap: Пространство между элементами + visible_separators: Видимые разделители +devtools: + enable: Включить инструменты разработчика + app_folders: Папки приложений + install_folder: Папка установки + data_folder: Папка данных + settings_file: Файл настроек + custom_config_file: Загрузить пользовательский файл конфигурации + load: Нагрузка +apps_configurations: + import: Импортировать + export: Экспорт + delete: Удалить + swap: Менять + new: Новый + bundled_title: Конфигурация приложения в комплекте с Seelen + bundled_msg: >- + Эти связанные конфигурации не подлежат редактированию и предназначены для + обеспечения максимального удобства без настройки. Они автоматически + настраивают для вас наиболее распространенные приложения. + confirm_delete_title: Подтвердите удаление + confirm_delete: Вы уверены, что хотите удалить эту конфигурацию? + search: Поиск + app: + name: Имя + category: Категория + category_placeholder: Никто + bindings: Привязка (обратите внимание, что необходимы оба параметра) + monitor: Монитор + monitor_placeholder: Никто + workspace: Рабочая среда + workspace_placeholder: Никто + title_edit: Редактирование {{name}} + title_create: Создание {{name}} + title_readonly: Просмотр {{name}} + ok_edit: Обновлять + ok_create: Создавать + ok_readonly: Редактировать как новый + options_label: Дополнительные опции + options: + float: Плавать + unmanage: Отменить управление + force: Принудительное управление + pinned: Закреплено + identifier: + remove: Удалить блок + id: Идентификатор + kind: Определить по + matching_strategy: Соответствующая стратегия + negation: Отрицательное соответствие + and: И + or: ИЛИ + add_block: Добавить блок +extras: + version: Версия + links: Официальные ссылки + github: GitHub + discord: Раздор + relaunch: Перезапуск + exit: Выйти/выйти +shortcuts: + enable: Включить встроенные ярлыки (ahk) + enable_tooltip: >- + Отключите, если вы будете реализовывать свои собственные ярлыки с помощью + API Seelen Core. + labels: + reserve_top: Резервный топ + reserve_bottom: Резервное дно + reserve_left: Резервный левый + reserve_right: Резервное право + reserve_float: Резервный плавающий + reserve_stack: Резервный стек + focus_top: Фокус Топ + focus_bottom: Фокус внизу + focus_left: Фокус влево + focus_right: Фокус вправо + focus_latest: Фокус последних + increase_width: Увеличить ширину + decrease_width: Уменьшить ширину + increase_height: Увеличение высоты + decrease_height: Уменьшить высоту + restore_sizes: Восстановить размеры + switch_workspace_0: Переключиться на рабочую область 0 + switch_workspace_1: Переключиться на рабочую область 1 + switch_workspace_2: Переключиться на рабочую область 2 + switch_workspace_3: Переключиться на рабочую область 3 + switch_workspace_4: Переключиться на рабочую область 4 + switch_workspace_5: Переключиться на рабочую область 5 + switch_workspace_6: Переключиться на рабочую область 6 + switch_workspace_7: Переключиться на рабочую область 7 + switch_workspace_8: Переключиться на рабочую область 8 + switch_workspace_9: Переключиться на рабочую область 9 + move_to_workspace_0: Перейти в рабочую область 0 + move_to_workspace_1: Перейти в рабочую область 1 + move_to_workspace_2: Перейти в рабочую область 2 + move_to_workspace_3: Перейти в рабочую область 3 + move_to_workspace_4: Перейти в рабочую область 4 + move_to_workspace_5: Перейти в рабочую область 5 + move_to_workspace_6: Перейти в рабочую область 6 + move_to_workspace_7: Перейти в рабочую область 7 + move_to_workspace_8: Перейти в рабочую область 8 + move_to_workspace_9: Перейти в рабочую область 9 + send_to_workspace_0: Отправить в рабочую область 0 + send_to_workspace_1: Отправить в рабочую область 1 + send_to_workspace_2: Отправить в рабочую область 2 + send_to_workspace_3: Отправить в рабочую область 3 + send_to_workspace_4: Отправить в рабочую область 4 + send_to_workspace_5: Отправить в рабочую область 5 + send_to_workspace_6: Отправить в рабочую область 6 + send_to_workspace_7: Отправить в рабочую область 7 + send_to_workspace_8: Отправить в рабочую область 8 + send_to_workspace_9: Отправить в рабочую область 9 diff --git a/src/apps/settings/i18n/translations/si.yml b/src/apps/settings/i18n/translations/si.yml index 01660e99..a34e8d47 100644 --- a/src/apps/settings/i18n/translations/si.yml +++ b/src/apps/settings/i18n/translations/si.yml @@ -1,193 +1,193 @@ -sides: - top: ඉහල - bottom: පහළ - right: හරි - left: වම -header: - labels: - developer: සංවර්ධකයා - monitors: නිරීක්ෂකයින් - general: ජනරාල් - info: විස්තර - seelen_bar: විසිතුරු මෙවලම් තීරුව - specific_apps: විශේෂිත යෙදුම් - shortcuts: කෙටිමං - seelen_wm: කවුළු කළමනාකරු - seelen_weg: ඩොක්/කාර්ය තීරුව -start: - title: සාදරයෙන් පිළිගනිමු! - message_accent: ශෛලිය සමග ඔබේ ඵලදායිතාව ප්රශස්ත කරන්න! - message: >- - ඔබගේ Windows 11 අත්දැකීම වැඩිදියුණු කිරීම සඳහා සංස්ථාපිත ටයිල් කවුළු - කළමනාකරුවෙකු සහිත අවසාන ඩෙස්ක්ටොප් පරිසරය වන Seelen UI වෙත සාදරයෙන් - පිළිගනිමු! අපගේ බුද්ධිමය අතුරුමුහුණත සහ උසස් විශේෂාංග සමඟ කාර්යක්ෂමතාවයේ සහ - බහුකාර්යයේ නව යුගයක් ගවේෂණය කරන්න. -general: - theme: - tags: ටැග් - description: විස්තර - author: කර්තෘ - enabled: සබල කළ තේමා - placeholder: තේමාව තෝරන්න - added: තේමාව දැනටමත් එකතු කර ඇත - label: තේමා තොරතුරු - add: තේමාව එකතු කරන්න - available: ඇත - selected: තෝරාගත් - language: භාෂාව - startup: ආරම්භයේදී ධාවනය කරන්නද? - icon_pack: - label: අයිකන ඇසුරුම් - accent_color: උච්චාරණ වර්ණය -toolbar: - placeholder: - author: කර්තෘ - description: විස්තර - select: මෙවලම් තීරු ව්යුහය - height: උස - enable: විසිතුරු මෙවලම් තීරුව සබල කරන්න -wm: - border: - width: මායිම් පළල - enable: කවුළුවේ මායිම සක්රිය කරන්න - offset: මායිම් ඕෆ්සෙට් - author: කර්තෘ - description: විස්තර - layout: පිරිසැලසුම - space_between_containers: බහාලුම් අතර අවකාශය - enable: කවුළු කළමනාකරු සබල කරන්න - workspace_padding: වැඩබිම් පිරවුම - resize_delta: ඩෙල්ටා ප්‍රමාණය වෙනස් කරන්න (%) - workspace_offset: වැඩබිම් ඕෆ්සෙට් (ආන්තික) - disabled_windows10: Windows 10 සඳහා Window Manager නොමැත. -weg: - items: - label: අයිතම - visible_separators: දෘශ්‍ය බෙදුම්කරුවන් - size: අයිතමයේ ප්රමාණය - gap: අයිතම අතර අවකාශය - zoom_size: විශාලනය කළ ප්‍රමාණය (තේමා සඳහා භාවිතා වේ) - label: ඩොක්/කාර්ය තීරුව - auto_hide: ස්වයංක්‍රීය සඟවන්න - padding: පෑඩිං - width: පළල - enable: Dock/Taskbar සබල කරන්න - dock_side: ඩොක් පැත්ත - gap: පරතරය - margin: ආන්තිකය -devtools: - enable: සංවර්ධක මෙවලම් සබල කරන්න - install_folder: ස්ථාපන ෆෝල්ඩරය - settings_file: සැකසුම් ගොනුව - app_folders: යෙදුම් ෆෝල්ඩර - data_folder: දත්ත ෆෝල්ඩරය - custom_config_file: අභිරුචි වින්‍යාස ගොනුව පූරණය කරන්න - load: පැටවීම -apps_configurations: - app: - options: - float: පාවෙන - pinned: පින් කර ඇත - force: බල කළමනාකරණය - unmanage: කළමනාකරණය කරන්න - title_create: '{{name}} නිර්මාණය කරමින්' - monitor: නිරීක්ෂණය කරන්න - category_placeholder: කිසිවක් නැත - name: නම - workspace_placeholder: කිසිවක් නැත - monitor_placeholder: කිසිවක් නැත - options_label: අමතර විකල්ප - ok_edit: යාවත්කාලීන කරන්න - category: වර්ගය - title_edit: '{{name}} සංස්කරණය කරමින්' - bindings: බැඳීම (විකල්ප දෙකම අවශ්‍ය බව සලකන්න) - workspace: වැඩබිම - ok_readonly: නව ලෙස සංස්කරණය කරන්න - title_readonly: '{{name}} බලමින්' - ok_create: නිර්මාණය කරන්න - identifier: - and: සහ - add_block: බ්ලොක් එක් කරන්න - negation: ගැලපීම නිෂේධනය කරන්න - or: හෝ - remove: අවහිර කිරීම මකන්න - id: හඳුනාගැනීම - kind: විසින් හඳුනා ගන්න - matching_strategy: ගැලපුම් උපාය මාර්ගය - search: සෙවීම - import: ආනයන - export: අපනයන - new: අලුත් - confirm_delete_title: මකා දැමීම තහවුරු කරන්න - bundled_title: යෙදුම් වින්‍යාසය සීලන් සමඟ බණ්ඩල් කර ඇත - delete: මකන්න - swap: හුවමාරු කරන්න - bundled_msg: >- - මෙම මිටි වින්‍යාසයන් සංස්කරණය කළ නොහැකි අතර අභිරුචිකරණයකින් තොරව ඔබට හොඳම - අත්දැකීම ලබා දීමට සැලසුම් කර ඇත. ඔවුන් ඔබ සඳහා වඩාත් පොදු යෙදුම් - ස්වයංක්‍රීයව වින්‍යාස කරයි. - confirm_delete: ඔබට මෙම වින්‍යාසය/s මැකීමට අවශ්‍ය බව විශ්වාසද? -extras: - version: පිටපත - discord: අසමගිය - github: GitHub - links: නිල සබැඳි - exit: පිටවීම/පිටවීම - relaunch: නැවත දියත් කරන්න -shortcuts: - labels: - restore_sizes: ප්‍රමාණ ප්‍රතිසාධනය කරන්න - focus_right: නිවැරදිව අවධානය යොමු කරන්න - increase_height: උස වැඩි කරන්න - send_to_workspace_2: Workspace 2 වෙත යවන්න - send_to_workspace_5: වැඩබිම වෙත යවන්න 5 - switch_workspace_0: Workspace 0 වෙත මාරු වන්න - move_to_workspace_7: වැඩබිම වෙත ගෙන යන්න 7 - send_to_workspace_3: වැඩබිම වෙත යවන්න 3 - send_to_workspace_9: Workspace 9 වෙත යවන්න - send_to_workspace_0: Workspace 0 වෙත යවන්න - switch_workspace_6: වැඩබිම වෙත මාරු වන්න 6 - move_to_workspace_2: කාර්ය ඉඩ 2 වෙත ගෙන යන්න - move_to_workspace_4: වැඩබිම වෙත ගෙන යන්න 4 - reserve_float: රක්ෂිත පාවෙන - send_to_workspace_1: කාර්ය ඉඩ 1 වෙත යවන්න - focus_latest: නවතම අවධානය යොමු කරන්න - focus_left: වමට අවධානය යොමු කරන්න - switch_workspace_1: කාර්ය ඉඩ 1 වෙත මාරු වන්න - move_to_workspace_5: වැඩබිම වෙත ගෙන යන්න 5 - decrease_height: උස අඩු කරන්න - reserve_bottom: සංචිත පතුලේ - move_to_workspace_9: වැඩබිම වෙත ගෙන යන්න 9 - send_to_workspace_7: Workspace 7 වෙත යවන්න - send_to_workspace_4: වැඩබිම වෙත යවන්න 4 - reserve_right: රක්ෂිත අයිතිය - move_to_workspace_0: Workspace 0 වෙත ගෙන යන්න - switch_workspace_2: කාර්ය ඉඩ 2 වෙත මාරු වන්න - move_to_workspace_1: කාර්ය ඉඩ 1 වෙත ගෙන යන්න - switch_workspace_9: වැඩබිම වෙත මාරු වන්න 9 - send_to_workspace_8: Workspace 8 වෙත යවන්න - move_to_workspace_3: වැඩබිම වෙත ගෙන යන්න 3 - send_to_workspace_6: වැඩබිම වෙත යවන්න 6 - decrease_width: පළල අඩු කරන්න - switch_workspace_4: වැඩබිම වෙත මාරු වන්න 4 - reserve_left: වම රක්ෂිතය - switch_workspace_5: වැඩබිම වෙත මාරු වන්න 5 - reserve_stack: සංචිත තොගය - move_to_workspace_8: වැඩබිම වෙත ගෙන යන්න 8 - reserve_top: ඉහළම රක්ෂිතය - switch_workspace_3: වැඩබිම වෙත මාරු වන්න 3 - switch_workspace_8: කාර්ය ඉඩ 8 වෙත මාරු වන්න - focus_top: ඉහළට අවධානය යොමු කරන්න - increase_width: පළල වැඩි කරන්න - move_to_workspace_6: වැඩබිම වෙත ගෙන යන්න 6 - switch_workspace_7: වැඩබිම 7 වෙත මාරු වන්න - focus_bottom: පහළට අවධානය යොමු කරන්න - enable_tooltip: ඔබ Seelen Core Api භාවිතයෙන් ඔබේම කෙටිමං ක්‍රියාත්මක කරන්නේ නම් අබල කරන්න - enable: ඒකාබද්ධ කෙටිමං සබල කරන්න (ahk) -loading: පූරණය වෙමින්... -quit: ඉවත් -inProgress: ප්රගතියේ... -cancel: අවලංගු කරන්න -delete: මකන්න -open: විවෘත -save: සුරකින්න +sides: + top: ඉහල + bottom: පහළ + right: හරි + left: වම +header: + labels: + developer: සංවර්ධකයා + monitors: නිරීක්ෂකයින් + general: ජනරාල් + info: විස්තර + seelen_bar: විසිතුරු මෙවලම් තීරුව + specific_apps: විශේෂිත යෙදුම් + shortcuts: කෙටිමං + seelen_wm: කවුළු කළමනාකරු + seelen_weg: ඩොක්/කාර්ය තීරුව +start: + title: සාදරයෙන් පිළිගනිමු! + message_accent: ශෛලිය සමග ඔබේ ඵලදායිතාව ප්රශස්ත කරන්න! + message: >- + ඔබගේ Windows 11 අත්දැකීම වැඩිදියුණු කිරීම සඳහා සංස්ථාපිත ටයිල් කවුළු + කළමනාකරුවෙකු සහිත අවසාන ඩෙස්ක්ටොප් පරිසරය වන Seelen UI වෙත සාදරයෙන් + පිළිගනිමු! අපගේ බුද්ධිමය අතුරුමුහුණත සහ උසස් විශේෂාංග සමඟ කාර්යක්ෂමතාවයේ සහ + බහුකාර්යයේ නව යුගයක් ගවේෂණය කරන්න. +general: + theme: + tags: ටැග් + description: විස්තර + author: කර්තෘ + enabled: සබල කළ තේමා + placeholder: තේමාව තෝරන්න + added: තේමාව දැනටමත් එකතු කර ඇත + label: තේමා තොරතුරු + add: තේමාව එකතු කරන්න + available: ඇත + selected: තෝරාගත් + language: භාෂාව + startup: ආරම්භයේදී ධාවනය කරන්නද? + icon_pack: + label: අයිකන ඇසුරුම් + accent_color: උච්චාරණ වර්ණය +toolbar: + placeholder: + author: කර්තෘ + description: විස්තර + select: මෙවලම් තීරු ව්යුහය + height: උස + enable: විසිතුරු මෙවලම් තීරුව සබල කරන්න +wm: + border: + width: මායිම් පළල + enable: කවුළුවේ මායිම සක්රිය කරන්න + offset: මායිම් ඕෆ්සෙට් + author: කර්තෘ + description: විස්තර + layout: පිරිසැලසුම + space_between_containers: බහාලුම් අතර අවකාශය + enable: කවුළු කළමනාකරු සබල කරන්න + workspace_padding: වැඩබිම් පිරවුම + resize_delta: ඩෙල්ටා ප්‍රමාණය වෙනස් කරන්න (%) + workspace_offset: වැඩබිම් ඕෆ්සෙට් (ආන්තික) + disabled_windows10: Windows 10 සඳහා Window Manager නොමැත. +weg: + items: + label: අයිතම + visible_separators: දෘශ්‍ය බෙදුම්කරුවන් + size: අයිතමයේ ප්රමාණය + gap: අයිතම අතර අවකාශය + zoom_size: විශාලනය කළ ප්‍රමාණය (තේමා සඳහා භාවිතා වේ) + label: ඩොක්/කාර්ය තීරුව + auto_hide: ස්වයංක්‍රීය සඟවන්න + padding: පෑඩිං + width: පළල + enable: Dock/Taskbar සබල කරන්න + dock_side: ඩොක් පැත්ත + gap: පරතරය + margin: ආන්තිකය +devtools: + enable: සංවර්ධක මෙවලම් සබල කරන්න + install_folder: ස්ථාපන ෆෝල්ඩරය + settings_file: සැකසුම් ගොනුව + app_folders: යෙදුම් ෆෝල්ඩර + data_folder: දත්ත ෆෝල්ඩරය + custom_config_file: අභිරුචි වින්‍යාස ගොනුව පූරණය කරන්න + load: පැටවීම +apps_configurations: + app: + options: + float: පාවෙන + pinned: පින් කර ඇත + force: බල කළමනාකරණය + unmanage: කළමනාකරණය කරන්න + title_create: '{{name}} නිර්මාණය කරමින්' + monitor: නිරීක්ෂණය කරන්න + category_placeholder: කිසිවක් නැත + name: නම + workspace_placeholder: කිසිවක් නැත + monitor_placeholder: කිසිවක් නැත + options_label: අමතර විකල්ප + ok_edit: යාවත්කාලීන කරන්න + category: වර්ගය + title_edit: '{{name}} සංස්කරණය කරමින්' + bindings: බැඳීම (විකල්ප දෙකම අවශ්‍ය බව සලකන්න) + workspace: වැඩබිම + ok_readonly: නව ලෙස සංස්කරණය කරන්න + title_readonly: '{{name}} බලමින්' + ok_create: නිර්මාණය කරන්න + identifier: + and: සහ + add_block: බ්ලොක් එක් කරන්න + negation: ගැලපීම නිෂේධනය කරන්න + or: හෝ + remove: අවහිර කිරීම මකන්න + id: හඳුනාගැනීම + kind: විසින් හඳුනා ගන්න + matching_strategy: ගැලපුම් උපාය මාර්ගය + search: සෙවීම + import: ආනයන + export: අපනයන + new: අලුත් + confirm_delete_title: මකා දැමීම තහවුරු කරන්න + bundled_title: යෙදුම් වින්‍යාසය සීලන් සමඟ බණ්ඩල් කර ඇත + delete: මකන්න + swap: හුවමාරු කරන්න + bundled_msg: >- + මෙම මිටි වින්‍යාසයන් සංස්කරණය කළ නොහැකි අතර අභිරුචිකරණයකින් තොරව ඔබට හොඳම + අත්දැකීම ලබා දීමට සැලසුම් කර ඇත. ඔවුන් ඔබ සඳහා වඩාත් පොදු යෙදුම් + ස්වයංක්‍රීයව වින්‍යාස කරයි. + confirm_delete: ඔබට මෙම වින්‍යාසය/s මැකීමට අවශ්‍ය බව විශ්වාසද? +extras: + version: පිටපත + discord: අසමගිය + github: GitHub + links: නිල සබැඳි + exit: පිටවීම/පිටවීම + relaunch: නැවත දියත් කරන්න +shortcuts: + labels: + restore_sizes: ප්‍රමාණ ප්‍රතිසාධනය කරන්න + focus_right: නිවැරදිව අවධානය යොමු කරන්න + increase_height: උස වැඩි කරන්න + send_to_workspace_2: Workspace 2 වෙත යවන්න + send_to_workspace_5: වැඩබිම වෙත යවන්න 5 + switch_workspace_0: Workspace 0 වෙත මාරු වන්න + move_to_workspace_7: වැඩබිම වෙත ගෙන යන්න 7 + send_to_workspace_3: වැඩබිම වෙත යවන්න 3 + send_to_workspace_9: Workspace 9 වෙත යවන්න + send_to_workspace_0: Workspace 0 වෙත යවන්න + switch_workspace_6: වැඩබිම වෙත මාරු වන්න 6 + move_to_workspace_2: කාර්ය ඉඩ 2 වෙත ගෙන යන්න + move_to_workspace_4: වැඩබිම වෙත ගෙන යන්න 4 + reserve_float: රක්ෂිත පාවෙන + send_to_workspace_1: කාර්ය ඉඩ 1 වෙත යවන්න + focus_latest: නවතම අවධානය යොමු කරන්න + focus_left: වමට අවධානය යොමු කරන්න + switch_workspace_1: කාර්ය ඉඩ 1 වෙත මාරු වන්න + move_to_workspace_5: වැඩබිම වෙත ගෙන යන්න 5 + decrease_height: උස අඩු කරන්න + reserve_bottom: සංචිත පතුලේ + move_to_workspace_9: වැඩබිම වෙත ගෙන යන්න 9 + send_to_workspace_7: Workspace 7 වෙත යවන්න + send_to_workspace_4: වැඩබිම වෙත යවන්න 4 + reserve_right: රක්ෂිත අයිතිය + move_to_workspace_0: Workspace 0 වෙත ගෙන යන්න + switch_workspace_2: කාර්ය ඉඩ 2 වෙත මාරු වන්න + move_to_workspace_1: කාර්ය ඉඩ 1 වෙත ගෙන යන්න + switch_workspace_9: වැඩබිම වෙත මාරු වන්න 9 + send_to_workspace_8: Workspace 8 වෙත යවන්න + move_to_workspace_3: වැඩබිම වෙත ගෙන යන්න 3 + send_to_workspace_6: වැඩබිම වෙත යවන්න 6 + decrease_width: පළල අඩු කරන්න + switch_workspace_4: වැඩබිම වෙත මාරු වන්න 4 + reserve_left: වම රක්ෂිතය + switch_workspace_5: වැඩබිම වෙත මාරු වන්න 5 + reserve_stack: සංචිත තොගය + move_to_workspace_8: වැඩබිම වෙත ගෙන යන්න 8 + reserve_top: ඉහළම රක්ෂිතය + switch_workspace_3: වැඩබිම වෙත මාරු වන්න 3 + switch_workspace_8: කාර්ය ඉඩ 8 වෙත මාරු වන්න + focus_top: ඉහළට අවධානය යොමු කරන්න + increase_width: පළල වැඩි කරන්න + move_to_workspace_6: වැඩබිම වෙත ගෙන යන්න 6 + switch_workspace_7: වැඩබිම 7 වෙත මාරු වන්න + focus_bottom: පහළට අවධානය යොමු කරන්න + enable_tooltip: ඔබ Seelen Core Api භාවිතයෙන් ඔබේම කෙටිමං ක්‍රියාත්මක කරන්නේ නම් අබල කරන්න + enable: ඒකාබද්ධ කෙටිමං සබල කරන්න (ahk) +loading: පූරණය වෙමින්... +quit: ඉවත් +inProgress: ප්රගතියේ... +cancel: අවලංගු කරන්න +delete: මකන්න +open: විවෘත +save: සුරකින්න diff --git a/src/apps/settings/i18n/translations/sk.yml b/src/apps/settings/i18n/translations/sk.yml index 6724654f..313c797c 100644 --- a/src/apps/settings/i18n/translations/sk.yml +++ b/src/apps/settings/i18n/translations/sk.yml @@ -1,193 +1,193 @@ -sides: - right: Správny - top: Vrchol - left: Vľavo - bottom: Spodná časť -header: - labels: - developer: Vývojár - seelen_bar: Ozdobný panel s nástrojmi - info: Informácie - shortcuts: Skratky - seelen_weg: Prístavný panel - monitors: Monitorovať - specific_apps: Konkrétne aplikácie - general: Všeobecný - seelen_wm: Správca okien -start: - title: Vitajte! - message: >- - Vitajte v používateľskom rozhraní Seelen, v konečnom prostredí Desktop so - začleneným obkladom Windows Manager, aby ste vylepšili váš zážitok z systému - Windows 11! Preskúmajte novú éru účinnosti a multitaskingu s naším - intuitívnym rozhraním a pokročilými funkciami. - message_accent: Optimalizujte svoju produktivitu štýlom! -general: - theme: - placeholder: Vyberte tému - description: Opis - added: Téma už bola pridaná - author: Autor - enabled: Povolené témy - label: Informácie o téme - add: Pridať tému - tags: Značky - selected: Vybraný - available: Dostupný - startup: Spustiť pri štarte? - language: Jazyk - icon_pack: - label: Ikon - accent_color: Prízvuk -toolbar: - placeholder: - author: Autor - select: Štruktúra - description: Opis - enable: Povoliť ozdobný panel s nástrojmi - height: Výška -wm: - border: - width: Šírka hranice - enable: Povoľte hranicu okna - offset: Vyrovnanie - author: Autor - resize_delta: Zmeňte veľkosť delty (%) - workspace_padding: Čalúnenie pracovných priestorov - enable: Povoliť správcu okien - layout: Usporiadanie - space_between_containers: Priestor medzi nádobami - description: Opis - disabled_windows10: Správca okien nie je k dispozícii pre Windows 10. - workspace_offset: Offsety Workspaces (marže) -weg: - items: - size: Veľkosť položky - zoom_size: Zväčšená veľkosť (používa sa na témy) - visible_separators: Viditeľné oddeľovače - label: Predmety - gap: Priestor medzi položkami - width: Šírka - label: Prístavný panel - enable: Povoliť prístavisko/panel úloh - gap: Priepasť - auto_hide: Automaticky skryť - padding: Vypchávka - margin: Okraj - dock_side: Strana -devtools: - enable: Povoľte vývojárskym nástrojom - custom_config_file: Načítať vlastný konfiguračný súbor - app_folders: Priečinky - install_folder: Inštalačný priečinok - load: Naložiť - settings_file: Nastavovací súbor - data_folder: Priečinok -apps_configurations: - app: - options: - float: Plavák - force: Riadiť silu - pinned: Pripnutý - unmanage: Nemeniť - name: názov - ok_edit: Aktualizácia - workspace: Pracovný priestor - ok_readonly: Upravovať ako nové - title_create: Vytváranie {{name}} - bindings: Viazanie (POZNÁMKA sú potrebné obe možnosti) - title_edit: Editovanie {{name}} - workspace_placeholder: Žiadny - options_label: Ďalšie možnosti - category_placeholder: Žiadny - ok_create: Vytvárať - title_readonly: Prezeranie {{name}} - monitor_placeholder: Žiadny - category: Kategória - monitor: Monitor - identifier: - remove: Vymazať blok - negation: Negovať zladenie - kind: Určiť - add_block: Pridať blok - id: Identifikátor - or: Alebo - matching_strategy: Stratégia - and: A - search: Vyhľadávanie - delete: Vymazať - export: Export - new: Nový - import: Dovoz - confirm_delete: Ste si istí, že chcete túto konfiguráciu vymazať? - confirm_delete_title: Potvrďte odstránenie - bundled_title: Aplikácia konfigurácia zviazaná s Seelen - bundled_msg: >- - Tieto zviazané konfigurácie nie sú upraviteľné a sú navrhnuté tak, aby vám - poskytli najlepší zážitok bez prispôsobenia. Automaticky nakonfigurujú pre - vás najbežnejšie aplikácie. - swap: Vymeniť -extras: - relaunch: Reštart - version: Verzia - github: Potápať sa - links: Oficiálne odkazy - discord: Nesúhlas - exit: Prestať -shortcuts: - labels: - decrease_width: Znížiť šírku - send_to_workspace_0: Pošlite do pracovného priestoru 0 - switch_workspace_7: Prepnite na pracovný priestor 7 - focus_top: Zaostrenie - focus_right: Zamerať sa - increase_height: Výška - move_to_workspace_5: Presuňte sa do pracovného priestoru 5 - move_to_workspace_4: Presuňte sa do pracovného priestoru 4 - move_to_workspace_2: Presuňte sa do pracovného priestoru 2 - move_to_workspace_9: Presuňte sa do pracovného priestoru 9 - move_to_workspace_8: Presuňte sa do pracovného priestoru 8 - switch_workspace_4: Prepnite na pracovný priestor 4 - reserve_stack: Zásobník - move_to_workspace_7: Presuňte sa do pracovného priestoru 7 - send_to_workspace_1: Pošlite do pracovného priestoru 1 - switch_workspace_1: Prepnite na pracovný priestor 1 - send_to_workspace_5: Pošlite do pracovného priestoru 5 - reserve_left: Vľavo - reserve_top: Horná časť - send_to_workspace_9: Pošlite do pracovného priestoru 9 - send_to_workspace_2: Pošlite do pracovného priestoru 2 - switch_workspace_9: Prepnite na pracovný priestor 9 - send_to_workspace_8: Pošlite do pracovného priestoru 8 - switch_workspace_5: Prepnite na pracovný priestor 5 - move_to_workspace_3: Presuňte sa do pracovného priestoru 3 - move_to_workspace_0: Presuňte sa do pracovného priestoru 0 - move_to_workspace_6: Presuňte sa do pracovného priestoru 6 - switch_workspace_3: Prepnite na pracovný priestor 3 - reserve_bottom: Dno - focus_bottom: Zaostrenie - send_to_workspace_4: Pošlite do pracovného priestoru 4 - decrease_height: Zníženie výšky - send_to_workspace_6: Pošlite do pracovného priestoru 6 - reserve_right: Oprávnenie - switch_workspace_2: Prepnite na pracovný priestor 2 - switch_workspace_8: Prepnite na pracovný priestor 8 - switch_workspace_6: Prepnite na pracovný priestor 6 - focus_left: Vľavo - reserve_float: Plavák - switch_workspace_0: Prepnite na pracovný priestor 0 - focus_latest: Najnovší - send_to_workspace_7: Pošlite do pracovného priestoru 7 - send_to_workspace_3: Pošlite do pracovného priestoru 3 - move_to_workspace_1: Presun do pracovného priestoru 1 - increase_width: Zväčšenie - restore_sizes: Obnoviť veľkosti - enable: Povoliť integrované skratky (AHK) - enable_tooltip: Zakážte, ak pomocou API Seelen Core API implementujete svoje vlastné skratky -inProgress: Prebieha ... -loading: Načítava... -open: OTVORENÉ -cancel: Zrušiť -quit: Prestať -save: Uložiť -delete: Vymazať +sides: + right: Správny + top: Vrchol + left: Vľavo + bottom: Spodná časť +header: + labels: + developer: Vývojár + seelen_bar: Ozdobný panel s nástrojmi + info: Informácie + shortcuts: Skratky + seelen_weg: Prístavný panel + monitors: Monitorovať + specific_apps: Konkrétne aplikácie + general: Všeobecný + seelen_wm: Správca okien +start: + title: Vitajte! + message: >- + Vitajte v používateľskom rozhraní Seelen, v konečnom prostredí Desktop so + začleneným obkladom Windows Manager, aby ste vylepšili váš zážitok z systému + Windows 11! Preskúmajte novú éru účinnosti a multitaskingu s naším + intuitívnym rozhraním a pokročilými funkciami. + message_accent: Optimalizujte svoju produktivitu štýlom! +general: + theme: + placeholder: Vyberte tému + description: Opis + added: Téma už bola pridaná + author: Autor + enabled: Povolené témy + label: Informácie o téme + add: Pridať tému + tags: Značky + selected: Vybraný + available: Dostupný + startup: Spustiť pri štarte? + language: Jazyk + icon_pack: + label: Ikon + accent_color: Prízvuk +toolbar: + placeholder: + author: Autor + select: Štruktúra + description: Opis + enable: Povoliť ozdobný panel s nástrojmi + height: Výška +wm: + border: + width: Šírka hranice + enable: Povoľte hranicu okna + offset: Vyrovnanie + author: Autor + resize_delta: Zmeňte veľkosť delty (%) + workspace_padding: Čalúnenie pracovných priestorov + enable: Povoliť správcu okien + layout: Usporiadanie + space_between_containers: Priestor medzi nádobami + description: Opis + disabled_windows10: Správca okien nie je k dispozícii pre Windows 10. + workspace_offset: Offsety Workspaces (marže) +weg: + items: + size: Veľkosť položky + zoom_size: Zväčšená veľkosť (používa sa na témy) + visible_separators: Viditeľné oddeľovače + label: Predmety + gap: Priestor medzi položkami + width: Šírka + label: Prístavný panel + enable: Povoliť prístavisko/panel úloh + gap: Priepasť + auto_hide: Automaticky skryť + padding: Vypchávka + margin: Okraj + dock_side: Strana +devtools: + enable: Povoľte vývojárskym nástrojom + custom_config_file: Načítať vlastný konfiguračný súbor + app_folders: Priečinky + install_folder: Inštalačný priečinok + load: Naložiť + settings_file: Nastavovací súbor + data_folder: Priečinok +apps_configurations: + app: + options: + float: Plavák + force: Riadiť silu + pinned: Pripnutý + unmanage: Nemeniť + name: názov + ok_edit: Aktualizácia + workspace: Pracovný priestor + ok_readonly: Upravovať ako nové + title_create: Vytváranie {{name}} + bindings: Viazanie (POZNÁMKA sú potrebné obe možnosti) + title_edit: Editovanie {{name}} + workspace_placeholder: Žiadny + options_label: Ďalšie možnosti + category_placeholder: Žiadny + ok_create: Vytvárať + title_readonly: Prezeranie {{name}} + monitor_placeholder: Žiadny + category: Kategória + monitor: Monitor + identifier: + remove: Vymazať blok + negation: Negovať zladenie + kind: Určiť + add_block: Pridať blok + id: Identifikátor + or: Alebo + matching_strategy: Stratégia + and: A + search: Vyhľadávanie + delete: Vymazať + export: Export + new: Nový + import: Dovoz + confirm_delete: Ste si istí, že chcete túto konfiguráciu vymazať? + confirm_delete_title: Potvrďte odstránenie + bundled_title: Aplikácia konfigurácia zviazaná s Seelen + bundled_msg: >- + Tieto zviazané konfigurácie nie sú upraviteľné a sú navrhnuté tak, aby vám + poskytli najlepší zážitok bez prispôsobenia. Automaticky nakonfigurujú pre + vás najbežnejšie aplikácie. + swap: Vymeniť +extras: + relaunch: Reštart + version: Verzia + github: Potápať sa + links: Oficiálne odkazy + discord: Nesúhlas + exit: Prestať +shortcuts: + labels: + decrease_width: Znížiť šírku + send_to_workspace_0: Pošlite do pracovného priestoru 0 + switch_workspace_7: Prepnite na pracovný priestor 7 + focus_top: Zaostrenie + focus_right: Zamerať sa + increase_height: Výška + move_to_workspace_5: Presuňte sa do pracovného priestoru 5 + move_to_workspace_4: Presuňte sa do pracovného priestoru 4 + move_to_workspace_2: Presuňte sa do pracovného priestoru 2 + move_to_workspace_9: Presuňte sa do pracovného priestoru 9 + move_to_workspace_8: Presuňte sa do pracovného priestoru 8 + switch_workspace_4: Prepnite na pracovný priestor 4 + reserve_stack: Zásobník + move_to_workspace_7: Presuňte sa do pracovného priestoru 7 + send_to_workspace_1: Pošlite do pracovného priestoru 1 + switch_workspace_1: Prepnite na pracovný priestor 1 + send_to_workspace_5: Pošlite do pracovného priestoru 5 + reserve_left: Vľavo + reserve_top: Horná časť + send_to_workspace_9: Pošlite do pracovného priestoru 9 + send_to_workspace_2: Pošlite do pracovného priestoru 2 + switch_workspace_9: Prepnite na pracovný priestor 9 + send_to_workspace_8: Pošlite do pracovného priestoru 8 + switch_workspace_5: Prepnite na pracovný priestor 5 + move_to_workspace_3: Presuňte sa do pracovného priestoru 3 + move_to_workspace_0: Presuňte sa do pracovného priestoru 0 + move_to_workspace_6: Presuňte sa do pracovného priestoru 6 + switch_workspace_3: Prepnite na pracovný priestor 3 + reserve_bottom: Dno + focus_bottom: Zaostrenie + send_to_workspace_4: Pošlite do pracovného priestoru 4 + decrease_height: Zníženie výšky + send_to_workspace_6: Pošlite do pracovného priestoru 6 + reserve_right: Oprávnenie + switch_workspace_2: Prepnite na pracovný priestor 2 + switch_workspace_8: Prepnite na pracovný priestor 8 + switch_workspace_6: Prepnite na pracovný priestor 6 + focus_left: Vľavo + reserve_float: Plavák + switch_workspace_0: Prepnite na pracovný priestor 0 + focus_latest: Najnovší + send_to_workspace_7: Pošlite do pracovného priestoru 7 + send_to_workspace_3: Pošlite do pracovného priestoru 3 + move_to_workspace_1: Presun do pracovného priestoru 1 + increase_width: Zväčšenie + restore_sizes: Obnoviť veľkosti + enable: Povoliť integrované skratky (AHK) + enable_tooltip: Zakážte, ak pomocou API Seelen Core API implementujete svoje vlastné skratky +inProgress: Prebieha ... +loading: Načítava... +open: OTVORENÉ +cancel: Zrušiť +quit: Prestať +save: Uložiť +delete: Vymazať diff --git a/src/apps/settings/i18n/translations/so.yml b/src/apps/settings/i18n/translations/so.yml index fad6118c..b4c3e97c 100644 --- a/src/apps/settings/i18n/translations/so.yml +++ b/src/apps/settings/i18n/translations/so.yml @@ -1,194 +1,194 @@ -sides: - left: Bidix - bottom: Hoose - top: Dusha kore - right: Sax -header: - labels: - monitors: Kormeerayaasha - seelen_weg: Dock / Tootshar - shortcuts: Gaaban - seelen_bar: Qalabka Fancy Toolbar - general: Guud - specific_apps: Barnaamijyo gaar ah - seelen_wm: Maamulaha daaqada - developer: Abuuris - info: War -start: - message: >- - Ku soo dhawow SELEN Ui, oo ah jawiga desktop-ka ugu dambeeya oo leh - maamulaha Windows-ka oo lagu daro Maareeyaha Windows 11 Sahamiyaan marxalad - cusub oo hufnaan iyo fara badan - title: Soo dhawow! - message_accent: Ku dadaal wax soo saarkaaga qaabka! -general: - theme: - description: Sifo - author: Qoraa - placeholder: Xullo mawduuca - tags: Calaamadaha - label: Macluumaadka mawduuca - add: Ku dar mawduuc - added: Mawduuca mar hore ayaa lagu daray - enabled: Awood u yeelo mowduucyada - selected: La xushay - available: Qof heli karo - startup: Ku orod bilowga? - language: Af - icon_pack: - label: Xirmooyinka icon - accent_color: Midab caqabad -toolbar: - placeholder: - description: Sifo - author: Qoraa - select: Qaab dhismeedka Qalabka - enable: Keeniyaan Qalabka Fancy Toolbar - height: Dherer -wm: - border: - enable: Karti xadka daaqadaha - width: Xadka ballaca - offset: Xudduud xadka - author: Qoraa - description: Sifo - disabled_windows10: Maamulaha daaqada ayaan loo heli karin Windows 10. - workspace_offset: Goobaha shaqada ayaa ka dhigtay - enable: Karti maamulaha daaqada - layout: Khariidad - resize_delta: Dib u dhig Delta (%) - space_between_containers: Meel bannaan oo u dhexeeya weelka - workspace_padding: Goobta Goobta Goobta -weg: - items: - gap: Meel udhaxeysa waxyaabaha - label: Waxyaabaha - size: Shayga cabirka - zoom_size: Cabbirka soojiidashada (oo loo isticmaalo mowduucyada) - visible_separators: Kala-sooca muuqda - dock_side: Dhinaceeda dhinaceeda - width: Ballac - enable: Kartida DOCK / Turniinka - gap: Dalool - padding: Suur - margin: Margin - label: Dock / Tootshar - auto_hide: Auto qaraha -devtools: - app_folders: Faylka app - install_folder: Xeerka rakibaadda - enable: U oggolow qalabka horumarinta - data_folder: Faylka xogta - custom_config_file: Xamuul faylka caadiga ah ee config - settings_file: Faylka Dejinta - load: Xammuul -apps_configurations: - app: - options: - pinned: Shaashad - float: Sabbayn - unmanage: Aan lahayn - force: Xoog u maareeyaan - title_create: Abuuritaanka {{Magaca {Magaca} - bindings: Xirashada (Xusuusin labada ikhtiyaar ayaa loo baahan yahay) - ok_readonly: Tafatir sida cusub - monitor_placeholder: Midna - category: Dabaqad - options_label: Fursadaha dheeraadka ah - ok_edit: Cusboonaysiin - workspace: Shaqo-joojin - title_readonly: Daawashada {{,} - monitor: Kaabba-galaas - category_placeholder: Midna - name: Magac - workspace_placeholder: Midna - ok_create: Abuurid - title_edit: Tafatirka {{magacii} - identifier: - remove: Tirtir xannibaadda - matching_strategy: Istaraatiijiyadda iswaafajinta - negation: Ciriiri u dhigma - kind: Aqoonso - and: Iyo - add_block: Ku dar xannibaadda - or: Ama - id: Aqoonsiga - new: Cusub - bundled_title: App COLOND SOLDED SELEN - confirm_delete: Ma hubtaa inaad rabto inaad tirtirto qaabeyntan / s? - import: Soo dejin - confirm_delete_title: Xaqiiji Delete - export: Dhoofin - search: Raadin - swap: Isku beddelo - delete: Tirtirid - bundled_msg: >- - Qaabeyntan xirmada ma aha wax aan la taabtaan oo loogu talagalay inay ku - siiyaan khibradda ugu fiican ee aan la helin. Waxay si otomaatig ah u - habeeyaan codsiyada ugu caansan adiga. -extras: - exit: Jooji / bixitaan - github: GitHub - version: Werin - relaunch: Dib u beer - discord: Huf - links: Xiriirinta rasmiga ah -shortcuts: - labels: - reserve_right: Xaq u dhig - reserve_top: Keydka sare - reserve_bottom: Kaydsanaanta hoose - restore_sizes: Soo celinta cabirka - move_to_workspace_0: U dhaqaaq goobta shaqada 0 - focus_left: Ahrive bidix - switch_workspace_5: U beddelo goobta shaqada 5 - increase_width: Kordhi ballaadhan - send_to_workspace_9: U dir goobta shaqada 9 - switch_workspace_8: U beddelo goobta shaqada 8 - move_to_workspace_2: U dhaqaaq goobta shaqada 2 - move_to_workspace_5: U dhaqaaq goobta shaqada 5 - switch_workspace_9: U beddelo goobta shaqada 9 - focus_latest: Diirad saar - send_to_workspace_5: U dir goobta shaqada 5 - focus_right: Diiradda saara - switch_workspace_3: U beddelo goobta shaqada 3 - send_to_workspace_7: U dir goobta shaqada 7 - move_to_workspace_7: U dhaqaaq goobta shaqada 7 - move_to_workspace_4: U dhaqaaq goobta shaqada 4 - focus_bottom: Hoos udhaca hoose - decrease_width: Ballaadhinta ballac - switch_workspace_2: U beddelo goobta shaqada 2 - move_to_workspace_1: U dhaqaaq goobta shaqada 1 - move_to_workspace_3: U dhaqaaq goobta shaqada 3 - increase_height: Kordhi dhererka - send_to_workspace_4: U dir goobta shaqada 4 - move_to_workspace_9: U dhaqaaq goobta shaqada 9 - reserve_float: Keydka sabuuradda - reserve_stack: Reebs Rap - switch_workspace_1: U beddelo goobta shaqada 1 - send_to_workspace_3: U dir goobta shaqada 3 - send_to_workspace_1: U dir goobta shaqada 1 - switch_workspace_7: U beddelo goobta shaqada 7 - send_to_workspace_8: U dir goobta shaqada 8 - move_to_workspace_8: U dhaqaaqso goobta shaqada 8 - send_to_workspace_6: U dir goobta shaqada 6 - focus_top: Xoogga saar dusha sare - reserve_left: Kaydsanaanta bidix - send_to_workspace_2: U dir goobta shaqada 2 - send_to_workspace_0: U dir goobta shaqada 0 - switch_workspace_0: U beddelo goobta shaqada 0 - decrease_height: Hoos u dhig dhererka - switch_workspace_4: U beddelo goobta shaqada 4 - move_to_workspace_6: U dhaqaaq goobta shaqada 6 - switch_workspace_6: U beddelo goobta shaqada 6 - enable: U fududee fulinta isku dhafan ee isku dhafan (Ahk) - enable_tooltip: >- - Disable Haddii aad hirgelin doontid gaagaaban adiga oo adeegsanaya api-ka - quruxda badan -loading: Loading ... -cancel: Burin -delete: Tirtirid -quit: Joojin -save: Badbaadin -inProgress: Horusocod ... -open: Furid +sides: + left: Bidix + bottom: Hoose + top: Dusha kore + right: Sax +header: + labels: + monitors: Kormeerayaasha + seelen_weg: Dock / Tootshar + shortcuts: Gaaban + seelen_bar: Qalabka Fancy Toolbar + general: Guud + specific_apps: Barnaamijyo gaar ah + seelen_wm: Maamulaha daaqada + developer: Abuuris + info: War +start: + message: >- + Ku soo dhawow SELEN Ui, oo ah jawiga desktop-ka ugu dambeeya oo leh + maamulaha Windows-ka oo lagu daro Maareeyaha Windows 11 Sahamiyaan marxalad + cusub oo hufnaan iyo fara badan + title: Soo dhawow! + message_accent: Ku dadaal wax soo saarkaaga qaabka! +general: + theme: + description: Sifo + author: Qoraa + placeholder: Xullo mawduuca + tags: Calaamadaha + label: Macluumaadka mawduuca + add: Ku dar mawduuc + added: Mawduuca mar hore ayaa lagu daray + enabled: Awood u yeelo mowduucyada + selected: La xushay + available: Qof heli karo + startup: Ku orod bilowga? + language: Af + icon_pack: + label: Xirmooyinka icon + accent_color: Midab caqabad +toolbar: + placeholder: + description: Sifo + author: Qoraa + select: Qaab dhismeedka Qalabka + enable: Keeniyaan Qalabka Fancy Toolbar + height: Dherer +wm: + border: + enable: Karti xadka daaqadaha + width: Xadka ballaca + offset: Xudduud xadka + author: Qoraa + description: Sifo + disabled_windows10: Maamulaha daaqada ayaan loo heli karin Windows 10. + workspace_offset: Goobaha shaqada ayaa ka dhigtay + enable: Karti maamulaha daaqada + layout: Khariidad + resize_delta: Dib u dhig Delta (%) + space_between_containers: Meel bannaan oo u dhexeeya weelka + workspace_padding: Goobta Goobta Goobta +weg: + items: + gap: Meel udhaxeysa waxyaabaha + label: Waxyaabaha + size: Shayga cabirka + zoom_size: Cabbirka soojiidashada (oo loo isticmaalo mowduucyada) + visible_separators: Kala-sooca muuqda + dock_side: Dhinaceeda dhinaceeda + width: Ballac + enable: Kartida DOCK / Turniinka + gap: Dalool + padding: Suur + margin: Margin + label: Dock / Tootshar + auto_hide: Auto qaraha +devtools: + app_folders: Faylka app + install_folder: Xeerka rakibaadda + enable: U oggolow qalabka horumarinta + data_folder: Faylka xogta + custom_config_file: Xamuul faylka caadiga ah ee config + settings_file: Faylka Dejinta + load: Xammuul +apps_configurations: + app: + options: + pinned: Shaashad + float: Sabbayn + unmanage: Aan lahayn + force: Xoog u maareeyaan + title_create: Abuuritaanka {{Magaca {Magaca} + bindings: Xirashada (Xusuusin labada ikhtiyaar ayaa loo baahan yahay) + ok_readonly: Tafatir sida cusub + monitor_placeholder: Midna + category: Dabaqad + options_label: Fursadaha dheeraadka ah + ok_edit: Cusboonaysiin + workspace: Shaqo-joojin + title_readonly: Daawashada {{,} + monitor: Kaabba-galaas + category_placeholder: Midna + name: Magac + workspace_placeholder: Midna + ok_create: Abuurid + title_edit: Tafatirka {{magacii} + identifier: + remove: Tirtir xannibaadda + matching_strategy: Istaraatiijiyadda iswaafajinta + negation: Ciriiri u dhigma + kind: Aqoonso + and: Iyo + add_block: Ku dar xannibaadda + or: Ama + id: Aqoonsiga + new: Cusub + bundled_title: App COLOND SOLDED SELEN + confirm_delete: Ma hubtaa inaad rabto inaad tirtirto qaabeyntan / s? + import: Soo dejin + confirm_delete_title: Xaqiiji Delete + export: Dhoofin + search: Raadin + swap: Isku beddelo + delete: Tirtirid + bundled_msg: >- + Qaabeyntan xirmada ma aha wax aan la taabtaan oo loogu talagalay inay ku + siiyaan khibradda ugu fiican ee aan la helin. Waxay si otomaatig ah u + habeeyaan codsiyada ugu caansan adiga. +extras: + exit: Jooji / bixitaan + github: GitHub + version: Werin + relaunch: Dib u beer + discord: Huf + links: Xiriirinta rasmiga ah +shortcuts: + labels: + reserve_right: Xaq u dhig + reserve_top: Keydka sare + reserve_bottom: Kaydsanaanta hoose + restore_sizes: Soo celinta cabirka + move_to_workspace_0: U dhaqaaq goobta shaqada 0 + focus_left: Ahrive bidix + switch_workspace_5: U beddelo goobta shaqada 5 + increase_width: Kordhi ballaadhan + send_to_workspace_9: U dir goobta shaqada 9 + switch_workspace_8: U beddelo goobta shaqada 8 + move_to_workspace_2: U dhaqaaq goobta shaqada 2 + move_to_workspace_5: U dhaqaaq goobta shaqada 5 + switch_workspace_9: U beddelo goobta shaqada 9 + focus_latest: Diirad saar + send_to_workspace_5: U dir goobta shaqada 5 + focus_right: Diiradda saara + switch_workspace_3: U beddelo goobta shaqada 3 + send_to_workspace_7: U dir goobta shaqada 7 + move_to_workspace_7: U dhaqaaq goobta shaqada 7 + move_to_workspace_4: U dhaqaaq goobta shaqada 4 + focus_bottom: Hoos udhaca hoose + decrease_width: Ballaadhinta ballac + switch_workspace_2: U beddelo goobta shaqada 2 + move_to_workspace_1: U dhaqaaq goobta shaqada 1 + move_to_workspace_3: U dhaqaaq goobta shaqada 3 + increase_height: Kordhi dhererka + send_to_workspace_4: U dir goobta shaqada 4 + move_to_workspace_9: U dhaqaaq goobta shaqada 9 + reserve_float: Keydka sabuuradda + reserve_stack: Reebs Rap + switch_workspace_1: U beddelo goobta shaqada 1 + send_to_workspace_3: U dir goobta shaqada 3 + send_to_workspace_1: U dir goobta shaqada 1 + switch_workspace_7: U beddelo goobta shaqada 7 + send_to_workspace_8: U dir goobta shaqada 8 + move_to_workspace_8: U dhaqaaqso goobta shaqada 8 + send_to_workspace_6: U dir goobta shaqada 6 + focus_top: Xoogga saar dusha sare + reserve_left: Kaydsanaanta bidix + send_to_workspace_2: U dir goobta shaqada 2 + send_to_workspace_0: U dir goobta shaqada 0 + switch_workspace_0: U beddelo goobta shaqada 0 + decrease_height: Hoos u dhig dhererka + switch_workspace_4: U beddelo goobta shaqada 4 + move_to_workspace_6: U dhaqaaq goobta shaqada 6 + switch_workspace_6: U beddelo goobta shaqada 6 + enable: U fududee fulinta isku dhafan ee isku dhafan (Ahk) + enable_tooltip: >- + Disable Haddii aad hirgelin doontid gaagaaban adiga oo adeegsanaya api-ka + quruxda badan +loading: Loading ... +cancel: Burin +delete: Tirtirid +quit: Joojin +save: Badbaadin +inProgress: Horusocod ... +open: Furid diff --git a/src/apps/settings/i18n/translations/sr.yml b/src/apps/settings/i18n/translations/sr.yml index 3eb601e8..f02c50ae 100644 --- a/src/apps/settings/i18n/translations/sr.yml +++ b/src/apps/settings/i18n/translations/sr.yml @@ -1,195 +1,195 @@ -sides: - bottom: Дно - right: Јел тако - left: Лево - top: На врху -header: - labels: - general: Генерал - shortcuts: Пречице - info: Информације - monitors: Монитори - seelen_bar: Фанци алатна трака - seelen_weg: Доцк / трака задатака - seelen_wm: Менаџер прозора - specific_apps: Специфичне апликације - developer: Разводнички -start: - title: Добродошли! - message_accent: Оптимизирајте своју продуктивност стилом! - message: >- - Добродошли у СЕЕЛЕН УИ, Ултимате Десктоп окружење са уграђеним виљушкар на - плочицем за повећање вашег Виндовс 11 искуства! Истражите нову еру - ефикасности и више задатака са нашим интуитивним интерфејсом и напредним - функцијама. -general: - theme: - tags: Ознаке - placeholder: Изаберите тему - label: Информације о темима - author: Аутор - enabled: Омогућене теме - description: Опис - added: Тема је већ додата - add: Додај тему - available: Доступан - selected: Изабран - startup: Ради на покретању? - language: Језик - icon_pack: - label: Паковање икона - accent_color: Боја нагласности -toolbar: - placeholder: - description: Опис - author: Аутор - select: Структура алатне траке - enable: Омогућите фанци траку са алаткама - height: Висина -wm: - border: - enable: Омогућите границу прозора - width: Ширина границе - offset: Помак на границу - description: Опис - space_between_containers: Простор између контејнера - enable: Омогући менаџер прозора - workspace_offset: Оффсет радних простора (маржи) - disabled_windows10: Менаџер прозора није доступан за Виндовс 10. - layout: Изглед - workspace_padding: Облога за радне просторе - resize_delta: Промените величину Делта (%) - author: Аутор -weg: - items: - zoom_size: Зуомирана величина (користи се за теме) - label: Предмети - visible_separators: Видљиви сепаратори - gap: Простор између предмета - size: Величина предмета - label: Доцк / трака задатака - gap: Празнина - enable: Омогући прикључак / траку задатака - padding: Подлокнути - width: Ширина - margin: Маргина - dock_side: Пристаниште - auto_hide: Аутоматска кожа -devtools: - enable: Омогућите алате за програмере - load: Оптеретити - app_folders: Мапе за апликације - custom_config_file: Учитајте прилагођену конфигуријску датотеку - install_folder: Инсталациона мапа - settings_file: Подешавања - data_folder: Мапа података -apps_configurations: - app: - options: - float: Пловак - pinned: Прикован - unmanage: Неукратити - force: Присилно управљање - category: Категорија - monitor_placeholder: Ниједан - ok_create: Креирај - workspace: Радни простор - workspace_placeholder: Ниједан - category_placeholder: Ниједан - ok_readonly: Уреди као ново - options_label: Додатне опције - ok_edit: ажурирање - title_edit: Уређивање {{наме}} - monitor: Монитор - title_readonly: Гледајући {{наме}} - title_create: Стварање {{наме}} - name: Назив - bindings: Везивање (белешка су обе опције потребне) - identifier: - remove: Избрисати блок - or: Или - id: Идентификатор - kind: Идентификовати - and: И - negation: Негирајте подударање - matching_strategy: Стратегија подударања - add_block: Додај блок - new: Нова - import: Увоз - confirm_delete_title: Потврдити брисање - search: Претрага - delete: Избрисати - bundled_msg: >- - Ове пакетне конфигурације нису уређене и дизајниране су да вам пруже најбоље - искуство без прилагођавања. Они аутоматски конфигуришу најчешће апликације - за вас. - export: Извоз - bundled_title: Апликација конфигурација у пакету са СЕЕЛЕН-ом - confirm_delete: Јесте ли сигурни да желите да избришете ову конфигурацију / с? - swap: Замена -extras: - relaunch: Поновити - exit: Престанак / излаз - version: Верзија - links: Званичне везе - discord: Нескладан - github: Гитхуб -shortcuts: - labels: - move_to_workspace_3: Пређите на радни простор 3 - focus_top: Фокусирати врх - send_to_workspace_9: Пошаљи на радни простор 9 - switch_workspace_3: Пређите на радни простор 3 - send_to_workspace_0: Пошаљи на радни простор 0 - send_to_workspace_4: Пошаљи на радни простор 4 - send_to_workspace_8: Пошаљи на радни простор 8 - switch_workspace_6: Пређите на радни простор 6 - send_to_workspace_7: Пошаљи на радни простор 7 - focus_latest: Фокусирати најновије - send_to_workspace_1: Пошаљи на радни простор 1 - switch_workspace_9: Пређите на радни простор 9 - focus_right: Фокусирати право - move_to_workspace_5: Пређите на радни простор 5 - increase_height: Повећати висину - switch_workspace_1: Пређите на радни простор 1 - send_to_workspace_5: Пошаљи на радни простор 5 - switch_workspace_4: Пређите на радни простор 4 - switch_workspace_5: Пређите на радни простор 5 - reserve_top: Резервисати врх - send_to_workspace_6: Пошаљи на радни простор 6 - reserve_bottom: Резервисати дно - focus_bottom: На дно фокуса - reserve_float: Резерват - move_to_workspace_0: Пређите на радни простор 0 - move_to_workspace_9: Пређите на радни простор 9 - switch_workspace_0: Пређите на радни простор 0 - increase_width: Повећати ширину - move_to_workspace_7: Пређите на радни простор 7 - reserve_right: Резервисати право - move_to_workspace_4: Пређите на радни простор 4 - decrease_height: Смањите висину - move_to_workspace_8: Прелазак на радни простор 8 - decrease_width: Смањите ширину - send_to_workspace_2: Пошаљи на Воркспаце 2 - focus_left: Фокус је остављен - reserve_left: Резерват лево - switch_workspace_8: Пређите на радни простор 8 - reserve_stack: Резервни сноп - switch_workspace_2: Пређите на радни простор 2 - restore_sizes: Вратите величине - move_to_workspace_6: Пређите на радни простор 6 - switch_workspace_7: Пређите на радни простор 7 - move_to_workspace_2: Пређите на радни простор 2 - send_to_workspace_3: Пошаљи на радни простор 3 - move_to_workspace_1: Прелазак на радни простор 1 - enable_tooltip: >- - Онемогућите ако ћете имплементирати сопствене пречице користећи СЕЕЛЕН ЦОРЕ - АПИ - enable: Омогућите интегрисане пречице (АХК) -quit: Одустати -inProgress: У току... -save: сачувати -cancel: Поништити, отказати -open: Отворен -delete: Избрисати -loading: Учитавање ... +sides: + bottom: Дно + right: Јел тако + left: Лево + top: На врху +header: + labels: + general: Генерал + shortcuts: Пречице + info: Информације + monitors: Монитори + seelen_bar: Фанци алатна трака + seelen_weg: Доцк / трака задатака + seelen_wm: Менаџер прозора + specific_apps: Специфичне апликације + developer: Разводнички +start: + title: Добродошли! + message_accent: Оптимизирајте своју продуктивност стилом! + message: >- + Добродошли у СЕЕЛЕН УИ, Ултимате Десктоп окружење са уграђеним виљушкар на + плочицем за повећање вашег Виндовс 11 искуства! Истражите нову еру + ефикасности и више задатака са нашим интуитивним интерфејсом и напредним + функцијама. +general: + theme: + tags: Ознаке + placeholder: Изаберите тему + label: Информације о темима + author: Аутор + enabled: Омогућене теме + description: Опис + added: Тема је већ додата + add: Додај тему + available: Доступан + selected: Изабран + startup: Ради на покретању? + language: Језик + icon_pack: + label: Паковање икона + accent_color: Боја нагласности +toolbar: + placeholder: + description: Опис + author: Аутор + select: Структура алатне траке + enable: Омогућите фанци траку са алаткама + height: Висина +wm: + border: + enable: Омогућите границу прозора + width: Ширина границе + offset: Помак на границу + description: Опис + space_between_containers: Простор између контејнера + enable: Омогући менаџер прозора + workspace_offset: Оффсет радних простора (маржи) + disabled_windows10: Менаџер прозора није доступан за Виндовс 10. + layout: Изглед + workspace_padding: Облога за радне просторе + resize_delta: Промените величину Делта (%) + author: Аутор +weg: + items: + zoom_size: Зуомирана величина (користи се за теме) + label: Предмети + visible_separators: Видљиви сепаратори + gap: Простор између предмета + size: Величина предмета + label: Доцк / трака задатака + gap: Празнина + enable: Омогући прикључак / траку задатака + padding: Подлокнути + width: Ширина + margin: Маргина + dock_side: Пристаниште + auto_hide: Аутоматска кожа +devtools: + enable: Омогућите алате за програмере + load: Оптеретити + app_folders: Мапе за апликације + custom_config_file: Учитајте прилагођену конфигуријску датотеку + install_folder: Инсталациона мапа + settings_file: Подешавања + data_folder: Мапа података +apps_configurations: + app: + options: + float: Пловак + pinned: Прикован + unmanage: Неукратити + force: Присилно управљање + category: Категорија + monitor_placeholder: Ниједан + ok_create: Креирај + workspace: Радни простор + workspace_placeholder: Ниједан + category_placeholder: Ниједан + ok_readonly: Уреди као ново + options_label: Додатне опције + ok_edit: ажурирање + title_edit: Уређивање {{наме}} + monitor: Монитор + title_readonly: Гледајући {{наме}} + title_create: Стварање {{наме}} + name: Назив + bindings: Везивање (белешка су обе опције потребне) + identifier: + remove: Избрисати блок + or: Или + id: Идентификатор + kind: Идентификовати + and: И + negation: Негирајте подударање + matching_strategy: Стратегија подударања + add_block: Додај блок + new: Нова + import: Увоз + confirm_delete_title: Потврдити брисање + search: Претрага + delete: Избрисати + bundled_msg: >- + Ове пакетне конфигурације нису уређене и дизајниране су да вам пруже најбоље + искуство без прилагођавања. Они аутоматски конфигуришу најчешће апликације + за вас. + export: Извоз + bundled_title: Апликација конфигурација у пакету са СЕЕЛЕН-ом + confirm_delete: Јесте ли сигурни да желите да избришете ову конфигурацију / с? + swap: Замена +extras: + relaunch: Поновити + exit: Престанак / излаз + version: Верзија + links: Званичне везе + discord: Нескладан + github: Гитхуб +shortcuts: + labels: + move_to_workspace_3: Пређите на радни простор 3 + focus_top: Фокусирати врх + send_to_workspace_9: Пошаљи на радни простор 9 + switch_workspace_3: Пређите на радни простор 3 + send_to_workspace_0: Пошаљи на радни простор 0 + send_to_workspace_4: Пошаљи на радни простор 4 + send_to_workspace_8: Пошаљи на радни простор 8 + switch_workspace_6: Пређите на радни простор 6 + send_to_workspace_7: Пошаљи на радни простор 7 + focus_latest: Фокусирати најновије + send_to_workspace_1: Пошаљи на радни простор 1 + switch_workspace_9: Пређите на радни простор 9 + focus_right: Фокусирати право + move_to_workspace_5: Пређите на радни простор 5 + increase_height: Повећати висину + switch_workspace_1: Пређите на радни простор 1 + send_to_workspace_5: Пошаљи на радни простор 5 + switch_workspace_4: Пређите на радни простор 4 + switch_workspace_5: Пређите на радни простор 5 + reserve_top: Резервисати врх + send_to_workspace_6: Пошаљи на радни простор 6 + reserve_bottom: Резервисати дно + focus_bottom: На дно фокуса + reserve_float: Резерват + move_to_workspace_0: Пређите на радни простор 0 + move_to_workspace_9: Пређите на радни простор 9 + switch_workspace_0: Пређите на радни простор 0 + increase_width: Повећати ширину + move_to_workspace_7: Пређите на радни простор 7 + reserve_right: Резервисати право + move_to_workspace_4: Пређите на радни простор 4 + decrease_height: Смањите висину + move_to_workspace_8: Прелазак на радни простор 8 + decrease_width: Смањите ширину + send_to_workspace_2: Пошаљи на Воркспаце 2 + focus_left: Фокус је остављен + reserve_left: Резерват лево + switch_workspace_8: Пређите на радни простор 8 + reserve_stack: Резервни сноп + switch_workspace_2: Пређите на радни простор 2 + restore_sizes: Вратите величине + move_to_workspace_6: Пређите на радни простор 6 + switch_workspace_7: Пређите на радни простор 7 + move_to_workspace_2: Пређите на радни простор 2 + send_to_workspace_3: Пошаљи на радни простор 3 + move_to_workspace_1: Прелазак на радни простор 1 + enable_tooltip: >- + Онемогућите ако ћете имплементирати сопствене пречице користећи СЕЕЛЕН ЦОРЕ + АПИ + enable: Омогућите интегрисане пречице (АХК) +quit: Одустати +inProgress: У току... +save: сачувати +cancel: Поништити, отказати +open: Отворен +delete: Избрисати +loading: Учитавање ... diff --git a/src/apps/settings/i18n/translations/sv.yml b/src/apps/settings/i18n/translations/sv.yml index 97426522..ec3633b4 100644 --- a/src/apps/settings/i18n/translations/sv.yml +++ b/src/apps/settings/i18n/translations/sv.yml @@ -1,195 +1,195 @@ -sides: - right: Höger - bottom: Botten - left: Vänster - top: Topp -header: - labels: - seelen_weg: Docka/arbetsfält - general: Allmän - developer: Utvecklare - seelen_wm: Fönsterchef - monitors: Monitorer - info: Information - specific_apps: Specifika appar - seelen_bar: Fint verktygsfält - shortcuts: Genvägar -start: - title: Välkommen! - message_accent: Optimera din produktivitet med stil! - message: >- - Välkommen till Seelen UI, den ultimata skrivbordsmiljön med en införlivad - kakling Windows Manager för att förbättra din Windows 11 -upplevelse! - Utforska en ny era av effektivitet och multitasking med vårt intuitiva - gränssnitt och avancerade funktioner. -general: - theme: - add: Lägga till tema - placeholder: Välj tema - author: Författare - added: Tema som redan har lagts till - description: Beskrivning - label: Temainformation - enabled: Aktiverade teman - tags: Taggar - selected: Vald - available: Tillgängliga - startup: Köras vid start? - language: Språk - icon_pack: - label: Ikonförpackningar - accent_color: Accentfärg -toolbar: - placeholder: - description: Beskrivning - author: Författare - select: Verktygsfältstruktur - height: Höjd - enable: Aktivera snyggt verktygsfält -wm: - border: - width: Gränsbredd - enable: Aktivera fönstergränsen - offset: Gränsförskjutning - author: Författare - layout: Layout - description: Beskrivning - resize_delta: Ändra ändra delta (%) - workspace_padding: Arbetsytor - enable: Aktivera fönsterhanterare - space_between_containers: Utrymme mellan containrar - disabled_windows10: Fönsterhanteraren är inte tillgänglig för Windows 10. - workspace_offset: Arbetsytor Offset (marginaler) -weg: - items: - zoom_size: Zoomad storlek (används för teman) - size: Objektstorlek - label: Föremål - gap: Utrymme mellan föremål - visible_separators: Synliga separatorer - width: Bredd - label: Docka/arbetsfält - gap: Glipa - auto_hide: Auto Hide - padding: Stoppning - margin: Marginal - enable: Aktivera bryggor/aktivitetsfält - dock_side: Brygga -devtools: - install_folder: Installationsmapp - load: Ladda - settings_file: Inställningsfil - custom_config_file: Ladda anpassad konfigurationsfil - data_folder: Datarmapp - app_folders: Appmappar - enable: Aktivera utvecklarverktyg -apps_configurations: - app: - options: - float: Flyta - force: Tvinga sig - pinned: Fästad - unmanage: Obehandla - category: Kategori - name: namn - workspace_placeholder: Ingen - title_readonly: Visa {{name}} - bindings: Bindning (Observera att båda alternativen krävs) - options_label: Extra alternativ - monitor_placeholder: Ingen - title_create: Skapa {{name}} - title_edit: Redge {{name}} - category_placeholder: Ingen - ok_create: Skapa - monitor: Övervaka - ok_edit: Uppdatering - workspace: Arbetsyta - ok_readonly: Redigera som ny - identifier: - and: OCH - remove: Radera block - id: Identifierare - or: ELLER - add_block: Lägga till - kind: Identifiera sig genom - negation: Negera matchning - matching_strategy: Matchningsstrategi - import: Importera - delete: Radera - confirm_delete_title: Bekräfta radering - new: Ny - swap: Byta - export: Exportera - search: Sök - confirm_delete: Är du säker på att du vill ta bort den här konfigurationen/s? - bundled_msg: >- - Dessa bundna konfigurationer är inte redigerbara och är utformade för att ge - dig den bästa upplevelsen utan anpassning. De konfigurerar automatiskt de - vanligaste applikationerna för dig. - bundled_title: App config bunded med seelen -extras: - exit: Sluta/avsluta - discord: Disharmoni - relaunch: Omstart - github: Github - version: Version - links: Officiella länkar -shortcuts: - labels: - move_to_workspace_1: Flytta till arbetsytan 1 - switch_workspace_2: Byt till arbetsyta 2 - increase_height: Öka höjden - increase_width: Öka bredd - move_to_workspace_3: Flytta till Workspace 3 - restore_sizes: Återställ storleken - focus_top: Focus topp - reserve_right: Reservera höger - switch_workspace_7: Byt till arbetsyta 7 - send_to_workspace_9: Skicka till Workspace 9 - focus_bottom: Fokusera botten - decrease_width: Minskande bredd - move_to_workspace_0: Flytta till arbetsytan 0 - send_to_workspace_8: Skicka till Workspace 8 - decrease_height: Minskande höjd - switch_workspace_0: Byt till arbetsyta 0 - send_to_workspace_0: Skicka till Workspace 0 - reserve_stack: Reservstack - send_to_workspace_5: Skicka till Workspace 5 - move_to_workspace_9: Flytta till Workspace 9 - switch_workspace_9: Byt till arbetsyta 9 - switch_workspace_6: Byt till arbetsyta 6 - send_to_workspace_2: Skicka till Workspace 2 - switch_workspace_8: Byt till arbetsyta 8 - send_to_workspace_3: Skicka till Workspace 3 - move_to_workspace_6: Flytta till Workspace 6 - send_to_workspace_4: Skicka till Workspace 4 - send_to_workspace_6: Skicka till Workspace 6 - move_to_workspace_8: Flytta till Workspace 8 - switch_workspace_3: Byt till arbetsyta 3 - focus_latest: Fokus senaste - send_to_workspace_7: Skicka till Workspace 7 - send_to_workspace_1: Skicka till Workspace 1 - move_to_workspace_7: Flytta till Workspace 7 - focus_left: Fokus vänster - move_to_workspace_2: Flytta till Workspace 2 - reserve_bottom: Reserv botten - switch_workspace_5: Byt till arbetsyta 5 - reserve_float: Reservflott - reserve_top: Reservtopp - switch_workspace_4: Byt till arbetsyta 4 - reserve_left: Reservera vänster - move_to_workspace_4: Flytta till Workspace 4 - switch_workspace_1: Byt till arbetsyta 1 - move_to_workspace_5: Flytta till arbetsytan 5 - focus_right: Fokusera rätt - enable: Aktivera integrerade genvägar (AHK) - enable_tooltip: >- - Inaktivera om du kommer att implementera dina egna genvägar med Seelen Core - API -loading: Läser in... -quit: Sluta -delete: Radera -inProgress: Pågående... -open: Öppen -cancel: Annullera -save: Spara +sides: + right: Höger + bottom: Botten + left: Vänster + top: Topp +header: + labels: + seelen_weg: Docka/arbetsfält + general: Allmän + developer: Utvecklare + seelen_wm: Fönsterchef + monitors: Monitorer + info: Information + specific_apps: Specifika appar + seelen_bar: Fint verktygsfält + shortcuts: Genvägar +start: + title: Välkommen! + message_accent: Optimera din produktivitet med stil! + message: >- + Välkommen till Seelen UI, den ultimata skrivbordsmiljön med en införlivad + kakling Windows Manager för att förbättra din Windows 11 -upplevelse! + Utforska en ny era av effektivitet och multitasking med vårt intuitiva + gränssnitt och avancerade funktioner. +general: + theme: + add: Lägga till tema + placeholder: Välj tema + author: Författare + added: Tema som redan har lagts till + description: Beskrivning + label: Temainformation + enabled: Aktiverade teman + tags: Taggar + selected: Vald + available: Tillgängliga + startup: Köras vid start? + language: Språk + icon_pack: + label: Ikonförpackningar + accent_color: Accentfärg +toolbar: + placeholder: + description: Beskrivning + author: Författare + select: Verktygsfältstruktur + height: Höjd + enable: Aktivera snyggt verktygsfält +wm: + border: + width: Gränsbredd + enable: Aktivera fönstergränsen + offset: Gränsförskjutning + author: Författare + layout: Layout + description: Beskrivning + resize_delta: Ändra ändra delta (%) + workspace_padding: Arbetsytor + enable: Aktivera fönsterhanterare + space_between_containers: Utrymme mellan containrar + disabled_windows10: Fönsterhanteraren är inte tillgänglig för Windows 10. + workspace_offset: Arbetsytor Offset (marginaler) +weg: + items: + zoom_size: Zoomad storlek (används för teman) + size: Objektstorlek + label: Föremål + gap: Utrymme mellan föremål + visible_separators: Synliga separatorer + width: Bredd + label: Docka/arbetsfält + gap: Glipa + auto_hide: Auto Hide + padding: Stoppning + margin: Marginal + enable: Aktivera bryggor/aktivitetsfält + dock_side: Brygga +devtools: + install_folder: Installationsmapp + load: Ladda + settings_file: Inställningsfil + custom_config_file: Ladda anpassad konfigurationsfil + data_folder: Datarmapp + app_folders: Appmappar + enable: Aktivera utvecklarverktyg +apps_configurations: + app: + options: + float: Flyta + force: Tvinga sig + pinned: Fästad + unmanage: Obehandla + category: Kategori + name: namn + workspace_placeholder: Ingen + title_readonly: Visa {{name}} + bindings: Bindning (Observera att båda alternativen krävs) + options_label: Extra alternativ + monitor_placeholder: Ingen + title_create: Skapa {{name}} + title_edit: Redge {{name}} + category_placeholder: Ingen + ok_create: Skapa + monitor: Övervaka + ok_edit: Uppdatering + workspace: Arbetsyta + ok_readonly: Redigera som ny + identifier: + and: OCH + remove: Radera block + id: Identifierare + or: ELLER + add_block: Lägga till + kind: Identifiera sig genom + negation: Negera matchning + matching_strategy: Matchningsstrategi + import: Importera + delete: Radera + confirm_delete_title: Bekräfta radering + new: Ny + swap: Byta + export: Exportera + search: Sök + confirm_delete: Är du säker på att du vill ta bort den här konfigurationen/s? + bundled_msg: >- + Dessa bundna konfigurationer är inte redigerbara och är utformade för att ge + dig den bästa upplevelsen utan anpassning. De konfigurerar automatiskt de + vanligaste applikationerna för dig. + bundled_title: App config bunded med seelen +extras: + exit: Sluta/avsluta + discord: Disharmoni + relaunch: Omstart + github: Github + version: Version + links: Officiella länkar +shortcuts: + labels: + move_to_workspace_1: Flytta till arbetsytan 1 + switch_workspace_2: Byt till arbetsyta 2 + increase_height: Öka höjden + increase_width: Öka bredd + move_to_workspace_3: Flytta till Workspace 3 + restore_sizes: Återställ storleken + focus_top: Focus topp + reserve_right: Reservera höger + switch_workspace_7: Byt till arbetsyta 7 + send_to_workspace_9: Skicka till Workspace 9 + focus_bottom: Fokusera botten + decrease_width: Minskande bredd + move_to_workspace_0: Flytta till arbetsytan 0 + send_to_workspace_8: Skicka till Workspace 8 + decrease_height: Minskande höjd + switch_workspace_0: Byt till arbetsyta 0 + send_to_workspace_0: Skicka till Workspace 0 + reserve_stack: Reservstack + send_to_workspace_5: Skicka till Workspace 5 + move_to_workspace_9: Flytta till Workspace 9 + switch_workspace_9: Byt till arbetsyta 9 + switch_workspace_6: Byt till arbetsyta 6 + send_to_workspace_2: Skicka till Workspace 2 + switch_workspace_8: Byt till arbetsyta 8 + send_to_workspace_3: Skicka till Workspace 3 + move_to_workspace_6: Flytta till Workspace 6 + send_to_workspace_4: Skicka till Workspace 4 + send_to_workspace_6: Skicka till Workspace 6 + move_to_workspace_8: Flytta till Workspace 8 + switch_workspace_3: Byt till arbetsyta 3 + focus_latest: Fokus senaste + send_to_workspace_7: Skicka till Workspace 7 + send_to_workspace_1: Skicka till Workspace 1 + move_to_workspace_7: Flytta till Workspace 7 + focus_left: Fokus vänster + move_to_workspace_2: Flytta till Workspace 2 + reserve_bottom: Reserv botten + switch_workspace_5: Byt till arbetsyta 5 + reserve_float: Reservflott + reserve_top: Reservtopp + switch_workspace_4: Byt till arbetsyta 4 + reserve_left: Reservera vänster + move_to_workspace_4: Flytta till Workspace 4 + switch_workspace_1: Byt till arbetsyta 1 + move_to_workspace_5: Flytta till arbetsytan 5 + focus_right: Fokusera rätt + enable: Aktivera integrerade genvägar (AHK) + enable_tooltip: >- + Inaktivera om du kommer att implementera dina egna genvägar med Seelen Core + API +loading: Läser in... +quit: Sluta +delete: Radera +inProgress: Pågående... +open: Öppen +cancel: Annullera +save: Spara diff --git a/src/apps/settings/i18n/translations/sw.yml b/src/apps/settings/i18n/translations/sw.yml index f90a79b2..03831d32 100644 --- a/src/apps/settings/i18n/translations/sw.yml +++ b/src/apps/settings/i18n/translations/sw.yml @@ -1,191 +1,191 @@ -sides: - right: Haki - top: Juu - left: Kushoto - bottom: Chini -header: - labels: - developer: Msanidi programu - seelen_wm: Meneja wa Window - info: Habari - seelen_bar: Zana ya Dhana - shortcuts: Njia za mkato - specific_apps: Programu maalum - seelen_weg: Dock/Taskbar - general: Mkuu - monitors: Wachunguzi -start: - message_accent: Boresha tija yako na mtindo! - message: >- - Karibu Seelen UI, mazingira ya mwisho ya desktop na meneja wa Windows - aliyeingizwa ili kuongeza uzoefu wako wa Windows 11! Chunguza enzi mpya ya - ufanisi na multitasking na interface yetu ya angavu na sifa za hali ya juu. - title: Karibu! -general: - theme: - enabled: Mada zilizowezeshwa - description: Maelezo - author: Mwandishi - tags: Lebo - label: Habari ya mada - added: Mada tayari imeongezwa - add: Ongeza mandhari - placeholder: Chagua mandhari - selected: Kuchaguliwa - available: Inapatikana - language: Lugha - startup: Kuendesha kuanza? - icon_pack: - label: Pakiti za ikoni - accent_color: Rangi ya lafudhi -toolbar: - placeholder: - description: Maelezo - select: Muundo wa zana - author: Mwandishi - enable: Wezesha zana ya dhana - height: Urefu -wm: - border: - enable: Wezesha mpaka wa dirisha - width: Upana wa mpaka - offset: Kukabiliana na mpaka - author: Mwandishi - resize_delta: Rudisha Delta (%) - workspace_offset: Nafasi za kazi za kukabiliana (pembezoni) - description: Maelezo - disabled_windows10: Meneja wa windows haipatikani kwa Windows 10. - space_between_containers: Nafasi kati ya vyombo - enable: Wezesha Meneja wa Dirisha - layout: Mpangilio - workspace_padding: Nafasi za kazi -weg: - items: - size: Saizi ya bidhaa - gap: Nafasi kati ya vitu - label: Vitu - zoom_size: Saizi iliyoondolewa (inayotumika kwa mada) - visible_separators: Watenganisho unaoonekana - gap: Pengo - dock_side: Kizimbani - width: Upana - margin: Margin - padding: Padding - auto_hide: Kujificha kiotomatiki - label: Dock/Taskbar - enable: Wezesha Dock/Taskbar -devtools: - app_folders: Folda za programu - enable: Wezesha zana za msanidi programu - load: Mzigo - settings_file: Faili ya mipangilio - data_folder: Folda ya data - install_folder: Folda ya usanikishaji - custom_config_file: Pakia faili ya usanidi wa kawaida -apps_configurations: - app: - options: - unmanage: Kuhama - force: Nguvu kusimamia - pinned: Iliyoandikwa - float: Kuelea - title_create: Kuunda {{jina}} - title_readonly: Kuangalia {{jina}} - category_placeholder: Hakuna - options_label: Chaguzi za ziada - monitor_placeholder: Hakuna - monitor: Kufuatilia - ok_edit: Sasisha - name: Jina - bindings: Kufunga (kumbuka chaguzi zote mbili zinahitajika) - category: Jamii - workspace: Nafasi ya kazi - ok_readonly: Hariri kama mpya - workspace_placeholder: Hakuna - ok_create: Unda - title_edit: Kuhariri {{jina}} - identifier: - negation: Negate kulinganisha - or: Au - kind: Tambua na - remove: Futa block - matching_strategy: Mkakati wa kulinganisha - and: Na - id: Kitambulisho - add_block: Ongeza block - confirm_delete: Je! Una uhakika unataka kufuta usanidi huu/s? - bundled_msg: >- - Usanidi huu uliowekwa wazi hauwezi kuhaririwa na umeundwa kukupa uzoefu bora - bila ubinafsishaji. Wao husanidi moja kwa moja programu za kawaida kwako. - export: Kuuza nje - bundled_title: Programu ya kusanidi na Seelen - search: Tafuta - new: Mpya - delete: Futa - import: Kuagiza - confirm_delete_title: Thibitisha Futa - swap: Kubadilishana -extras: - relaunch: Kuzindua tena - discord: Ugomvi - github: GitHub - exit: Acha/exit - links: Viungo rasmi - version: Toleo -shortcuts: - labels: - focus_top: Kuzingatia juu - increase_width: Ongeza upana - restore_sizes: Kurejesha ukubwa - focus_left: Kuzingatia kushoto - switch_workspace_2: Badilika kwenye nafasi ya kazi 2 - decrease_height: Kupungua urefu - reserve_top: Hifadhi juu - reserve_right: Hifadhi haki - reserve_stack: Hifadhi ya Hifadhi - focus_latest: Kuzingatia hivi karibuni - reserve_bottom: Hifadhi chini - focus_right: Zingatia kulia - switch_workspace_9: Badilika kwa nafasi ya kazi 9 - switch_workspace_8: Badilika kwa nafasi ya kazi 8 - move_to_workspace_5: Hoja kwa nafasi ya kazi 5 - switch_workspace_1: Badilika kwenye nafasi ya kazi 1 - send_to_workspace_1: Tuma kwa nafasi ya kazi 1 - send_to_workspace_8: Tuma kwa nafasi ya kazi 8 - send_to_workspace_5: Tuma kwa nafasi ya kazi 5 - switch_workspace_5: Badilika kwa nafasi ya kazi 5 - send_to_workspace_4: Tuma kwa nafasi ya kazi 4 - move_to_workspace_2: Hoja kwenye nafasi ya kazi 2 - move_to_workspace_8: Hoja kwa nafasi ya kazi 8 - move_to_workspace_3: Hoja kwenye nafasi ya kazi 3 - reserve_float: Hifadhi kuelea - reserve_left: Hifadhi kushoto - switch_workspace_6: Badilika kwa nafasi ya kazi 6 - decrease_width: Punguza upana - send_to_workspace_6: Tuma kwa nafasi ya kazi 6 - focus_bottom: Kuzingatia chini - switch_workspace_7: Badilika kwa nafasi ya kazi 7 - move_to_workspace_7: Hoja kwa nafasi ya kazi 7 - increase_height: Ongeza urefu - send_to_workspace_2: Tuma kwa nafasi ya kazi 2 - move_to_workspace_0: Hoja kwenye nafasi ya kazi 0 - move_to_workspace_6: Hoja kwa nafasi ya kazi 6 - send_to_workspace_0: Tuma kwa nafasi ya kazi 0 - switch_workspace_3: Badilika kwa nafasi ya kazi 3 - switch_workspace_4: Badilika kwa nafasi ya kazi 4 - send_to_workspace_3: Tuma kwa nafasi ya kazi 3 - move_to_workspace_1: Hoja kwa nafasi ya kazi 1 - switch_workspace_0: Badilika kwenye nafasi ya kazi 0 - send_to_workspace_7: Tuma kwa nafasi ya kazi 7 - move_to_workspace_4: Hoja kwa nafasi ya kazi 4 - send_to_workspace_9: Tuma kwa nafasi ya kazi 9 - move_to_workspace_9: Hoja kwa nafasi ya kazi 9 - enable: Wezesha njia za mkato zilizojumuishwa (AHK) - enable_tooltip: Lemaza ikiwa utatumia njia zako za mkato kwa kutumia API ya Seelen Core -inProgress: Inaendelea... -loading: Inapakia ... -delete: Futa -cancel: Ghairi -save: Kuokoa -quit: Acha -open: Wazi +sides: + right: Haki + top: Juu + left: Kushoto + bottom: Chini +header: + labels: + developer: Msanidi programu + seelen_wm: Meneja wa Window + info: Habari + seelen_bar: Zana ya Dhana + shortcuts: Njia za mkato + specific_apps: Programu maalum + seelen_weg: Dock/Taskbar + general: Mkuu + monitors: Wachunguzi +start: + message_accent: Boresha tija yako na mtindo! + message: >- + Karibu Seelen UI, mazingira ya mwisho ya desktop na meneja wa Windows + aliyeingizwa ili kuongeza uzoefu wako wa Windows 11! Chunguza enzi mpya ya + ufanisi na multitasking na interface yetu ya angavu na sifa za hali ya juu. + title: Karibu! +general: + theme: + enabled: Mada zilizowezeshwa + description: Maelezo + author: Mwandishi + tags: Lebo + label: Habari ya mada + added: Mada tayari imeongezwa + add: Ongeza mandhari + placeholder: Chagua mandhari + selected: Kuchaguliwa + available: Inapatikana + language: Lugha + startup: Kuendesha kuanza? + icon_pack: + label: Pakiti za ikoni + accent_color: Rangi ya lafudhi +toolbar: + placeholder: + description: Maelezo + select: Muundo wa zana + author: Mwandishi + enable: Wezesha zana ya dhana + height: Urefu +wm: + border: + enable: Wezesha mpaka wa dirisha + width: Upana wa mpaka + offset: Kukabiliana na mpaka + author: Mwandishi + resize_delta: Rudisha Delta (%) + workspace_offset: Nafasi za kazi za kukabiliana (pembezoni) + description: Maelezo + disabled_windows10: Meneja wa windows haipatikani kwa Windows 10. + space_between_containers: Nafasi kati ya vyombo + enable: Wezesha Meneja wa Dirisha + layout: Mpangilio + workspace_padding: Nafasi za kazi +weg: + items: + size: Saizi ya bidhaa + gap: Nafasi kati ya vitu + label: Vitu + zoom_size: Saizi iliyoondolewa (inayotumika kwa mada) + visible_separators: Watenganisho unaoonekana + gap: Pengo + dock_side: Kizimbani + width: Upana + margin: Margin + padding: Padding + auto_hide: Kujificha kiotomatiki + label: Dock/Taskbar + enable: Wezesha Dock/Taskbar +devtools: + app_folders: Folda za programu + enable: Wezesha zana za msanidi programu + load: Mzigo + settings_file: Faili ya mipangilio + data_folder: Folda ya data + install_folder: Folda ya usanikishaji + custom_config_file: Pakia faili ya usanidi wa kawaida +apps_configurations: + app: + options: + unmanage: Kuhama + force: Nguvu kusimamia + pinned: Iliyoandikwa + float: Kuelea + title_create: Kuunda {{jina}} + title_readonly: Kuangalia {{jina}} + category_placeholder: Hakuna + options_label: Chaguzi za ziada + monitor_placeholder: Hakuna + monitor: Kufuatilia + ok_edit: Sasisha + name: Jina + bindings: Kufunga (kumbuka chaguzi zote mbili zinahitajika) + category: Jamii + workspace: Nafasi ya kazi + ok_readonly: Hariri kama mpya + workspace_placeholder: Hakuna + ok_create: Unda + title_edit: Kuhariri {{jina}} + identifier: + negation: Negate kulinganisha + or: Au + kind: Tambua na + remove: Futa block + matching_strategy: Mkakati wa kulinganisha + and: Na + id: Kitambulisho + add_block: Ongeza block + confirm_delete: Je! Una uhakika unataka kufuta usanidi huu/s? + bundled_msg: >- + Usanidi huu uliowekwa wazi hauwezi kuhaririwa na umeundwa kukupa uzoefu bora + bila ubinafsishaji. Wao husanidi moja kwa moja programu za kawaida kwako. + export: Kuuza nje + bundled_title: Programu ya kusanidi na Seelen + search: Tafuta + new: Mpya + delete: Futa + import: Kuagiza + confirm_delete_title: Thibitisha Futa + swap: Kubadilishana +extras: + relaunch: Kuzindua tena + discord: Ugomvi + github: GitHub + exit: Acha/exit + links: Viungo rasmi + version: Toleo +shortcuts: + labels: + focus_top: Kuzingatia juu + increase_width: Ongeza upana + restore_sizes: Kurejesha ukubwa + focus_left: Kuzingatia kushoto + switch_workspace_2: Badilika kwenye nafasi ya kazi 2 + decrease_height: Kupungua urefu + reserve_top: Hifadhi juu + reserve_right: Hifadhi haki + reserve_stack: Hifadhi ya Hifadhi + focus_latest: Kuzingatia hivi karibuni + reserve_bottom: Hifadhi chini + focus_right: Zingatia kulia + switch_workspace_9: Badilika kwa nafasi ya kazi 9 + switch_workspace_8: Badilika kwa nafasi ya kazi 8 + move_to_workspace_5: Hoja kwa nafasi ya kazi 5 + switch_workspace_1: Badilika kwenye nafasi ya kazi 1 + send_to_workspace_1: Tuma kwa nafasi ya kazi 1 + send_to_workspace_8: Tuma kwa nafasi ya kazi 8 + send_to_workspace_5: Tuma kwa nafasi ya kazi 5 + switch_workspace_5: Badilika kwa nafasi ya kazi 5 + send_to_workspace_4: Tuma kwa nafasi ya kazi 4 + move_to_workspace_2: Hoja kwenye nafasi ya kazi 2 + move_to_workspace_8: Hoja kwa nafasi ya kazi 8 + move_to_workspace_3: Hoja kwenye nafasi ya kazi 3 + reserve_float: Hifadhi kuelea + reserve_left: Hifadhi kushoto + switch_workspace_6: Badilika kwa nafasi ya kazi 6 + decrease_width: Punguza upana + send_to_workspace_6: Tuma kwa nafasi ya kazi 6 + focus_bottom: Kuzingatia chini + switch_workspace_7: Badilika kwa nafasi ya kazi 7 + move_to_workspace_7: Hoja kwa nafasi ya kazi 7 + increase_height: Ongeza urefu + send_to_workspace_2: Tuma kwa nafasi ya kazi 2 + move_to_workspace_0: Hoja kwenye nafasi ya kazi 0 + move_to_workspace_6: Hoja kwa nafasi ya kazi 6 + send_to_workspace_0: Tuma kwa nafasi ya kazi 0 + switch_workspace_3: Badilika kwa nafasi ya kazi 3 + switch_workspace_4: Badilika kwa nafasi ya kazi 4 + send_to_workspace_3: Tuma kwa nafasi ya kazi 3 + move_to_workspace_1: Hoja kwa nafasi ya kazi 1 + switch_workspace_0: Badilika kwenye nafasi ya kazi 0 + send_to_workspace_7: Tuma kwa nafasi ya kazi 7 + move_to_workspace_4: Hoja kwa nafasi ya kazi 4 + send_to_workspace_9: Tuma kwa nafasi ya kazi 9 + move_to_workspace_9: Hoja kwa nafasi ya kazi 9 + enable: Wezesha njia za mkato zilizojumuishwa (AHK) + enable_tooltip: Lemaza ikiwa utatumia njia zako za mkato kwa kutumia API ya Seelen Core +inProgress: Inaendelea... +loading: Inapakia ... +delete: Futa +cancel: Ghairi +save: Kuokoa +quit: Acha +open: Wazi diff --git a/src/apps/settings/i18n/translations/ta.yml b/src/apps/settings/i18n/translations/ta.yml index 0727fee5..dde30208 100644 --- a/src/apps/settings/i18n/translations/ta.yml +++ b/src/apps/settings/i18n/translations/ta.yml @@ -1,195 +1,195 @@ -sides: - bottom: கீழே - top: மேல் - right: சரி - left: விட்டு -header: - labels: - seelen_wm: சாளர மேலாளர் - info: தகவல் - monitors: கண்காணிப்பாளர்கள் - developer: டெவலப்பர் - shortcuts: குறுக்குவழிகள் - general: பொது - seelen_weg: கப்பல்துறை/பணிப்பட்டி - specific_apps: குறிப்பிட்ட பயன்பாடுகள் - seelen_bar: ஆடம்பரமான கருவிப்பட்டி -start: - title: வரவேற்பு! - message_accent: பாணியுடன் உங்கள் உற்பத்தித்திறனை மேம்படுத்துங்கள்! - message: >- - உங்கள் Windows 11 அனுபவத்தை மேம்படுத்த, ஒருங்கிணைக்கப்பட்ட டைலிங் விண்டோஸ் - மேலாளருடன் கூடிய இறுதி டெஸ்க்டாப் சூழலான Seelen UIக்கு வரவேற்கிறோம்! எங்கள் - உள்ளுணர்வு இடைமுகம் மற்றும் மேம்பட்ட அம்சங்களுடன் செயல்திறன் மற்றும் - பல்பணியின் புதிய சகாப்தத்தை ஆராயுங்கள். -general: - theme: - tags: குறிச்சொற்கள் - placeholder: தீம் தேர்ந்தெடுக்கவும் - description: விளக்கம் - author: நூலாசிரியர் - enabled: இயக்கப்பட்ட தீம்கள் - add: தீம் சேர்க்கவும் - added: தீம் ஏற்கனவே சேர்க்கப்பட்டது - label: தீம் தகவல் - available: கிடைக்கிறது - selected: தேர்ந்தெடுக்கப்பட்டது - language: மொழி - startup: தொடக்கத்தில் இயக்கவா? - icon_pack: - label: ஐகான் பொதிகள் - accent_color: உச்சரிப்பு நிறம் -toolbar: - placeholder: - author: நூலாசிரியர் - description: விளக்கம் - select: கருவிப்பட்டி அமைப்பு - height: உயரம் - enable: ஆடம்பரமான கருவிப்பட்டியை இயக்கவும் -wm: - border: - width: பார்டர் அகலம் - enable: சாளரத்தின் எல்லையை இயக்கு - offset: பார்டர் ஆஃப்செட் - author: நூலாசிரியர் - description: விளக்கம் - space_between_containers: கொள்கலன்களுக்கு இடையில் இடைவெளி - workspace_padding: பணியிடங்கள் திணிப்பு - resize_delta: டெல்டாவின் அளவை மாற்று (%) - enable: சாளர மேலாளரை இயக்கு - disabled_windows10: விண்டோஸ் 10 க்கு சாளர மேலாளர் கிடைக்கவில்லை. - workspace_offset: பணியிடங்கள் ஆஃப்செட் (விளிம்புகள்) - layout: தளவமைப்பு -weg: - items: - label: பொருட்களை - size: பொருளின் அளவு - visible_separators: காணக்கூடிய பிரிப்பான்கள் - gap: பொருட்களுக்கு இடையே உள்ள இடம் - zoom_size: பெரிதாக்கப்பட்ட அளவு (தீம்களுக்குப் பயன்படுத்தப்படுகிறது) - auto_hide: தானாக மறை - padding: திணிப்பு - label: கப்பல்துறை/பணிப்பட்டி - margin: விளிம்பு - gap: இடைவெளி - width: அகலம் - enable: டாக்/டாஸ்க்பாரை இயக்கவும் - dock_side: டாக் சைட் -devtools: - install_folder: நிறுவல் கோப்புறை - enable: டெவலப்பர் கருவிகளை இயக்கு - custom_config_file: தனிப்பயன் கட்டமைப்பு கோப்பை ஏற்றவும் - app_folders: பயன்பாட்டு கோப்புறைகள் - data_folder: தரவு கோப்புறை - load: ஏற்றவும் - settings_file: அமைப்புகள் கோப்பு -apps_configurations: - app: - options: - pinned: பின் செய்யப்பட்டது - float: மிதவை - unmanage: நிர்வகியுங்கள் - force: கட்டாயம் நிர்வகி - monitor: கண்காணிக்கவும் - options_label: கூடுதல் விருப்பங்கள் - title_create: '{{name}} உருவாக்குகிறது' - workspace: பணியிடம் - workspace_placeholder: இல்லை - category_placeholder: இல்லை - monitor_placeholder: இல்லை - name: பெயர் - category: வகை - ok_create: உருவாக்கு - title_readonly: '{{name}} பார்க்கிறது' - ok_edit: புதுப்பிக்கவும் - ok_readonly: புதியதாக திருத்தவும் - title_edit: திருத்துகிறது {{name}} - bindings: பிணைப்பு (இரண்டு விருப்பங்களும் தேவை என்பதை நினைவில் கொள்ளவும்) - identifier: - and: மற்றும் - remove: தடுப்பை நீக்கு - negation: பொருத்தத்தை மறுக்கவும் - id: அடையாளங்காட்டி - add_block: தொகுதியைச் சேர்க்கவும் - or: அல்லது - kind: மூலம் அடையாளம் காணவும் - matching_strategy: பொருந்தும் உத்தி - export: ஏற்றுமதி - confirm_delete_title: நீக்குவதை உறுதிப்படுத்தவும் - delete: அழி - bundled_title: பயன்பாட்டு கட்டமைப்பு சீலனுடன் தொகுக்கப்பட்டுள்ளது - confirm_delete: இந்த உள்ளமைவு/களை நிச்சயமாக நீக்க விரும்புகிறீர்களா? - bundled_msg: >- - இந்தத் தொகுக்கப்பட்ட உள்ளமைவுகளைத் திருத்த முடியாது மற்றும் தனிப்பயனாக்கம் - இல்லாமல் சிறந்த அனுபவத்தை உங்களுக்கு வழங்கும் வகையில் வடிவமைக்கப்பட்டுள்ளது. - உங்களுக்கான பொதுவான பயன்பாடுகளை அவை தானாகவே கட்டமைக்கும். - import: இறக்குமதி - search: தேடு - swap: இடமாற்று - new: புதியது -extras: - discord: கருத்து வேறுபாடு - exit: வெளியேறு/வெளியேறு - links: அதிகாரப்பூர்வ இணைப்புகள் - relaunch: மறுதொடக்கம் - version: பதிப்பு - github: கிட்ஹப் -shortcuts: - labels: - focus_latest: சமீபத்திய கவனம் - send_to_workspace_2: பணியிடத்திற்கு அனுப்பு 2 - increase_height: உயரத்தை அதிகரிக்கவும் - restore_sizes: அளவுகளை மீட்டமை - increase_width: அகலத்தை அதிகரிக்கவும் - switch_workspace_1: பணியிடத்திற்கு மாறவும் 1 - send_to_workspace_4: பணியிடத்திற்கு அனுப்பு 4 - move_to_workspace_5: பணியிடத்திற்கு நகர்த்து 5 - reserve_right: ரிசர்வ் ரைட் - switch_workspace_6: பணியிடத்திற்கு மாறவும் 6 - send_to_workspace_1: பணியிடத்திற்கு அனுப்பு 1 - send_to_workspace_0: பணியிடம் 0க்கு அனுப்பவும் - focus_right: ஃபோகஸ் ரைட் - switch_workspace_0: பணியிடம் 0க்கு மாறவும் - reserve_float: ரிசர்வ் ஃப்ளோட் - reserve_left: ரிசர்வ் இடது - switch_workspace_5: பணியிடத்திற்கு மாறவும் 5 - focus_top: ஃபோகஸ் டாப் - move_to_workspace_0: பணியிடம் 0க்கு நகர்த்தவும் - move_to_workspace_1: பணியிடத்திற்கு நகர்த்து 1 - move_to_workspace_6: பணியிடத்திற்கு நகர்த்து 6 - switch_workspace_2: பணியிடத்திற்கு மாறவும் 2 - reserve_stack: ரிசர்வ் ஸ்டாக் - decrease_width: அகலத்தை குறைக்கவும் - switch_workspace_8: பணியிடத்திற்கு மாறவும் 8 - send_to_workspace_8: பணியிடம் 8க்கு அனுப்பவும் - reserve_top: ரிசர்வ் டாப் - send_to_workspace_5: பணியிடத்திற்கு அனுப்பு 5 - focus_left: இடதுபுறத்தில் கவனம் செலுத்துங்கள் - move_to_workspace_4: பணியிடத்திற்கு நகர்த்து 4 - send_to_workspace_9: பணியிடம் 9க்கு அனுப்பவும் - move_to_workspace_2: பணியிடத்திற்கு நகர்த்து 2 - move_to_workspace_9: பணியிடத்திற்கு நகர்த்து 9 - send_to_workspace_3: பணியிடத்திற்கு அனுப்பு 3 - send_to_workspace_7: பணியிடம் 7க்கு அனுப்பவும் - decrease_height: உயரத்தைக் குறைக்கவும் - send_to_workspace_6: பணியிடத்திற்கு அனுப்பு 6 - switch_workspace_4: பணியிடத்திற்கு மாறவும் 4 - reserve_bottom: ரிசர்வ் பாட்டம் - move_to_workspace_8: பணியிடத்திற்கு நகர்த்து 8 - move_to_workspace_3: பணியிடத்திற்கு நகர்த்து 3 - switch_workspace_3: பணியிடத்திற்கு மாறவும் 3 - move_to_workspace_7: பணியிடத்திற்கு நகர்த்து 7 - switch_workspace_9: பணியிடத்திற்கு மாறவும் 9 - focus_bottom: கீழே கவனம் செலுத்துங்கள் - switch_workspace_7: பணியிடம் 7க்கு மாறவும் - enable: ஒருங்கிணைந்த குறுக்குவழிகளை இயக்கு (ahk) - enable_tooltip: >- - சீலன் கோர் ஏபிஐ பயன்படுத்தி உங்கள் சொந்த ஷார்ட்கட்களை செயல்படுத்தினால் - முடக்கவும் -inProgress: செயல்பாட்டில் உள்ளது... -cancel: ரத்து செய் -quit: விட்டுவிட -delete: அழி -loading: ஏற்றுகிறது... -save: சேமிக்கவும் -open: திற +sides: + bottom: கீழே + top: மேல் + right: சரி + left: விட்டு +header: + labels: + seelen_wm: சாளர மேலாளர் + info: தகவல் + monitors: கண்காணிப்பாளர்கள் + developer: டெவலப்பர் + shortcuts: குறுக்குவழிகள் + general: பொது + seelen_weg: கப்பல்துறை/பணிப்பட்டி + specific_apps: குறிப்பிட்ட பயன்பாடுகள் + seelen_bar: ஆடம்பரமான கருவிப்பட்டி +start: + title: வரவேற்பு! + message_accent: பாணியுடன் உங்கள் உற்பத்தித்திறனை மேம்படுத்துங்கள்! + message: >- + உங்கள் Windows 11 அனுபவத்தை மேம்படுத்த, ஒருங்கிணைக்கப்பட்ட டைலிங் விண்டோஸ் + மேலாளருடன் கூடிய இறுதி டெஸ்க்டாப் சூழலான Seelen UIக்கு வரவேற்கிறோம்! எங்கள் + உள்ளுணர்வு இடைமுகம் மற்றும் மேம்பட்ட அம்சங்களுடன் செயல்திறன் மற்றும் + பல்பணியின் புதிய சகாப்தத்தை ஆராயுங்கள். +general: + theme: + tags: குறிச்சொற்கள் + placeholder: தீம் தேர்ந்தெடுக்கவும் + description: விளக்கம் + author: நூலாசிரியர் + enabled: இயக்கப்பட்ட தீம்கள் + add: தீம் சேர்க்கவும் + added: தீம் ஏற்கனவே சேர்க்கப்பட்டது + label: தீம் தகவல் + available: கிடைக்கிறது + selected: தேர்ந்தெடுக்கப்பட்டது + language: மொழி + startup: தொடக்கத்தில் இயக்கவா? + icon_pack: + label: ஐகான் பொதிகள் + accent_color: உச்சரிப்பு நிறம் +toolbar: + placeholder: + author: நூலாசிரியர் + description: விளக்கம் + select: கருவிப்பட்டி அமைப்பு + height: உயரம் + enable: ஆடம்பரமான கருவிப்பட்டியை இயக்கவும் +wm: + border: + width: பார்டர் அகலம் + enable: சாளரத்தின் எல்லையை இயக்கு + offset: பார்டர் ஆஃப்செட் + author: நூலாசிரியர் + description: விளக்கம் + space_between_containers: கொள்கலன்களுக்கு இடையில் இடைவெளி + workspace_padding: பணியிடங்கள் திணிப்பு + resize_delta: டெல்டாவின் அளவை மாற்று (%) + enable: சாளர மேலாளரை இயக்கு + disabled_windows10: விண்டோஸ் 10 க்கு சாளர மேலாளர் கிடைக்கவில்லை. + workspace_offset: பணியிடங்கள் ஆஃப்செட் (விளிம்புகள்) + layout: தளவமைப்பு +weg: + items: + label: பொருட்களை + size: பொருளின் அளவு + visible_separators: காணக்கூடிய பிரிப்பான்கள் + gap: பொருட்களுக்கு இடையே உள்ள இடம் + zoom_size: பெரிதாக்கப்பட்ட அளவு (தீம்களுக்குப் பயன்படுத்தப்படுகிறது) + auto_hide: தானாக மறை + padding: திணிப்பு + label: கப்பல்துறை/பணிப்பட்டி + margin: விளிம்பு + gap: இடைவெளி + width: அகலம் + enable: டாக்/டாஸ்க்பாரை இயக்கவும் + dock_side: டாக் சைட் +devtools: + install_folder: நிறுவல் கோப்புறை + enable: டெவலப்பர் கருவிகளை இயக்கு + custom_config_file: தனிப்பயன் கட்டமைப்பு கோப்பை ஏற்றவும் + app_folders: பயன்பாட்டு கோப்புறைகள் + data_folder: தரவு கோப்புறை + load: ஏற்றவும் + settings_file: அமைப்புகள் கோப்பு +apps_configurations: + app: + options: + pinned: பின் செய்யப்பட்டது + float: மிதவை + unmanage: நிர்வகியுங்கள் + force: கட்டாயம் நிர்வகி + monitor: கண்காணிக்கவும் + options_label: கூடுதல் விருப்பங்கள் + title_create: '{{name}} உருவாக்குகிறது' + workspace: பணியிடம் + workspace_placeholder: இல்லை + category_placeholder: இல்லை + monitor_placeholder: இல்லை + name: பெயர் + category: வகை + ok_create: உருவாக்கு + title_readonly: '{{name}} பார்க்கிறது' + ok_edit: புதுப்பிக்கவும் + ok_readonly: புதியதாக திருத்தவும் + title_edit: திருத்துகிறது {{name}} + bindings: பிணைப்பு (இரண்டு விருப்பங்களும் தேவை என்பதை நினைவில் கொள்ளவும்) + identifier: + and: மற்றும் + remove: தடுப்பை நீக்கு + negation: பொருத்தத்தை மறுக்கவும் + id: அடையாளங்காட்டி + add_block: தொகுதியைச் சேர்க்கவும் + or: அல்லது + kind: மூலம் அடையாளம் காணவும் + matching_strategy: பொருந்தும் உத்தி + export: ஏற்றுமதி + confirm_delete_title: நீக்குவதை உறுதிப்படுத்தவும் + delete: அழி + bundled_title: பயன்பாட்டு கட்டமைப்பு சீலனுடன் தொகுக்கப்பட்டுள்ளது + confirm_delete: இந்த உள்ளமைவு/களை நிச்சயமாக நீக்க விரும்புகிறீர்களா? + bundled_msg: >- + இந்தத் தொகுக்கப்பட்ட உள்ளமைவுகளைத் திருத்த முடியாது மற்றும் தனிப்பயனாக்கம் + இல்லாமல் சிறந்த அனுபவத்தை உங்களுக்கு வழங்கும் வகையில் வடிவமைக்கப்பட்டுள்ளது. + உங்களுக்கான பொதுவான பயன்பாடுகளை அவை தானாகவே கட்டமைக்கும். + import: இறக்குமதி + search: தேடு + swap: இடமாற்று + new: புதியது +extras: + discord: கருத்து வேறுபாடு + exit: வெளியேறு/வெளியேறு + links: அதிகாரப்பூர்வ இணைப்புகள் + relaunch: மறுதொடக்கம் + version: பதிப்பு + github: கிட்ஹப் +shortcuts: + labels: + focus_latest: சமீபத்திய கவனம் + send_to_workspace_2: பணியிடத்திற்கு அனுப்பு 2 + increase_height: உயரத்தை அதிகரிக்கவும் + restore_sizes: அளவுகளை மீட்டமை + increase_width: அகலத்தை அதிகரிக்கவும் + switch_workspace_1: பணியிடத்திற்கு மாறவும் 1 + send_to_workspace_4: பணியிடத்திற்கு அனுப்பு 4 + move_to_workspace_5: பணியிடத்திற்கு நகர்த்து 5 + reserve_right: ரிசர்வ் ரைட் + switch_workspace_6: பணியிடத்திற்கு மாறவும் 6 + send_to_workspace_1: பணியிடத்திற்கு அனுப்பு 1 + send_to_workspace_0: பணியிடம் 0க்கு அனுப்பவும் + focus_right: ஃபோகஸ் ரைட் + switch_workspace_0: பணியிடம் 0க்கு மாறவும் + reserve_float: ரிசர்வ் ஃப்ளோட் + reserve_left: ரிசர்வ் இடது + switch_workspace_5: பணியிடத்திற்கு மாறவும் 5 + focus_top: ஃபோகஸ் டாப் + move_to_workspace_0: பணியிடம் 0க்கு நகர்த்தவும் + move_to_workspace_1: பணியிடத்திற்கு நகர்த்து 1 + move_to_workspace_6: பணியிடத்திற்கு நகர்த்து 6 + switch_workspace_2: பணியிடத்திற்கு மாறவும் 2 + reserve_stack: ரிசர்வ் ஸ்டாக் + decrease_width: அகலத்தை குறைக்கவும் + switch_workspace_8: பணியிடத்திற்கு மாறவும் 8 + send_to_workspace_8: பணியிடம் 8க்கு அனுப்பவும் + reserve_top: ரிசர்வ் டாப் + send_to_workspace_5: பணியிடத்திற்கு அனுப்பு 5 + focus_left: இடதுபுறத்தில் கவனம் செலுத்துங்கள் + move_to_workspace_4: பணியிடத்திற்கு நகர்த்து 4 + send_to_workspace_9: பணியிடம் 9க்கு அனுப்பவும் + move_to_workspace_2: பணியிடத்திற்கு நகர்த்து 2 + move_to_workspace_9: பணியிடத்திற்கு நகர்த்து 9 + send_to_workspace_3: பணியிடத்திற்கு அனுப்பு 3 + send_to_workspace_7: பணியிடம் 7க்கு அனுப்பவும் + decrease_height: உயரத்தைக் குறைக்கவும் + send_to_workspace_6: பணியிடத்திற்கு அனுப்பு 6 + switch_workspace_4: பணியிடத்திற்கு மாறவும் 4 + reserve_bottom: ரிசர்வ் பாட்டம் + move_to_workspace_8: பணியிடத்திற்கு நகர்த்து 8 + move_to_workspace_3: பணியிடத்திற்கு நகர்த்து 3 + switch_workspace_3: பணியிடத்திற்கு மாறவும் 3 + move_to_workspace_7: பணியிடத்திற்கு நகர்த்து 7 + switch_workspace_9: பணியிடத்திற்கு மாறவும் 9 + focus_bottom: கீழே கவனம் செலுத்துங்கள் + switch_workspace_7: பணியிடம் 7க்கு மாறவும் + enable: ஒருங்கிணைந்த குறுக்குவழிகளை இயக்கு (ahk) + enable_tooltip: >- + சீலன் கோர் ஏபிஐ பயன்படுத்தி உங்கள் சொந்த ஷார்ட்கட்களை செயல்படுத்தினால் + முடக்கவும் +inProgress: செயல்பாட்டில் உள்ளது... +cancel: ரத்து செய் +quit: விட்டுவிட +delete: அழி +loading: ஏற்றுகிறது... +save: சேமிக்கவும் +open: திற diff --git a/src/apps/settings/i18n/translations/te.yml b/src/apps/settings/i18n/translations/te.yml index 624d49bf..b5b17bac 100644 --- a/src/apps/settings/i18n/translations/te.yml +++ b/src/apps/settings/i18n/translations/te.yml @@ -1,195 +1,195 @@ -sides: - bottom: దిగువన - top: టాప్ - left: ఎడమ - right: కుడి -header: - labels: - info: సమాచారం - general: జనరల్ - monitors: మానిటర్లు - seelen_wm: విండో మేనేజర్ - shortcuts: సత్వరమార్గాలు - developer: డెవలపర్ - specific_apps: నిర్దిష్ట యాప్‌లు - seelen_bar: ఫ్యాన్సీ టూల్‌బార్ - seelen_weg: డాక్/టాస్క్‌బార్ -start: - title: స్వాగతం! - message_accent: శైలితో మీ ఉత్పాదకతను ఆప్టిమైజ్ చేయండి! - message: >- - సీలెన్ UIకి స్వాగతం, మీ Windows 11 అనుభవాన్ని మెరుగుపరచడానికి - ఇన్‌కార్పొరేటెడ్ టైలింగ్ విండోస్ మేనేజర్‌తో అంతిమ డెస్క్‌టాప్ - ఎన్విరాన్‌మెంట్! మా సహజమైన ఇంటర్‌ఫేస్ మరియు అధునాతన ఫీచర్‌లతో సమర్ధత మరియు - బహువిధి యొక్క కొత్త యుగాన్ని అన్వేషించండి. -general: - theme: - tags: టాగ్లు - placeholder: థీమ్‌ని ఎంచుకోండి - description: వివరణ - author: రచయిత - label: థీమ్ సమాచారం - added: థీమ్ ఇప్పటికే జోడించబడింది - enabled: ప్రారంభించబడిన థీమ్‌లు - add: థీమ్ జోడించండి - available: అందుబాటులో ఉంది - selected: ఎంచుకున్నారు - language: భాష - startup: స్టార్టప్‌లో అమలు చేయాలా? - icon_pack: - label: ఐకాన్ ప్యాక్‌లు - accent_color: యాస రంగు -toolbar: - placeholder: - author: రచయిత - description: వివరణ - select: టూల్‌బార్ నిర్మాణం - height: ఎత్తు - enable: ఫ్యాన్సీ టూల్‌బార్‌ని ప్రారంభించండి -wm: - border: - width: అంచు వెడల్పు - offset: సరిహద్దు ఆఫ్‌సెట్ - enable: విండో అంచుని ప్రారంభించండి - layout: లేఅవుట్ - author: రచయిత - description: వివరణ - space_between_containers: కంటైనర్ల మధ్య ఖాళీ - disabled_windows10: విండోస్ 10 కోసం విండో మేనేజర్ అందుబాటులో లేదు. - enable: విండో మేనేజర్‌ని ప్రారంభించండి - workspace_padding: కార్యస్థలాల పాడింగ్ - workspace_offset: వర్క్‌స్పేస్ ఆఫ్‌సెట్ (మార్జిన్‌లు) - resize_delta: డెల్టా (%) పరిమాణాన్ని మార్చండి -weg: - items: - label: వస్తువులు - size: అంశం పరిమాణం - visible_separators: కనిపించే సెపరేటర్లు - gap: వస్తువుల మధ్య ఖాళీ - zoom_size: జూమ్ చేసిన పరిమాణం (థీమ్‌ల కోసం ఉపయోగించబడుతుంది) - auto_hide: ఆటో దాచు - padding: పాడింగ్ - label: డాక్/టాస్క్‌బార్ - margin: మార్జిన్ - gap: గ్యాప్ - width: వెడల్పు - enable: డాక్/టాస్క్‌బార్‌ని ప్రారంభించండి - dock_side: డాక్ సైడ్ -devtools: - enable: డెవలపర్ సాధనాలను ప్రారంభించండి - custom_config_file: కస్టమ్ కాన్ఫిగర్ ఫైల్‌ను లోడ్ చేయండి - settings_file: సెట్టింగుల ఫైల్ - data_folder: డేటా ఫోల్డర్ - load: లోడ్ చేయండి - install_folder: ఇన్‌స్టాలేషన్ ఫోల్డర్ - app_folders: యాప్ ఫోల్డర్‌లు -apps_configurations: - app: - options: - pinned: పిన్ చేయబడింది - float: ఫ్లోట్ - unmanage: నిర్వహించవద్దు - force: బలవంతంగా నిర్వహించండి - monitor: మానిటర్ - options_label: అదనపు ఎంపికలు - workspace: కార్యస్థలం - workspace_placeholder: ఏదీ లేదు - category_placeholder: ఏదీ లేదు - monitor_placeholder: ఏదీ లేదు - category: వర్గం - name: పేరు - title_create: '{{name}}ని సృష్టిస్తోంది' - title_readonly: '{{name}} వీక్షిస్తోంది' - title_edit: '{{name}}ని సవరిస్తోంది' - ok_edit: నవీకరించు - ok_readonly: కొత్తదిగా సవరించండి - bindings: బైండింగ్ (రెండు ఎంపికలు అవసరమని గమనించండి) - ok_create: సృష్టించు - identifier: - and: మరియు - negation: సరిపోలికను తిరస్కరించండి - or: లేదా - matching_strategy: మ్యాచింగ్ స్ట్రాటజీ - remove: బ్లాక్‌ని తొలగించండి - add_block: బ్లాక్ జోడించండి - id: ఐడెంటిఫైయర్ - kind: ద్వారా గుర్తించండి - search: వెతకండి - swap: మార్పిడి - new: కొత్తది - import: దిగుమతి - export: ఎగుమతి చేయండి - confirm_delete_title: తొలగించడాన్ని నిర్ధారించండి - bundled_title: యాప్ కాన్ఫిగర్ సీలెన్‌తో బండిల్ చేయబడింది - delete: తొలగించు - confirm_delete: మీరు ఈ కాన్ఫిగరేషన్/లని ఖచ్చితంగా తొలగించాలనుకుంటున్నారా? - bundled_msg: >- - ఈ బండిల్ కాన్ఫిగరేషన్‌లు సవరించదగినవి కావు మరియు అనుకూలీకరణ లేకుండా మీకు - ఉత్తమ అనుభవాన్ని అందించడానికి రూపొందించబడ్డాయి. వారు మీ కోసం అత్యంత సాధారణ - అప్లికేషన్‌లను స్వయంచాలకంగా కాన్ఫిగర్ చేస్తారు. -extras: - version: 'సంస్కరణ: Telugu' - github: GitHub - links: అధికారిక లింకులు - discord: అసమ్మతి - relaunch: పునఃప్రారంభించండి - exit: నిష్క్రమించు/నిష్క్రమించు -shortcuts: - labels: - focus_right: ఫోకస్ రైట్ - reserve_right: రిజర్వ్ హక్కు - reserve_left: రిజర్వ్ ఎడమ - increase_height: ఎత్తు పెంచండి - switch_workspace_0: కార్యస్థలం 0కి మారండి - reserve_bottom: రిజర్వ్ బాటమ్ - send_to_workspace_0: కార్యస్థలం 0కి పంపండి - switch_workspace_1: కార్యస్థలానికి మారండి 1 - move_to_workspace_4: కార్యస్థలానికి తరలించు 4 - switch_workspace_6: కార్యస్థలానికి మారండి 6 - reserve_top: రిజర్వ్ టాప్ - focus_latest: తాజాగా ఫోకస్ చేయండి - restore_sizes: పరిమాణాలను పునరుద్ధరించండి - reserve_stack: రిజర్వ్ స్టాక్ - focus_left: ఎడమవైపు దృష్టి పెట్టండి - move_to_workspace_5: కార్యస్థలానికి తరలించు 5 - decrease_height: ఎత్తు తగ్గించండి - send_to_workspace_1: కార్యస్థలానికి పంపండి 1 - send_to_workspace_3: కార్యస్థలానికి పంపండి 3 - send_to_workspace_4: కార్యస్థలానికి పంపండి 4 - send_to_workspace_2: కార్యస్థలానికి పంపండి 2 - send_to_workspace_9: కార్యస్థలానికి పంపండి 9 - move_to_workspace_2: కార్యస్థలానికి తరలించు 2 - send_to_workspace_5: కార్యస్థలానికి పంపండి 5 - move_to_workspace_7: కార్యస్థలానికి తరలించు 7 - increase_width: వెడల్పు పెంచండి - switch_workspace_5: కార్యస్థలానికి మారండి 5 - decrease_width: వెడల్పును తగ్గించండి - reserve_float: రిజర్వ్ ఫ్లోట్ - move_to_workspace_6: కార్యస్థలానికి తరలించు 6 - send_to_workspace_7: కార్యస్థలానికి పంపండి 7 - move_to_workspace_1: కార్యస్థలానికి తరలించు 1 - switch_workspace_8: కార్యస్థలానికి మారండి 8 - switch_workspace_3: కార్యస్థలానికి మారండి 3 - focus_top: ఫోకస్ టాప్ - move_to_workspace_0: కార్యస్థలం 0కి తరలించండి - move_to_workspace_9: కార్యస్థలానికి తరలించు 9 - switch_workspace_2: కార్యస్థలానికి మారండి 2 - switch_workspace_9: కార్యస్థలానికి మారండి 9 - send_to_workspace_6: కార్యస్థలానికి పంపండి 6 - move_to_workspace_8: కార్యస్థలానికి తరలించు 8 - move_to_workspace_3: కార్యస్థలానికి తరలించు 3 - switch_workspace_4: కార్యస్థలానికి మారండి 4 - send_to_workspace_8: కార్యస్థలానికి పంపండి 8 - switch_workspace_7: కార్యస్థలానికి మారండి 7 - focus_bottom: ఫోకస్ బాటమ్ - enable: ఇంటిగ్రేటెడ్ షార్ట్‌కట్‌లను ప్రారంభించండి (ahk) - enable_tooltip: >- - మీరు సీలెన్ కోర్ Apiని ఉపయోగించి మీ స్వంత సత్వరమార్గాలను అమలు చేస్తే - నిలిపివేయండి -loading: లోడ్... -delete: తొలగించు -open: తెరవండి -save: సేవ్ చేయండి -cancel: రద్దు చేయండి -quit: నిష్క్రమించు -inProgress: పురోగతిలో ఉంది... +sides: + bottom: దిగువన + top: టాప్ + left: ఎడమ + right: కుడి +header: + labels: + info: సమాచారం + general: జనరల్ + monitors: మానిటర్లు + seelen_wm: విండో మేనేజర్ + shortcuts: సత్వరమార్గాలు + developer: డెవలపర్ + specific_apps: నిర్దిష్ట యాప్‌లు + seelen_bar: ఫ్యాన్సీ టూల్‌బార్ + seelen_weg: డాక్/టాస్క్‌బార్ +start: + title: స్వాగతం! + message_accent: శైలితో మీ ఉత్పాదకతను ఆప్టిమైజ్ చేయండి! + message: >- + సీలెన్ UIకి స్వాగతం, మీ Windows 11 అనుభవాన్ని మెరుగుపరచడానికి + ఇన్‌కార్పొరేటెడ్ టైలింగ్ విండోస్ మేనేజర్‌తో అంతిమ డెస్క్‌టాప్ + ఎన్విరాన్‌మెంట్! మా సహజమైన ఇంటర్‌ఫేస్ మరియు అధునాతన ఫీచర్‌లతో సమర్ధత మరియు + బహువిధి యొక్క కొత్త యుగాన్ని అన్వేషించండి. +general: + theme: + tags: టాగ్లు + placeholder: థీమ్‌ని ఎంచుకోండి + description: వివరణ + author: రచయిత + label: థీమ్ సమాచారం + added: థీమ్ ఇప్పటికే జోడించబడింది + enabled: ప్రారంభించబడిన థీమ్‌లు + add: థీమ్ జోడించండి + available: అందుబాటులో ఉంది + selected: ఎంచుకున్నారు + language: భాష + startup: స్టార్టప్‌లో అమలు చేయాలా? + icon_pack: + label: ఐకాన్ ప్యాక్‌లు + accent_color: యాస రంగు +toolbar: + placeholder: + author: రచయిత + description: వివరణ + select: టూల్‌బార్ నిర్మాణం + height: ఎత్తు + enable: ఫ్యాన్సీ టూల్‌బార్‌ని ప్రారంభించండి +wm: + border: + width: అంచు వెడల్పు + offset: సరిహద్దు ఆఫ్‌సెట్ + enable: విండో అంచుని ప్రారంభించండి + layout: లేఅవుట్ + author: రచయిత + description: వివరణ + space_between_containers: కంటైనర్ల మధ్య ఖాళీ + disabled_windows10: విండోస్ 10 కోసం విండో మేనేజర్ అందుబాటులో లేదు. + enable: విండో మేనేజర్‌ని ప్రారంభించండి + workspace_padding: కార్యస్థలాల పాడింగ్ + workspace_offset: వర్క్‌స్పేస్ ఆఫ్‌సెట్ (మార్జిన్‌లు) + resize_delta: డెల్టా (%) పరిమాణాన్ని మార్చండి +weg: + items: + label: వస్తువులు + size: అంశం పరిమాణం + visible_separators: కనిపించే సెపరేటర్లు + gap: వస్తువుల మధ్య ఖాళీ + zoom_size: జూమ్ చేసిన పరిమాణం (థీమ్‌ల కోసం ఉపయోగించబడుతుంది) + auto_hide: ఆటో దాచు + padding: పాడింగ్ + label: డాక్/టాస్క్‌బార్ + margin: మార్జిన్ + gap: గ్యాప్ + width: వెడల్పు + enable: డాక్/టాస్క్‌బార్‌ని ప్రారంభించండి + dock_side: డాక్ సైడ్ +devtools: + enable: డెవలపర్ సాధనాలను ప్రారంభించండి + custom_config_file: కస్టమ్ కాన్ఫిగర్ ఫైల్‌ను లోడ్ చేయండి + settings_file: సెట్టింగుల ఫైల్ + data_folder: డేటా ఫోల్డర్ + load: లోడ్ చేయండి + install_folder: ఇన్‌స్టాలేషన్ ఫోల్డర్ + app_folders: యాప్ ఫోల్డర్‌లు +apps_configurations: + app: + options: + pinned: పిన్ చేయబడింది + float: ఫ్లోట్ + unmanage: నిర్వహించవద్దు + force: బలవంతంగా నిర్వహించండి + monitor: మానిటర్ + options_label: అదనపు ఎంపికలు + workspace: కార్యస్థలం + workspace_placeholder: ఏదీ లేదు + category_placeholder: ఏదీ లేదు + monitor_placeholder: ఏదీ లేదు + category: వర్గం + name: పేరు + title_create: '{{name}}ని సృష్టిస్తోంది' + title_readonly: '{{name}} వీక్షిస్తోంది' + title_edit: '{{name}}ని సవరిస్తోంది' + ok_edit: నవీకరించు + ok_readonly: కొత్తదిగా సవరించండి + bindings: బైండింగ్ (రెండు ఎంపికలు అవసరమని గమనించండి) + ok_create: సృష్టించు + identifier: + and: మరియు + negation: సరిపోలికను తిరస్కరించండి + or: లేదా + matching_strategy: మ్యాచింగ్ స్ట్రాటజీ + remove: బ్లాక్‌ని తొలగించండి + add_block: బ్లాక్ జోడించండి + id: ఐడెంటిఫైయర్ + kind: ద్వారా గుర్తించండి + search: వెతకండి + swap: మార్పిడి + new: కొత్తది + import: దిగుమతి + export: ఎగుమతి చేయండి + confirm_delete_title: తొలగించడాన్ని నిర్ధారించండి + bundled_title: యాప్ కాన్ఫిగర్ సీలెన్‌తో బండిల్ చేయబడింది + delete: తొలగించు + confirm_delete: మీరు ఈ కాన్ఫిగరేషన్/లని ఖచ్చితంగా తొలగించాలనుకుంటున్నారా? + bundled_msg: >- + ఈ బండిల్ కాన్ఫిగరేషన్‌లు సవరించదగినవి కావు మరియు అనుకూలీకరణ లేకుండా మీకు + ఉత్తమ అనుభవాన్ని అందించడానికి రూపొందించబడ్డాయి. వారు మీ కోసం అత్యంత సాధారణ + అప్లికేషన్‌లను స్వయంచాలకంగా కాన్ఫిగర్ చేస్తారు. +extras: + version: 'సంస్కరణ: Telugu' + github: GitHub + links: అధికారిక లింకులు + discord: అసమ్మతి + relaunch: పునఃప్రారంభించండి + exit: నిష్క్రమించు/నిష్క్రమించు +shortcuts: + labels: + focus_right: ఫోకస్ రైట్ + reserve_right: రిజర్వ్ హక్కు + reserve_left: రిజర్వ్ ఎడమ + increase_height: ఎత్తు పెంచండి + switch_workspace_0: కార్యస్థలం 0కి మారండి + reserve_bottom: రిజర్వ్ బాటమ్ + send_to_workspace_0: కార్యస్థలం 0కి పంపండి + switch_workspace_1: కార్యస్థలానికి మారండి 1 + move_to_workspace_4: కార్యస్థలానికి తరలించు 4 + switch_workspace_6: కార్యస్థలానికి మారండి 6 + reserve_top: రిజర్వ్ టాప్ + focus_latest: తాజాగా ఫోకస్ చేయండి + restore_sizes: పరిమాణాలను పునరుద్ధరించండి + reserve_stack: రిజర్వ్ స్టాక్ + focus_left: ఎడమవైపు దృష్టి పెట్టండి + move_to_workspace_5: కార్యస్థలానికి తరలించు 5 + decrease_height: ఎత్తు తగ్గించండి + send_to_workspace_1: కార్యస్థలానికి పంపండి 1 + send_to_workspace_3: కార్యస్థలానికి పంపండి 3 + send_to_workspace_4: కార్యస్థలానికి పంపండి 4 + send_to_workspace_2: కార్యస్థలానికి పంపండి 2 + send_to_workspace_9: కార్యస్థలానికి పంపండి 9 + move_to_workspace_2: కార్యస్థలానికి తరలించు 2 + send_to_workspace_5: కార్యస్థలానికి పంపండి 5 + move_to_workspace_7: కార్యస్థలానికి తరలించు 7 + increase_width: వెడల్పు పెంచండి + switch_workspace_5: కార్యస్థలానికి మారండి 5 + decrease_width: వెడల్పును తగ్గించండి + reserve_float: రిజర్వ్ ఫ్లోట్ + move_to_workspace_6: కార్యస్థలానికి తరలించు 6 + send_to_workspace_7: కార్యస్థలానికి పంపండి 7 + move_to_workspace_1: కార్యస్థలానికి తరలించు 1 + switch_workspace_8: కార్యస్థలానికి మారండి 8 + switch_workspace_3: కార్యస్థలానికి మారండి 3 + focus_top: ఫోకస్ టాప్ + move_to_workspace_0: కార్యస్థలం 0కి తరలించండి + move_to_workspace_9: కార్యస్థలానికి తరలించు 9 + switch_workspace_2: కార్యస్థలానికి మారండి 2 + switch_workspace_9: కార్యస్థలానికి మారండి 9 + send_to_workspace_6: కార్యస్థలానికి పంపండి 6 + move_to_workspace_8: కార్యస్థలానికి తరలించు 8 + move_to_workspace_3: కార్యస్థలానికి తరలించు 3 + switch_workspace_4: కార్యస్థలానికి మారండి 4 + send_to_workspace_8: కార్యస్థలానికి పంపండి 8 + switch_workspace_7: కార్యస్థలానికి మారండి 7 + focus_bottom: ఫోకస్ బాటమ్ + enable: ఇంటిగ్రేటెడ్ షార్ట్‌కట్‌లను ప్రారంభించండి (ahk) + enable_tooltip: >- + మీరు సీలెన్ కోర్ Apiని ఉపయోగించి మీ స్వంత సత్వరమార్గాలను అమలు చేస్తే + నిలిపివేయండి +loading: లోడ్... +delete: తొలగించు +open: తెరవండి +save: సేవ్ చేయండి +cancel: రద్దు చేయండి +quit: నిష్క్రమించు +inProgress: పురోగతిలో ఉంది... diff --git a/src/apps/settings/i18n/translations/tg.yml b/src/apps/settings/i18n/translations/tg.yml index 6696a3e5..671354ed 100644 --- a/src/apps/settings/i18n/translations/tg.yml +++ b/src/apps/settings/i18n/translations/tg.yml @@ -1,192 +1,192 @@ -sides: - left: Бесоҳибмонда - right: Рост - bottom: Тагпо - top: Боло -header: - labels: - shortcuts: Миёнбурҳо - seelen_wm: Менеҷери тиреза - general: Генерал - seelen_weg: Dock / супоришҳо - specific_apps: Барномаҳои мушаххас - monitors: Мониторҳо - developer: Таҳиякунанда - seelen_bar: Панели футбол - info: Ахбор -start: - message_accent: Ҳосилнокии худро бо услуб оптимед кунед! - message: >- - Хуш омадед ба Селен ui, муҳити ниҳооии мизи корӣ бо намоиши менеҷери TIS - Windows Manage 11 таҷрибаи Windows 11 Windows 11! Давраи нави самаранокиро - кашф кунед ва бисёрҷанбаҳо бо интерфейси амиқии мо ва хусусиятҳои пешрафта. - title: Хуш омадед! -general: - theme: - enabled: Дар мавзӯъҳо фаъол карда шудааст - label: Маълумот дар мавзӯъ - description: Тасвирӣ - author: Муаллиф - placeholder: Интихоб кунед Мавзӯъ - added: Мавзӯъ аллакай илова карда шуд - add: Иловаи мавзӯъ - tags: Тегҳо - selected: Интихоб карда шуд - available: Дастрас - startup: Оғози кор? - language: Забон - icon_pack: - label: ICon бастаҳои - accent_color: Ранги ҳисоб -toolbar: - placeholder: - select: Сохтори панели асбобҳо - description: Тасвирӣ - author: Муаллиф - height: Баландӣ - enable: Дастрас кардани панели футболи -wm: - border: - width: Паҳнои сарҳад - offset: Ҳафтаи сарҳад - enable: Сарҳади тирезаро фаъол созед - description: Тасвирӣ - disabled_windows10: Менеҷери тиреза барои Windows 10 дастрас нест. - layout: Тарҳ - space_between_containers: Фосила байни контейнер - workspace_offset: Ҷойгиршавӣ - author: Муаллиф - enable: Фаъолсозии мудири тиреза - resize_delta: Татбиқи Delta (%) - workspace_padding: Worlpaces Padding -weg: - items: - zoom_size: Андозаи масоҳати (барои мавзӯъҳо истифода мешавад) - visible_separators: Бандиаткунандагони намоён - label: Ашё - size: Андозаи ашё - gap: Фосила байни ашё - label: Dock / супоришҳо - enable: Dock / Travelar - padding: Тахтача - width: Васеъ - dock_side: Тарафи док - auto_hide: Худкор Пинҳон кардани - gap: Фосила - margin: Маржа -devtools: - custom_config_file: Файли танзимоти танзими фармоишӣ - load: Сарборӣ - settings_file: Файлҳои танзимот - install_folder: Феҳристи насб - enable: Воситаҳои таҳиягарро фаъол кунед - data_folder: Папкаи додаҳо - app_folders: Папкаҳои барнома -apps_configurations: - app: - options: - unmanage: Тасдиқнашаванда - float: Шино кардан - pinned: Пинҳон - force: Идоракунии қувва - monitor_placeholder: Ҳеь - monitor: Назорат - category: Категория - title_edit: Таҳрири {{НОМ}} - workspace_placeholder: Ҳеь - ok_create: Сохтан - title_readonly: Дидани {{НОМ}} - options_label: Имконоти иловагӣ - workspace: Корӣ - bindings: Бодед - name: Ном - category_placeholder: Ҳеь - ok_edit: Навсозӣ - ok_readonly: Ҳамчун нав - title_create: Эҷоди {{НОМИ}} - identifier: - or: Ё - kind: Муайян мекунад - remove: Нест кардани блок - id: Муайянкунанда - and: Ва - add_block: Блокро илова кунед - negation: Мувофиқати манфӣ - matching_strategy: Стратегияи мувофиқ - confirm_delete_title: Тасдиқро тасдиқ кунед - confirm_delete: Шумо мутмаин ҳастед, ки мехоҳед ин конфигуратсия / S-ро нест кунед? - swap: Своп - export: Содирот - bundled_title: App Confile бо seelen - import: Воридот - new: Нав - delete: Нест - bundled_msg: >- - Ин конфигуратсияи маҷмӯӣ таҳрир карда намешавад ва барои таъмини таҷрибаи - беҳтарин бидуни фармоишӣ пешбинӣ шудаанд. Онҳо ба таври худкор барномаҳои - маъмултарини шуморо барои шумо танзим мекунанд. - search: Кофтуков -extras: - links: Истеҳсоли расмӣ - version: Версия - relaunch: Радкунӣ - github: Github - discord: Ихтисор - exit: Курат / баромадан -shortcuts: - labels: - increase_height: Баланд бардоштани баландӣ - switch_workspace_9: Гузариш ба кории 9 - reserve_stack: Стекер захира - move_to_workspace_0: Ба фазои корпартоӣ ҳаракат кунед - switch_workspace_8: Гузариш ба корҳо 8 - switch_workspace_6: Гузариш ба корҳо 6 - move_to_workspace_6: Ба корпартои 6 ҳаракат кунед - focus_right: Фокус ба - send_to_workspace_7: Ба корҳо фиристед 7 - send_to_workspace_5: Ба кории 5 фиристед - move_to_workspace_9: Ба фазои 9 ҳаракат кунед - switch_workspace_0: Гузариш ба Prowspace 0 - increase_width: Паҳнои васеъ - decrease_height: Баландиро кам мекунад - send_to_workspace_3: Ба кории 3 фиристед 3 - send_to_workspace_9: Ба кории 9 фиристед - switch_workspace_2: Гузариш ба корҳо 2 - send_to_workspace_2: Ба кории 2 фиристед 2 - move_to_workspace_7: Ба корҳо ҳаракат кунед 7 - focus_left: Тамаркуз ба чап - focus_latest: Тамаркуз охирин - switch_workspace_4: Гузариш ба корҳо 4 - reserve_left: Захира - send_to_workspace_8: Ба корҳо фиристед 8 - send_to_workspace_1: Ба кории 1 фиристед 1 - move_to_workspace_8: Ба фазои корӣ ҳаракат кунед - reserve_bottom: Поёни захиравӣ - send_to_workspace_6: Ба корҳо фиристед 6 - move_to_workspace_5: Ба кории 5 ҳаракат кунед - switch_workspace_3: Гузариш ба кории 3 - reserve_float: Шино мекунанд - send_to_workspace_4: Ба кории 4 фиристед - focus_bottom: Фаъолахш - switch_workspace_7: Гузариш ба кории 7 - move_to_workspace_1: Ба корпартои 1 ҳаракат кунед - reserve_top: Болои боло - reserve_right: Зарф аз тарафи - restore_sizes: Барқарор кардан - move_to_workspace_3: Ба кории 3 ҳаракат кунед - switch_workspace_1: Гузариш ба Prowspace 1 - switch_workspace_5: Гузариш ба корҳо 5 - send_to_workspace_0: Ба кории 0 фиристед - focus_top: Фокус ба боло - move_to_workspace_4: Ба фазои 4 ҳаракат кунед - move_to_workspace_2: Ба фазои кории 2 гузаред - decrease_width: Пойафзол коҳиш диҳед - enable: Миёнабурҳои ҳамгирошударо фаъол созед (AHK) - enable_tooltip: Агар шумо миёнабурҳои худро бо истифода аз Seelen Cear Secten истифода баред -inProgress: Дар ҷараён... -open: Кушодан -save: Пул захира кардан -quit: Баромадан -loading: Боркунӣ ... -cancel: Манъ кардан -delete: Нест +sides: + left: Бесоҳибмонда + right: Рост + bottom: Тагпо + top: Боло +header: + labels: + shortcuts: Миёнбурҳо + seelen_wm: Менеҷери тиреза + general: Генерал + seelen_weg: Dock / супоришҳо + specific_apps: Барномаҳои мушаххас + monitors: Мониторҳо + developer: Таҳиякунанда + seelen_bar: Панели футбол + info: Ахбор +start: + message_accent: Ҳосилнокии худро бо услуб оптимед кунед! + message: >- + Хуш омадед ба Селен ui, муҳити ниҳооии мизи корӣ бо намоиши менеҷери TIS + Windows Manage 11 таҷрибаи Windows 11 Windows 11! Давраи нави самаранокиро + кашф кунед ва бисёрҷанбаҳо бо интерфейси амиқии мо ва хусусиятҳои пешрафта. + title: Хуш омадед! +general: + theme: + enabled: Дар мавзӯъҳо фаъол карда шудааст + label: Маълумот дар мавзӯъ + description: Тасвирӣ + author: Муаллиф + placeholder: Интихоб кунед Мавзӯъ + added: Мавзӯъ аллакай илова карда шуд + add: Иловаи мавзӯъ + tags: Тегҳо + selected: Интихоб карда шуд + available: Дастрас + startup: Оғози кор? + language: Забон + icon_pack: + label: ICon бастаҳои + accent_color: Ранги ҳисоб +toolbar: + placeholder: + select: Сохтори панели асбобҳо + description: Тасвирӣ + author: Муаллиф + height: Баландӣ + enable: Дастрас кардани панели футболи +wm: + border: + width: Паҳнои сарҳад + offset: Ҳафтаи сарҳад + enable: Сарҳади тирезаро фаъол созед + description: Тасвирӣ + disabled_windows10: Менеҷери тиреза барои Windows 10 дастрас нест. + layout: Тарҳ + space_between_containers: Фосила байни контейнер + workspace_offset: Ҷойгиршавӣ + author: Муаллиф + enable: Фаъолсозии мудири тиреза + resize_delta: Татбиқи Delta (%) + workspace_padding: Worlpaces Padding +weg: + items: + zoom_size: Андозаи масоҳати (барои мавзӯъҳо истифода мешавад) + visible_separators: Бандиаткунандагони намоён + label: Ашё + size: Андозаи ашё + gap: Фосила байни ашё + label: Dock / супоришҳо + enable: Dock / Travelar + padding: Тахтача + width: Васеъ + dock_side: Тарафи док + auto_hide: Худкор Пинҳон кардани + gap: Фосила + margin: Маржа +devtools: + custom_config_file: Файли танзимоти танзими фармоишӣ + load: Сарборӣ + settings_file: Файлҳои танзимот + install_folder: Феҳристи насб + enable: Воситаҳои таҳиягарро фаъол кунед + data_folder: Папкаи додаҳо + app_folders: Папкаҳои барнома +apps_configurations: + app: + options: + unmanage: Тасдиқнашаванда + float: Шино кардан + pinned: Пинҳон + force: Идоракунии қувва + monitor_placeholder: Ҳеь + monitor: Назорат + category: Категория + title_edit: Таҳрири {{НОМ}} + workspace_placeholder: Ҳеь + ok_create: Сохтан + title_readonly: Дидани {{НОМ}} + options_label: Имконоти иловагӣ + workspace: Корӣ + bindings: Бодед + name: Ном + category_placeholder: Ҳеь + ok_edit: Навсозӣ + ok_readonly: Ҳамчун нав + title_create: Эҷоди {{НОМИ}} + identifier: + or: Ё + kind: Муайян мекунад + remove: Нест кардани блок + id: Муайянкунанда + and: Ва + add_block: Блокро илова кунед + negation: Мувофиқати манфӣ + matching_strategy: Стратегияи мувофиқ + confirm_delete_title: Тасдиқро тасдиқ кунед + confirm_delete: Шумо мутмаин ҳастед, ки мехоҳед ин конфигуратсия / S-ро нест кунед? + swap: Своп + export: Содирот + bundled_title: App Confile бо seelen + import: Воридот + new: Нав + delete: Нест + bundled_msg: >- + Ин конфигуратсияи маҷмӯӣ таҳрир карда намешавад ва барои таъмини таҷрибаи + беҳтарин бидуни фармоишӣ пешбинӣ шудаанд. Онҳо ба таври худкор барномаҳои + маъмултарини шуморо барои шумо танзим мекунанд. + search: Кофтуков +extras: + links: Истеҳсоли расмӣ + version: Версия + relaunch: Радкунӣ + github: Github + discord: Ихтисор + exit: Курат / баромадан +shortcuts: + labels: + increase_height: Баланд бардоштани баландӣ + switch_workspace_9: Гузариш ба кории 9 + reserve_stack: Стекер захира + move_to_workspace_0: Ба фазои корпартоӣ ҳаракат кунед + switch_workspace_8: Гузариш ба корҳо 8 + switch_workspace_6: Гузариш ба корҳо 6 + move_to_workspace_6: Ба корпартои 6 ҳаракат кунед + focus_right: Фокус ба + send_to_workspace_7: Ба корҳо фиристед 7 + send_to_workspace_5: Ба кории 5 фиристед + move_to_workspace_9: Ба фазои 9 ҳаракат кунед + switch_workspace_0: Гузариш ба Prowspace 0 + increase_width: Паҳнои васеъ + decrease_height: Баландиро кам мекунад + send_to_workspace_3: Ба кории 3 фиристед 3 + send_to_workspace_9: Ба кории 9 фиристед + switch_workspace_2: Гузариш ба корҳо 2 + send_to_workspace_2: Ба кории 2 фиристед 2 + move_to_workspace_7: Ба корҳо ҳаракат кунед 7 + focus_left: Тамаркуз ба чап + focus_latest: Тамаркуз охирин + switch_workspace_4: Гузариш ба корҳо 4 + reserve_left: Захира + send_to_workspace_8: Ба корҳо фиристед 8 + send_to_workspace_1: Ба кории 1 фиристед 1 + move_to_workspace_8: Ба фазои корӣ ҳаракат кунед + reserve_bottom: Поёни захиравӣ + send_to_workspace_6: Ба корҳо фиристед 6 + move_to_workspace_5: Ба кории 5 ҳаракат кунед + switch_workspace_3: Гузариш ба кории 3 + reserve_float: Шино мекунанд + send_to_workspace_4: Ба кории 4 фиристед + focus_bottom: Фаъолахш + switch_workspace_7: Гузариш ба кории 7 + move_to_workspace_1: Ба корпартои 1 ҳаракат кунед + reserve_top: Болои боло + reserve_right: Зарф аз тарафи + restore_sizes: Барқарор кардан + move_to_workspace_3: Ба кории 3 ҳаракат кунед + switch_workspace_1: Гузариш ба Prowspace 1 + switch_workspace_5: Гузариш ба корҳо 5 + send_to_workspace_0: Ба кории 0 фиристед + focus_top: Фокус ба боло + move_to_workspace_4: Ба фазои 4 ҳаракат кунед + move_to_workspace_2: Ба фазои кории 2 гузаред + decrease_width: Пойафзол коҳиш диҳед + enable: Миёнабурҳои ҳамгирошударо фаъол созед (AHK) + enable_tooltip: Агар шумо миёнабурҳои худро бо истифода аз Seelen Cear Secten истифода баред +inProgress: Дар ҷараён... +open: Кушодан +save: Пул захира кардан +quit: Баромадан +loading: Боркунӣ ... +cancel: Манъ кардан +delete: Нест diff --git a/src/apps/settings/i18n/translations/th.yml b/src/apps/settings/i18n/translations/th.yml index 053d48ad..690b16b3 100644 --- a/src/apps/settings/i18n/translations/th.yml +++ b/src/apps/settings/i18n/translations/th.yml @@ -1,191 +1,191 @@ -sides: - bottom: ด้านล่าง - right: ขวา - left: ซ้าย - top: สูงสุด -header: - labels: - info: ข้อมูล - general: ทั่วไป - developer: ผู้พัฒนา - seelen_bar: แถบเครื่องมือแฟนซี - seelen_weg: แท่นวาง/บาร์ - specific_apps: แอพเฉพาะ - seelen_wm: ผู้จัดการหน้าต่าง - monitors: จอภาพ - shortcuts: ทางลัด -start: - title: ยินดีต้อนรับ! - message_accent: เพิ่มประสิทธิภาพการทำงานของคุณอย่างมีสไตล์! - message: >- - ยินดีต้อนรับสู่ Seelen UI สภาพแวดล้อมเดสก์ท็อปที่ดีที่สุดพร้อมตัวจัดการ - Windows Tiling ที่จัดตั้งขึ้นเพื่อปรับปรุงประสบการณ์ Windows 11 ของคุณ! - สำรวจยุคใหม่ของประสิทธิภาพและการทำงานหลายอย่างด้วยอินเทอร์เฟซที่ใช้งานง่ายและคุณสมบัติขั้นสูงของเรา -general: - theme: - author: ผู้เขียน - add: เพิ่มธีม - description: คำอธิบาย - placeholder: เลือกธีม - tags: แท็ก - added: ธีมเพิ่มแล้ว - label: ข้อมูลธีม - enabled: เปิดใช้งานธีม - available: มีอยู่ - selected: ที่เลือกสรรแล้ว - language: ภาษา - startup: วิ่งเมื่อเริ่มต้น? - icon_pack: - label: ไอคอนแพ็ค - accent_color: สีเน้น -toolbar: - placeholder: - author: ผู้เขียน - description: คำอธิบาย - select: โครงสร้างแถบเครื่องมือ - height: ความสูง - enable: เปิดใช้งานแถบเครื่องมือแฟนซี -wm: - border: - width: ความกว้างชายแดน - enable: เปิดใช้งานเส้นขอบของหน้าต่าง - offset: ชดเชยพรมแดน - author: ผู้เขียน - description: คำอธิบาย - workspace_offset: พื้นที่ทำงานออฟเซ็ต (ระยะขอบ) - space_between_containers: ช่องว่างระหว่างภาชนะบรรจุ - layout: เค้าโครง - resize_delta: ปรับขนาดเดลต้า (%) - enable: เปิดใช้งาน Manager Window - workspace_padding: ช่องว่างพื้นที่ทำงาน - disabled_windows10: ตัวจัดการหน้าต่างไม่สามารถใช้ได้สำหรับ Windows 10 -weg: - items: - size: ขนาดรายการ - zoom_size: ขนาดซูม (ใช้สำหรับธีม) - visible_separators: ตัวแยกที่มองเห็นได้ - label: รายการ - gap: ช่องว่างระหว่างรายการ - padding: การขยายความ - width: ความกว้าง - auto_hide: ซ่อนอัตโนมัติ - gap: ช่องว่าง - margin: ระยะขอบ - label: แท่นวาง/บาร์ - enable: เปิดใช้งาน Dock/Task -Babar - dock_side: ด้านท่าเรือ -devtools: - settings_file: ไฟล์การตั้งค่า - install_folder: โฟลเดอร์การติดตั้ง - enable: เปิดใช้งานเครื่องมือนักพัฒนาซอฟต์แวร์ - custom_config_file: โหลดไฟล์กำหนดค่าที่กำหนดเอง - app_folders: โฟลเดอร์แอพ - load: โหลด - data_folder: โฟลเดอร์ข้อมูล -apps_configurations: - app: - options: - float: ลอย - force: บังคับให้จัดการ - pinned: ที่ถูกตรึง - unmanage: ไม่มีการจัดการ - title_readonly: การดู {{ชื่อ}} - category: หมวดหมู่ - monitor_placeholder: ไม่มี - monitor: เฝ้าสังเกต - category_placeholder: ไม่มี - ok_create: สร้าง - ok_edit: อัปเดต - ok_readonly: แก้ไขเป็นใหม่ - workspace: พื้นที่ทำงาน - title_edit: แก้ไข {{ชื่อ}} - workspace_placeholder: ไม่มี - name: ชื่อ - bindings: การเชื่อม (หมายเหตุทั้งสองตัวเลือกเป็นสิ่งจำเป็น) - title_create: การสร้าง {{ชื่อ}} - options_label: ตัวเลือกพิเศษ - identifier: - and: และ - or: หรือ - id: ตัวระบุ - negation: คัดค้านการจับคู่ - matching_strategy: กลยุทธ์การจับคู่ - remove: ลบบล็อก - kind: ระบุโดย - add_block: เพิ่มบล็อก - delete: ลบ - new: ใหม่ - swap: แลกเปลี่ยน - export: ส่งออก - search: ค้นหา - bundled_title: แอพกำหนดค่ามาพร้อมกับ Seelen - import: นำเข้า - bundled_msg: >- - การกำหนดค่าแบบรวมเหล่านี้ไม่สามารถแก้ไขได้และได้รับการออกแบบมาเพื่อให้คุณได้รับประสบการณ์ที่ดีที่สุดโดยไม่ต้องปรับแต่ง - พวกเขากำหนดค่าแอปพลิเคชันที่พบบ่อยที่สุดสำหรับคุณโดยอัตโนมัติ - confirm_delete_title: ยืนยันการลบ - confirm_delete: แน่ใจหรือว่าต้องการลบการกำหนดค่านี้/s? -extras: - github: คนอื่น ๆ - discord: ความไม่ลงรอยกัน - exit: ออก/ออก - relaunch: เปิดใหม่ - links: ลิงค์อย่างเป็นทางการ - version: รุ่น -shortcuts: - labels: - focus_left: โฟกัสซ้าย - reserve_right: สำรองสิทธิ - switch_workspace_7: เปลี่ยนไปใช้พื้นที่ทำงาน 7 - switch_workspace_3: เปลี่ยนเป็น Workspace 3 - send_to_workspace_6: ส่งไปยังเวิร์กสเปซ 6 - send_to_workspace_8: ส่งไปยังเวิร์กสเปซ 8 - decrease_width: ลดความกว้าง - increase_height: เพิ่มความสูง - focus_bottom: โฟกัสด้านล่าง - send_to_workspace_2: ส่งไปยังเวิร์กสเปซ 2 - reserve_top: สำรองด้านบน - decrease_height: ลดความสูง - switch_workspace_0: สลับไปที่เวิร์กสเปซ 0 - reserve_bottom: สำรองด้านล่าง - move_to_workspace_8: ย้ายไปที่เวิร์กสเปซ 8 - reserve_float: สำรองลอย - send_to_workspace_3: ส่งไปยังเวิร์กสเปซ 3 - move_to_workspace_2: ย้ายไปที่เวิร์กสเปซ 2 - move_to_workspace_4: ย้ายไปที่เวิร์กสเปซ 4 - switch_workspace_6: เปลี่ยนไปใช้พื้นที่ทำงาน 6 - switch_workspace_1: เปลี่ยนไปใช้พื้นที่ทำงาน 1 - move_to_workspace_5: ย้ายไปที่เวิร์กสเปซ 5 - move_to_workspace_0: ย้ายไปที่เวิร์กสเปซ 0 - switch_workspace_9: เปลี่ยนไปใช้พื้นที่ทำงาน 9 - move_to_workspace_1: ย้ายไปที่เวิร์กสเปซ 1 - switch_workspace_5: เปลี่ยนไปใช้พื้นที่ทำงาน 5 - move_to_workspace_9: ย้ายไปที่เวิร์กสเปซ 9 - move_to_workspace_6: ย้ายไปที่เวิร์กสเปซ 6 - send_to_workspace_5: ส่งไปยังเวิร์กสเปซ 5 - restore_sizes: คืนค่าขนาด - send_to_workspace_0: ส่งไปยังเวิร์กสเปซ 0 - switch_workspace_8: เปลี่ยนไปใช้พื้นที่ทำงาน 8 - send_to_workspace_1: ส่งไปยังเวิร์กสเปซ 1 - reserve_stack: กองสำรอง - switch_workspace_4: เปลี่ยนไปใช้พื้นที่ทำงาน 4 - increase_width: เพิ่มความกว้าง - reserve_left: สำรองซ้าย - focus_top: โฟกัสด้านบน - move_to_workspace_3: ย้ายไปที่เวิร์กสเปซ 3 - focus_right: โฟกัสขวา - switch_workspace_2: เปลี่ยนเป็น Workspace 2 - send_to_workspace_9: ส่งไปยังเวิร์กสเปซ 9 - focus_latest: โฟกัสล่าสุด - send_to_workspace_7: ส่งไปยังเวิร์กสเปซ 7 - send_to_workspace_4: ส่งไปยังเวิร์กสเปซ 4 - move_to_workspace_7: ย้ายไปที่เวิร์กสเปซ 7 - enable: เปิดใช้งานทางลัดแบบบูรณาการ (AHK) - enable_tooltip: ปิดการใช้งานหากคุณจะใช้ทางลัดของคุณเองโดยใช้ Seelen Core API -inProgress: กำลังดำเนินการ... -cancel: ยกเลิก -delete: ลบ -save: บันทึก -quit: ล้มเลิก -open: เปิด -loading: กำลังโหลด ... +sides: + bottom: ด้านล่าง + right: ขวา + left: ซ้าย + top: สูงสุด +header: + labels: + info: ข้อมูล + general: ทั่วไป + developer: ผู้พัฒนา + seelen_bar: แถบเครื่องมือแฟนซี + seelen_weg: แท่นวาง/บาร์ + specific_apps: แอพเฉพาะ + seelen_wm: ผู้จัดการหน้าต่าง + monitors: จอภาพ + shortcuts: ทางลัด +start: + title: ยินดีต้อนรับ! + message_accent: เพิ่มประสิทธิภาพการทำงานของคุณอย่างมีสไตล์! + message: >- + ยินดีต้อนรับสู่ Seelen UI สภาพแวดล้อมเดสก์ท็อปที่ดีที่สุดพร้อมตัวจัดการ + Windows Tiling ที่จัดตั้งขึ้นเพื่อปรับปรุงประสบการณ์ Windows 11 ของคุณ! + สำรวจยุคใหม่ของประสิทธิภาพและการทำงานหลายอย่างด้วยอินเทอร์เฟซที่ใช้งานง่ายและคุณสมบัติขั้นสูงของเรา +general: + theme: + author: ผู้เขียน + add: เพิ่มธีม + description: คำอธิบาย + placeholder: เลือกธีม + tags: แท็ก + added: ธีมเพิ่มแล้ว + label: ข้อมูลธีม + enabled: เปิดใช้งานธีม + available: มีอยู่ + selected: ที่เลือกสรรแล้ว + language: ภาษา + startup: วิ่งเมื่อเริ่มต้น? + icon_pack: + label: ไอคอนแพ็ค + accent_color: สีเน้น +toolbar: + placeholder: + author: ผู้เขียน + description: คำอธิบาย + select: โครงสร้างแถบเครื่องมือ + height: ความสูง + enable: เปิดใช้งานแถบเครื่องมือแฟนซี +wm: + border: + width: ความกว้างชายแดน + enable: เปิดใช้งานเส้นขอบของหน้าต่าง + offset: ชดเชยพรมแดน + author: ผู้เขียน + description: คำอธิบาย + workspace_offset: พื้นที่ทำงานออฟเซ็ต (ระยะขอบ) + space_between_containers: ช่องว่างระหว่างภาชนะบรรจุ + layout: เค้าโครง + resize_delta: ปรับขนาดเดลต้า (%) + enable: เปิดใช้งาน Manager Window + workspace_padding: ช่องว่างพื้นที่ทำงาน + disabled_windows10: ตัวจัดการหน้าต่างไม่สามารถใช้ได้สำหรับ Windows 10 +weg: + items: + size: ขนาดรายการ + zoom_size: ขนาดซูม (ใช้สำหรับธีม) + visible_separators: ตัวแยกที่มองเห็นได้ + label: รายการ + gap: ช่องว่างระหว่างรายการ + padding: การขยายความ + width: ความกว้าง + auto_hide: ซ่อนอัตโนมัติ + gap: ช่องว่าง + margin: ระยะขอบ + label: แท่นวาง/บาร์ + enable: เปิดใช้งาน Dock/Task -Babar + dock_side: ด้านท่าเรือ +devtools: + settings_file: ไฟล์การตั้งค่า + install_folder: โฟลเดอร์การติดตั้ง + enable: เปิดใช้งานเครื่องมือนักพัฒนาซอฟต์แวร์ + custom_config_file: โหลดไฟล์กำหนดค่าที่กำหนดเอง + app_folders: โฟลเดอร์แอพ + load: โหลด + data_folder: โฟลเดอร์ข้อมูล +apps_configurations: + app: + options: + float: ลอย + force: บังคับให้จัดการ + pinned: ที่ถูกตรึง + unmanage: ไม่มีการจัดการ + title_readonly: การดู {{ชื่อ}} + category: หมวดหมู่ + monitor_placeholder: ไม่มี + monitor: เฝ้าสังเกต + category_placeholder: ไม่มี + ok_create: สร้าง + ok_edit: อัปเดต + ok_readonly: แก้ไขเป็นใหม่ + workspace: พื้นที่ทำงาน + title_edit: แก้ไข {{ชื่อ}} + workspace_placeholder: ไม่มี + name: ชื่อ + bindings: การเชื่อม (หมายเหตุทั้งสองตัวเลือกเป็นสิ่งจำเป็น) + title_create: การสร้าง {{ชื่อ}} + options_label: ตัวเลือกพิเศษ + identifier: + and: และ + or: หรือ + id: ตัวระบุ + negation: คัดค้านการจับคู่ + matching_strategy: กลยุทธ์การจับคู่ + remove: ลบบล็อก + kind: ระบุโดย + add_block: เพิ่มบล็อก + delete: ลบ + new: ใหม่ + swap: แลกเปลี่ยน + export: ส่งออก + search: ค้นหา + bundled_title: แอพกำหนดค่ามาพร้อมกับ Seelen + import: นำเข้า + bundled_msg: >- + การกำหนดค่าแบบรวมเหล่านี้ไม่สามารถแก้ไขได้และได้รับการออกแบบมาเพื่อให้คุณได้รับประสบการณ์ที่ดีที่สุดโดยไม่ต้องปรับแต่ง + พวกเขากำหนดค่าแอปพลิเคชันที่พบบ่อยที่สุดสำหรับคุณโดยอัตโนมัติ + confirm_delete_title: ยืนยันการลบ + confirm_delete: แน่ใจหรือว่าต้องการลบการกำหนดค่านี้/s? +extras: + github: คนอื่น ๆ + discord: ความไม่ลงรอยกัน + exit: ออก/ออก + relaunch: เปิดใหม่ + links: ลิงค์อย่างเป็นทางการ + version: รุ่น +shortcuts: + labels: + focus_left: โฟกัสซ้าย + reserve_right: สำรองสิทธิ + switch_workspace_7: เปลี่ยนไปใช้พื้นที่ทำงาน 7 + switch_workspace_3: เปลี่ยนเป็น Workspace 3 + send_to_workspace_6: ส่งไปยังเวิร์กสเปซ 6 + send_to_workspace_8: ส่งไปยังเวิร์กสเปซ 8 + decrease_width: ลดความกว้าง + increase_height: เพิ่มความสูง + focus_bottom: โฟกัสด้านล่าง + send_to_workspace_2: ส่งไปยังเวิร์กสเปซ 2 + reserve_top: สำรองด้านบน + decrease_height: ลดความสูง + switch_workspace_0: สลับไปที่เวิร์กสเปซ 0 + reserve_bottom: สำรองด้านล่าง + move_to_workspace_8: ย้ายไปที่เวิร์กสเปซ 8 + reserve_float: สำรองลอย + send_to_workspace_3: ส่งไปยังเวิร์กสเปซ 3 + move_to_workspace_2: ย้ายไปที่เวิร์กสเปซ 2 + move_to_workspace_4: ย้ายไปที่เวิร์กสเปซ 4 + switch_workspace_6: เปลี่ยนไปใช้พื้นที่ทำงาน 6 + switch_workspace_1: เปลี่ยนไปใช้พื้นที่ทำงาน 1 + move_to_workspace_5: ย้ายไปที่เวิร์กสเปซ 5 + move_to_workspace_0: ย้ายไปที่เวิร์กสเปซ 0 + switch_workspace_9: เปลี่ยนไปใช้พื้นที่ทำงาน 9 + move_to_workspace_1: ย้ายไปที่เวิร์กสเปซ 1 + switch_workspace_5: เปลี่ยนไปใช้พื้นที่ทำงาน 5 + move_to_workspace_9: ย้ายไปที่เวิร์กสเปซ 9 + move_to_workspace_6: ย้ายไปที่เวิร์กสเปซ 6 + send_to_workspace_5: ส่งไปยังเวิร์กสเปซ 5 + restore_sizes: คืนค่าขนาด + send_to_workspace_0: ส่งไปยังเวิร์กสเปซ 0 + switch_workspace_8: เปลี่ยนไปใช้พื้นที่ทำงาน 8 + send_to_workspace_1: ส่งไปยังเวิร์กสเปซ 1 + reserve_stack: กองสำรอง + switch_workspace_4: เปลี่ยนไปใช้พื้นที่ทำงาน 4 + increase_width: เพิ่มความกว้าง + reserve_left: สำรองซ้าย + focus_top: โฟกัสด้านบน + move_to_workspace_3: ย้ายไปที่เวิร์กสเปซ 3 + focus_right: โฟกัสขวา + switch_workspace_2: เปลี่ยนเป็น Workspace 2 + send_to_workspace_9: ส่งไปยังเวิร์กสเปซ 9 + focus_latest: โฟกัสล่าสุด + send_to_workspace_7: ส่งไปยังเวิร์กสเปซ 7 + send_to_workspace_4: ส่งไปยังเวิร์กสเปซ 4 + move_to_workspace_7: ย้ายไปที่เวิร์กสเปซ 7 + enable: เปิดใช้งานทางลัดแบบบูรณาการ (AHK) + enable_tooltip: ปิดการใช้งานหากคุณจะใช้ทางลัดของคุณเองโดยใช้ Seelen Core API +inProgress: กำลังดำเนินการ... +cancel: ยกเลิก +delete: ลบ +save: บันทึก +quit: ล้มเลิก +open: เปิด +loading: กำลังโหลด ... diff --git a/src/apps/settings/i18n/translations/tl.yml b/src/apps/settings/i18n/translations/tl.yml index 879c69c4..f7f80db3 100644 --- a/src/apps/settings/i18n/translations/tl.yml +++ b/src/apps/settings/i18n/translations/tl.yml @@ -1,196 +1,196 @@ -sides: - right: Tama - left: Kaliwa - top: Tuktok - bottom: Ilalim -header: - labels: - seelen_bar: Fancy Toolbar - seelen_wm: Window Manager - general: Pangkalahatan - info: Impormasyon - monitors: Monitor - shortcuts: Mga shortcut - developer: Developer - specific_apps: Tukoy na apps - seelen_weg: Dock/Taskbar -start: - message: >- - Maligayang pagdating sa Seelen UI, ang panghuli desktop na kapaligiran na - may isang isinama na tiling windows manager upang mapahusay ang iyong - karanasan sa Windows 11! Galugarin ang isang bagong panahon ng kahusayan at - multitasking sa aming intuitive interface at mga advanced na tampok. - title: Maligayang pagdating! - message_accent: I -optimize ang iyong pagiging produktibo sa estilo! -general: - theme: - author: May -akda - placeholder: Piliin ang TEMA - add: Magdagdag ng tema - description: Paglalarawan - label: Impormasyon sa Tema - enabled: Pinagana ang mga tema - added: Naidagdag na ang tema - tags: Tags - selected: Napili - available: Magagamit - language: Wika - startup: Patakbuhin sa Startup? - icon_pack: - label: Icon pack - accent_color: Kulay ng accent -toolbar: - placeholder: - author: May -akda - select: Istraktura ng toolbar - description: Paglalarawan - height: Taas - enable: Paganahin ang magarbong toolbar -wm: - border: - width: Lapad ng hangganan - offset: Border Offset - enable: Paganahin ang hangganan ng window - author: May -akda - disabled_windows10: Ang window manager ay hindi magagamit para sa Windows 10. - description: Paglalarawan - space_between_containers: Puwang sa pagitan ng mga lalagyan - layout: Layout - workspace_offset: Workspaces Offset (Margin) - enable: Paganahin ang Window Manager - workspace_padding: Mga workspaces padding - resize_delta: Baguhin ang laki ng Delta (%) -weg: - items: - label: Mga item - visible_separators: Visible Separator - zoom_size: Zoom na laki (ginamit para sa mga tema) - gap: Puwang sa pagitan ng mga item - size: Laki ng item - width: Lapad - padding: Padding - enable: Paganahin ang pantalan/taskbar - label: Dock/Taskbar - margin: Margin - auto_hide: Auto itago - dock_side: Dock side - gap: Gap -devtools: - custom_config_file: I -load ang pasadyang config file - app_folders: Mga folder ng app - load: Mag -load - settings_file: File ng mga setting - data_folder: Folder ng data - install_folder: Folder ng pag -install - enable: Paganahin ang mga tool ng developer -apps_configurations: - app: - options: - float: Lumutang - force: Pamahalaan ang Pamahalaan - pinned: Naka -pin - unmanage: Hindi namamahala - bindings: Ang pagbubuklod (tandaan ang parehong mga pagpipilian ay kinakailangan) - ok_edit: I -update - title_create: Lumilikha ng {{pangalan}} - title_readonly: Pagtingin {{pangalan}} - category_placeholder: Wala - ok_create: Lumikha - monitor_placeholder: Wala - title_edit: Pag -edit {{pangalan}} - category: Kategorya - ok_readonly: I -edit bilang bago - options_label: Dagdag na mga pagpipilian - workspace: Workspace - monitor: Subaybayan - workspace_placeholder: Wala - name: Pangalan - identifier: - id: Identifier - negation: Negate pagtutugma - kind: Kilalanin ng - remove: Tanggalin ang bloke - matching_strategy: Diskarte sa pagtutugma - add_block: Magdagdag ng block - or: O - and: At - import: Angkat - delete: Tanggalin - search: Maghanap - export: I -export - bundled_title: Ang config ng app na naka -bundle kay Seelen - bundled_msg: >- - Ang mga naka -bundle na mga pagsasaayos ay hindi mai -edit at idinisenyo - upang mabigyan ka ng pinakamahusay na karanasan nang walang pagpapasadya. - Awtomatiko nilang i -configure ang pinaka -karaniwang mga aplikasyon para sa - iyo. - confirm_delete: Sigurado ka bang nais mong tanggalin ang pagsasaayos na ito/s? - confirm_delete_title: Kumpirmahin ang Tanggalin - new: Bago - swap: Ipagpalit -extras: - relaunch: Muling pagsasaayos - version: Bersyon - exit: Huminto/exit - github: Github - links: Opisyal na mga link - discord: Discord -shortcuts: - labels: - focus_top: Tumuon sa itaas - reserve_stack: Reserve stack - increase_height: Dagdagan ang taas - focus_bottom: Pokus sa ilalim - switch_workspace_5: Lumipat sa Workspace 5 - focus_left: Kaliwa ng Focus - send_to_workspace_2: Ipadala sa Workspace 2 - switch_workspace_6: Lumipat sa Workspace 6 - send_to_workspace_6: Ipadala sa Workspace 6 - focus_latest: Pinakabagong ituon - send_to_workspace_0: Ipadala sa Workspace 0 - move_to_workspace_0: Lumipat sa workspace 0 - send_to_workspace_8: Ipadala sa Workspace 8 - restore_sizes: Ibalik ang mga sukat - move_to_workspace_8: Lumipat sa Workspace 8 - switch_workspace_9: Lumipat sa Workspace 9 - reserve_left: Reserve Kaliwa - send_to_workspace_1: Ipadala sa Workspace 1 - switch_workspace_3: Lumipat sa Workspace 3 - send_to_workspace_5: Ipadala sa Workspace 5 - reserve_top: Reserve top - switch_workspace_7: Lumipat sa Workspace 7 - reserve_right: Tama ang reserba - move_to_workspace_9: Lumipat sa Workspace 9 - send_to_workspace_9: Ipadala sa Workspace 9 - move_to_workspace_5: Lumipat sa Workspace 5 - move_to_workspace_3: Lumipat sa Workspace 3 - switch_workspace_2: Lumipat sa Workspace 2 - switch_workspace_4: Lumipat sa Workspace 4 - move_to_workspace_6: Lumipat sa Workspace 6 - decrease_width: Bawasan ang lapad - move_to_workspace_2: Lumipat sa Workspace 2 - reserve_bottom: Reserve Bottom - move_to_workspace_7: Lumipat sa Workspace 7 - move_to_workspace_4: Lumipat sa Workspace 4 - increase_width: Dagdagan ang lapad - reserve_float: Reserve float - send_to_workspace_4: Ipadala sa Workspace 4 - decrease_height: Bawasan ang taas - focus_right: Tama ang ituon - move_to_workspace_1: Lumipat sa Workspace 1 - switch_workspace_8: Lumipat sa Workspace 8 - switch_workspace_1: Lumipat sa Workspace 1 - switch_workspace_0: Lumipat sa workspace 0 - send_to_workspace_7: Ipadala sa Workspace 7 - send_to_workspace_3: Ipadala sa Workspace 3 - enable_tooltip: >- - Huwag paganahin kung ipatutupad mo ang iyong sariling mga shortcut gamit ang - Seelen Core API - enable: Paganahin ang Integrated Shortcut (AHK) -inProgress: Sa pag -unlad ... -delete: Tanggalin -loading: Naglo -load ... -cancel: Kanselahin -quit: Huminto ka -open: Buksan -save: I -save +sides: + right: Tama + left: Kaliwa + top: Tuktok + bottom: Ilalim +header: + labels: + seelen_bar: Fancy Toolbar + seelen_wm: Window Manager + general: Pangkalahatan + info: Impormasyon + monitors: Monitor + shortcuts: Mga shortcut + developer: Developer + specific_apps: Tukoy na apps + seelen_weg: Dock/Taskbar +start: + message: >- + Maligayang pagdating sa Seelen UI, ang panghuli desktop na kapaligiran na + may isang isinama na tiling windows manager upang mapahusay ang iyong + karanasan sa Windows 11! Galugarin ang isang bagong panahon ng kahusayan at + multitasking sa aming intuitive interface at mga advanced na tampok. + title: Maligayang pagdating! + message_accent: I -optimize ang iyong pagiging produktibo sa estilo! +general: + theme: + author: May -akda + placeholder: Piliin ang TEMA + add: Magdagdag ng tema + description: Paglalarawan + label: Impormasyon sa Tema + enabled: Pinagana ang mga tema + added: Naidagdag na ang tema + tags: Tags + selected: Napili + available: Magagamit + language: Wika + startup: Patakbuhin sa Startup? + icon_pack: + label: Icon pack + accent_color: Kulay ng accent +toolbar: + placeholder: + author: May -akda + select: Istraktura ng toolbar + description: Paglalarawan + height: Taas + enable: Paganahin ang magarbong toolbar +wm: + border: + width: Lapad ng hangganan + offset: Border Offset + enable: Paganahin ang hangganan ng window + author: May -akda + disabled_windows10: Ang window manager ay hindi magagamit para sa Windows 10. + description: Paglalarawan + space_between_containers: Puwang sa pagitan ng mga lalagyan + layout: Layout + workspace_offset: Workspaces Offset (Margin) + enable: Paganahin ang Window Manager + workspace_padding: Mga workspaces padding + resize_delta: Baguhin ang laki ng Delta (%) +weg: + items: + label: Mga item + visible_separators: Visible Separator + zoom_size: Zoom na laki (ginamit para sa mga tema) + gap: Puwang sa pagitan ng mga item + size: Laki ng item + width: Lapad + padding: Padding + enable: Paganahin ang pantalan/taskbar + label: Dock/Taskbar + margin: Margin + auto_hide: Auto itago + dock_side: Dock side + gap: Gap +devtools: + custom_config_file: I -load ang pasadyang config file + app_folders: Mga folder ng app + load: Mag -load + settings_file: File ng mga setting + data_folder: Folder ng data + install_folder: Folder ng pag -install + enable: Paganahin ang mga tool ng developer +apps_configurations: + app: + options: + float: Lumutang + force: Pamahalaan ang Pamahalaan + pinned: Naka -pin + unmanage: Hindi namamahala + bindings: Ang pagbubuklod (tandaan ang parehong mga pagpipilian ay kinakailangan) + ok_edit: I -update + title_create: Lumilikha ng {{pangalan}} + title_readonly: Pagtingin {{pangalan}} + category_placeholder: Wala + ok_create: Lumikha + monitor_placeholder: Wala + title_edit: Pag -edit {{pangalan}} + category: Kategorya + ok_readonly: I -edit bilang bago + options_label: Dagdag na mga pagpipilian + workspace: Workspace + monitor: Subaybayan + workspace_placeholder: Wala + name: Pangalan + identifier: + id: Identifier + negation: Negate pagtutugma + kind: Kilalanin ng + remove: Tanggalin ang bloke + matching_strategy: Diskarte sa pagtutugma + add_block: Magdagdag ng block + or: O + and: At + import: Angkat + delete: Tanggalin + search: Maghanap + export: I -export + bundled_title: Ang config ng app na naka -bundle kay Seelen + bundled_msg: >- + Ang mga naka -bundle na mga pagsasaayos ay hindi mai -edit at idinisenyo + upang mabigyan ka ng pinakamahusay na karanasan nang walang pagpapasadya. + Awtomatiko nilang i -configure ang pinaka -karaniwang mga aplikasyon para sa + iyo. + confirm_delete: Sigurado ka bang nais mong tanggalin ang pagsasaayos na ito/s? + confirm_delete_title: Kumpirmahin ang Tanggalin + new: Bago + swap: Ipagpalit +extras: + relaunch: Muling pagsasaayos + version: Bersyon + exit: Huminto/exit + github: Github + links: Opisyal na mga link + discord: Discord +shortcuts: + labels: + focus_top: Tumuon sa itaas + reserve_stack: Reserve stack + increase_height: Dagdagan ang taas + focus_bottom: Pokus sa ilalim + switch_workspace_5: Lumipat sa Workspace 5 + focus_left: Kaliwa ng Focus + send_to_workspace_2: Ipadala sa Workspace 2 + switch_workspace_6: Lumipat sa Workspace 6 + send_to_workspace_6: Ipadala sa Workspace 6 + focus_latest: Pinakabagong ituon + send_to_workspace_0: Ipadala sa Workspace 0 + move_to_workspace_0: Lumipat sa workspace 0 + send_to_workspace_8: Ipadala sa Workspace 8 + restore_sizes: Ibalik ang mga sukat + move_to_workspace_8: Lumipat sa Workspace 8 + switch_workspace_9: Lumipat sa Workspace 9 + reserve_left: Reserve Kaliwa + send_to_workspace_1: Ipadala sa Workspace 1 + switch_workspace_3: Lumipat sa Workspace 3 + send_to_workspace_5: Ipadala sa Workspace 5 + reserve_top: Reserve top + switch_workspace_7: Lumipat sa Workspace 7 + reserve_right: Tama ang reserba + move_to_workspace_9: Lumipat sa Workspace 9 + send_to_workspace_9: Ipadala sa Workspace 9 + move_to_workspace_5: Lumipat sa Workspace 5 + move_to_workspace_3: Lumipat sa Workspace 3 + switch_workspace_2: Lumipat sa Workspace 2 + switch_workspace_4: Lumipat sa Workspace 4 + move_to_workspace_6: Lumipat sa Workspace 6 + decrease_width: Bawasan ang lapad + move_to_workspace_2: Lumipat sa Workspace 2 + reserve_bottom: Reserve Bottom + move_to_workspace_7: Lumipat sa Workspace 7 + move_to_workspace_4: Lumipat sa Workspace 4 + increase_width: Dagdagan ang lapad + reserve_float: Reserve float + send_to_workspace_4: Ipadala sa Workspace 4 + decrease_height: Bawasan ang taas + focus_right: Tama ang ituon + move_to_workspace_1: Lumipat sa Workspace 1 + switch_workspace_8: Lumipat sa Workspace 8 + switch_workspace_1: Lumipat sa Workspace 1 + switch_workspace_0: Lumipat sa workspace 0 + send_to_workspace_7: Ipadala sa Workspace 7 + send_to_workspace_3: Ipadala sa Workspace 3 + enable_tooltip: >- + Huwag paganahin kung ipatutupad mo ang iyong sariling mga shortcut gamit ang + Seelen Core API + enable: Paganahin ang Integrated Shortcut (AHK) +inProgress: Sa pag -unlad ... +delete: Tanggalin +loading: Naglo -load ... +cancel: Kanselahin +quit: Huminto ka +open: Buksan +save: I -save diff --git a/src/apps/settings/i18n/translations/tr.yml b/src/apps/settings/i18n/translations/tr.yml index 4c1a7e8b..1caebfc8 100644 --- a/src/apps/settings/i18n/translations/tr.yml +++ b/src/apps/settings/i18n/translations/tr.yml @@ -1,195 +1,195 @@ -sides: - bottom: Alt - top: Tepe - left: Sol - right: Sağ -header: - labels: - info: Bilgi - developer: Geliştirici - general: Genel - seelen_weg: Rıhtım/görev çubuğu - seelen_wm: Pencere yöneticisi - seelen_bar: Süslü araç çubuğu - specific_apps: Belirli uygulamalar - monitors: Monitörler - shortcuts: Kısayollar -start: - title: Hoş geldin! - message_accent: Verimliliğinizi stille optimize edin! - message: >- - Windows 11 deneyiminizi geliştirmek için birleştirilmiş bir fayans Windows - yöneticisi olan nihai masaüstü ortamı olan Seelen UI'ye hoş geldiniz! - Sezgisel arayüzümüz ve gelişmiş özelliklerimizle yeni bir verimlilik ve - çoklu görev dönemini keşfedin. -general: - theme: - description: Tanım - author: Yazar - placeholder: Tema seçin - tags: Etiketler - enabled: Etkin temalar - label: Tema Bilgileri - added: Tema zaten eklendi - add: Tema ekle - available: Mevcut - selected: Seçilmiş - language: Dil - startup: Başlangıçta koşmak mı? - icon_pack: - label: Simge paketleri - accent_color: Aksan rengi -toolbar: - placeholder: - author: Yazar - description: Tanım - select: Araç çubuğu yapısı - height: Yükseklik - enable: Süslü araç çubuğunu etkinleştirin -wm: - border: - width: Sınır genişliği - offset: Sınır ofseti - enable: Pencerenin Sınırını Etkinleştir - layout: Düzen - author: Yazar - description: Tanım - workspace_padding: Çalışma alanları dolgu - disabled_windows10: Pencere yöneticisi Windows 10 için mevcut değildir. - resize_delta: Yeniden boyutlandırma delta (%) - enable: Pencere Yöneticisini Etkinleştir - space_between_containers: Konteynerler arasındaki boşluk - workspace_offset: Çalışma alanları ofseti (kenar boşlukları) -weg: - items: - label: Öğeler - zoom_size: Yakınlaştırılmış boyut (temalar için kullanılır) - visible_separators: Görünür Ayırıcılar - gap: Ürünler arasında boşluk - size: Öğe boyutu - width: Genişlik - auto_hide: Otomatik gizleme - gap: Açıklık - padding: Dolgu malzemesi - margin: Marj - enable: Dock/görev çubuğunu etkinleştir - label: Rıhtım/görev çubuğu - dock_side: Rıhtım tarafı -devtools: - custom_config_file: Özel Yapılandırma Dosyasını Yükle - settings_file: Ayarlar Dosyası - load: Yük - data_folder: Veri klasörü - install_folder: Kurulum klasörü - app_folders: Uygulama klasörleri - enable: Geliştirici Araçlarını Etkinleştir -apps_configurations: - app: - options: - float: Batmadan yüzmek - pinned: Sabitlenmiş - force: Zorlamak - unmanage: Yönetilmek - title_create: '{{Name}} oluşturmak' - monitor: İzlemek - category_placeholder: Hiçbiri - ok_create: Yaratmak - ok_edit: Güncelleme - monitor_placeholder: Hiçbiri - options_label: Ekstra Seçenekler - name: İsim - bindings: Bağlama (Not Her iki seçeneğin de gerekli olduğunu not edin) - category: Kategori - title_readonly: Görüntüleme {{name}} - workspace: Çalışma alanı - workspace_placeholder: Hiçbiri - ok_readonly: Yeni Olarak Düzenle - title_edit: Düzenleme {{name}} - identifier: - and: VE - matching_strategy: Eşleştirme Stratejisi - or: VEYA - add_block: Blok ekle - kind: Tanımlamak - id: Tanımlayıcı - remove: Blok silme - negation: Eşleşmeyi reddet - export: İhracat - swap: Takas - search: Aramak - import: İçe aktarmak - bundled_msg: >- - Bu paketlenmiş konfigürasyonlar düzenlenemez değildir ve size - özelleştirmeden en iyi deneyimi sağlamak için tasarlanmıştır. Sizin için en - yaygın uygulamaları otomatik olarak yapılandırırlar. - delete: Silmek - new: Yeni - bundled_title: Seelen ile paketlenmiş uygulama yapılandırma - confirm_delete: Bu yapılandırmayı/s'yi silmek istediğinizden emin misiniz? - confirm_delete_title: Silini onaylayın -extras: - github: Gitithub - links: Resmi Bağlantılar - discord: Anlaşmazlık - relaunch: Yeniden başlatmak - exit: Çık/Çık - version: Versiyon -shortcuts: - labels: - send_to_workspace_0: Çalışma Alanına Gönder 0 - move_to_workspace_4: Çalışma Alanına Taşın 4 - move_to_workspace_5: Çalışma Alanına Taşın 5 - move_to_workspace_0: Çalışma Alanına Taşın 0 - focus_latest: En son odak - restore_sizes: Boyutları Geri Yükle - send_to_workspace_4: Çalışma Alanına Gönder 4 - send_to_workspace_8: Çalışma Alanına Gönder 8 - focus_top: Focus tepe - move_to_workspace_2: Çalışma Alanına Taşın 2 - reserve_top: Üst kısım - move_to_workspace_1: Çalışma Alanına Taşın 1 - focus_left: Sola odaklanmak - send_to_workspace_6: Çalışma Alanına Gönder 6 - switch_workspace_3: Çalışma Alanına Geçin 3 - decrease_width: Genişliği Azalt - move_to_workspace_6: Çalışma Alanına Taşın 6 - switch_workspace_1: Çalışma Alanına Geç 1 - switch_workspace_8: Çalışma Alanı 8'e geç - reserve_left: Sola gitme - switch_workspace_9: Çalışma Alanına geç 9 - reserve_float: Yüzmek - reserve_bottom: Dip - send_to_workspace_1: Çalışma Alanına Gönder 1 - move_to_workspace_8: Çalışma Alanına Taşın 8 - switch_workspace_2: Çalışma Alanı 2'ye geçin - switch_workspace_4: Çalışma Alanına Geçiş 4 - reserve_stack: Yedek yığın - move_to_workspace_7: Çalışma Alanına Taşın - decrease_height: Yüksekliği Azalt - send_to_workspace_2: Çalışma Alanına Gönder 2 - move_to_workspace_3: Çalışma Alanına Taşın 3 - send_to_workspace_5: Çalışma Alanına Gönder 5 - switch_workspace_0: Çalışma alanına geç 0 - focus_bottom: Dip - switch_workspace_7: Çalışma Alanı 7'ye geç - send_to_workspace_9: Çalışma Alanına Gönder 9 - increase_height: Yüksekliği arttırmak - focus_right: Doğru odaklanmak - reserve_right: Doğru ayırtmak - send_to_workspace_3: Çalışma Alanına Gönder 3 - increase_width: Genişliği Artırın - switch_workspace_6: Çalışma Alanı 6'ya geç - move_to_workspace_9: Çalışma Alanına Taşın 9 - send_to_workspace_7: Çalışma Alanına Gönder 7 - switch_workspace_5: Çalışma Alanı 5'e geç - enable_tooltip: >- - Seelen Core API'sını kullanarak kendi kısayollarınızı uygulayacaksanız devre - dışı bırakın - enable: Entegre Kısayolları Etkinleştir (AHK) -cancel: İptal etmek -inProgress: Devam etmekte... -loading: Yükleniyor... -quit: Çıkış yapmak -save: Kaydetmek -delete: Silmek -open: Açık +sides: + bottom: Alt + top: Tepe + left: Sol + right: Sağ +header: + labels: + info: Bilgi + developer: Geliştirici + general: Genel + seelen_weg: Rıhtım/görev çubuğu + seelen_wm: Pencere yöneticisi + seelen_bar: Süslü araç çubuğu + specific_apps: Belirli uygulamalar + monitors: Monitörler + shortcuts: Kısayollar +start: + title: Hoş geldin! + message_accent: Verimliliğinizi stille optimize edin! + message: >- + Windows 11 deneyiminizi geliştirmek için birleştirilmiş bir fayans Windows + yöneticisi olan nihai masaüstü ortamı olan Seelen UI'ye hoş geldiniz! + Sezgisel arayüzümüz ve gelişmiş özelliklerimizle yeni bir verimlilik ve + çoklu görev dönemini keşfedin. +general: + theme: + description: Tanım + author: Yazar + placeholder: Tema seçin + tags: Etiketler + enabled: Etkin temalar + label: Tema Bilgileri + added: Tema zaten eklendi + add: Tema ekle + available: Mevcut + selected: Seçilmiş + language: Dil + startup: Başlangıçta koşmak mı? + icon_pack: + label: Simge paketleri + accent_color: Aksan rengi +toolbar: + placeholder: + author: Yazar + description: Tanım + select: Araç çubuğu yapısı + height: Yükseklik + enable: Süslü araç çubuğunu etkinleştirin +wm: + border: + width: Sınır genişliği + offset: Sınır ofseti + enable: Pencerenin Sınırını Etkinleştir + layout: Düzen + author: Yazar + description: Tanım + workspace_padding: Çalışma alanları dolgu + disabled_windows10: Pencere yöneticisi Windows 10 için mevcut değildir. + resize_delta: Yeniden boyutlandırma delta (%) + enable: Pencere Yöneticisini Etkinleştir + space_between_containers: Konteynerler arasındaki boşluk + workspace_offset: Çalışma alanları ofseti (kenar boşlukları) +weg: + items: + label: Öğeler + zoom_size: Yakınlaştırılmış boyut (temalar için kullanılır) + visible_separators: Görünür Ayırıcılar + gap: Ürünler arasında boşluk + size: Öğe boyutu + width: Genişlik + auto_hide: Otomatik gizleme + gap: Açıklık + padding: Dolgu malzemesi + margin: Marj + enable: Dock/görev çubuğunu etkinleştir + label: Rıhtım/görev çubuğu + dock_side: Rıhtım tarafı +devtools: + custom_config_file: Özel Yapılandırma Dosyasını Yükle + settings_file: Ayarlar Dosyası + load: Yük + data_folder: Veri klasörü + install_folder: Kurulum klasörü + app_folders: Uygulama klasörleri + enable: Geliştirici Araçlarını Etkinleştir +apps_configurations: + app: + options: + float: Batmadan yüzmek + pinned: Sabitlenmiş + force: Zorlamak + unmanage: Yönetilmek + title_create: '{{Name}} oluşturmak' + monitor: İzlemek + category_placeholder: Hiçbiri + ok_create: Yaratmak + ok_edit: Güncelleme + monitor_placeholder: Hiçbiri + options_label: Ekstra Seçenekler + name: İsim + bindings: Bağlama (Not Her iki seçeneğin de gerekli olduğunu not edin) + category: Kategori + title_readonly: Görüntüleme {{name}} + workspace: Çalışma alanı + workspace_placeholder: Hiçbiri + ok_readonly: Yeni Olarak Düzenle + title_edit: Düzenleme {{name}} + identifier: + and: VE + matching_strategy: Eşleştirme Stratejisi + or: VEYA + add_block: Blok ekle + kind: Tanımlamak + id: Tanımlayıcı + remove: Blok silme + negation: Eşleşmeyi reddet + export: İhracat + swap: Takas + search: Aramak + import: İçe aktarmak + bundled_msg: >- + Bu paketlenmiş konfigürasyonlar düzenlenemez değildir ve size + özelleştirmeden en iyi deneyimi sağlamak için tasarlanmıştır. Sizin için en + yaygın uygulamaları otomatik olarak yapılandırırlar. + delete: Silmek + new: Yeni + bundled_title: Seelen ile paketlenmiş uygulama yapılandırma + confirm_delete: Bu yapılandırmayı/s'yi silmek istediğinizden emin misiniz? + confirm_delete_title: Silini onaylayın +extras: + github: Gitithub + links: Resmi Bağlantılar + discord: Anlaşmazlık + relaunch: Yeniden başlatmak + exit: Çık/Çık + version: Versiyon +shortcuts: + labels: + send_to_workspace_0: Çalışma Alanına Gönder 0 + move_to_workspace_4: Çalışma Alanına Taşın 4 + move_to_workspace_5: Çalışma Alanına Taşın 5 + move_to_workspace_0: Çalışma Alanına Taşın 0 + focus_latest: En son odak + restore_sizes: Boyutları Geri Yükle + send_to_workspace_4: Çalışma Alanına Gönder 4 + send_to_workspace_8: Çalışma Alanına Gönder 8 + focus_top: Focus tepe + move_to_workspace_2: Çalışma Alanına Taşın 2 + reserve_top: Üst kısım + move_to_workspace_1: Çalışma Alanına Taşın 1 + focus_left: Sola odaklanmak + send_to_workspace_6: Çalışma Alanına Gönder 6 + switch_workspace_3: Çalışma Alanına Geçin 3 + decrease_width: Genişliği Azalt + move_to_workspace_6: Çalışma Alanına Taşın 6 + switch_workspace_1: Çalışma Alanına Geç 1 + switch_workspace_8: Çalışma Alanı 8'e geç + reserve_left: Sola gitme + switch_workspace_9: Çalışma Alanına geç 9 + reserve_float: Yüzmek + reserve_bottom: Dip + send_to_workspace_1: Çalışma Alanına Gönder 1 + move_to_workspace_8: Çalışma Alanına Taşın 8 + switch_workspace_2: Çalışma Alanı 2'ye geçin + switch_workspace_4: Çalışma Alanına Geçiş 4 + reserve_stack: Yedek yığın + move_to_workspace_7: Çalışma Alanına Taşın + decrease_height: Yüksekliği Azalt + send_to_workspace_2: Çalışma Alanına Gönder 2 + move_to_workspace_3: Çalışma Alanına Taşın 3 + send_to_workspace_5: Çalışma Alanına Gönder 5 + switch_workspace_0: Çalışma alanına geç 0 + focus_bottom: Dip + switch_workspace_7: Çalışma Alanı 7'ye geç + send_to_workspace_9: Çalışma Alanına Gönder 9 + increase_height: Yüksekliği arttırmak + focus_right: Doğru odaklanmak + reserve_right: Doğru ayırtmak + send_to_workspace_3: Çalışma Alanına Gönder 3 + increase_width: Genişliği Artırın + switch_workspace_6: Çalışma Alanı 6'ya geç + move_to_workspace_9: Çalışma Alanına Taşın 9 + send_to_workspace_7: Çalışma Alanına Gönder 7 + switch_workspace_5: Çalışma Alanı 5'e geç + enable_tooltip: >- + Seelen Core API'sını kullanarak kendi kısayollarınızı uygulayacaksanız devre + dışı bırakın + enable: Entegre Kısayolları Etkinleştir (AHK) +cancel: İptal etmek +inProgress: Devam etmekte... +loading: Yükleniyor... +quit: Çıkış yapmak +save: Kaydetmek +delete: Silmek +open: Açık diff --git a/src/apps/settings/i18n/translations/uk.yml b/src/apps/settings/i18n/translations/uk.yml index 03993482..44644c8a 100644 --- a/src/apps/settings/i18n/translations/uk.yml +++ b/src/apps/settings/i18n/translations/uk.yml @@ -1,193 +1,193 @@ -sides: - right: Право - left: Лівий - top: Топ - bottom: Дно -header: - labels: - specific_apps: Конкретні програми - info: Інформація - seelen_bar: Панель інструментів вишуканих - general: Загальний - seelen_weg: Док/панель завдань - monitors: Монітори - developer: Розробник - seelen_wm: Менеджер вікон - shortcuts: Ярлики -start: - title: Ласкаво просимо! - message_accent: Оптимізуйте свою продуктивність стилем! - message: >- - Ласкаво просимо в інтерфейс SEELEN, Ultimate Desktop Envirtional із - включеним менеджером з плитки Windows для покращення вашого досвіду Windows - 11! Вивчіть нову еру ефективності та багатозадачності за допомогою нашого - інтуїтивного інтерфейсу та розширених функцій. -general: - theme: - enabled: Увімкнено теми - added: Тема вже додана - description: Опис - author: Автор - tags: Теги - add: Додати тему - label: Інформація про тему - placeholder: Виберіть тему - selected: Обраний - available: Доступний - language: Мова - startup: Бігати на стартап? - icon_pack: - label: Пакети значків - accent_color: Акцентний колір -toolbar: - placeholder: - select: Структура панелі інструментів - description: Опис - author: Автор - enable: Увімкнути панель інструментів вишуканих - height: Висота -wm: - border: - width: Ширина кордону - enable: Увімкнути кордон вікна - offset: Зміщення кордону - enable: Увімкніть менеджер вікон - description: Опис - resize_delta: Змінити розмір дельти (%) - layout: Макет - disabled_windows10: Менеджер вікон недоступний для Windows 10. - author: Автор - workspace_offset: Зсув робочих просторів (поля) - space_between_containers: Простір між контейнерами - workspace_padding: Прокладка робочих просторів -weg: - items: - label: Предмети - zoom_size: Збільшений розмір (використовується для тем) - size: Розмір товару - gap: Простір між предметами - visible_separators: Видимі сепаратори - enable: Увімкнути док/панель завдань - margin: Націнка - auto_hide: Автомати - label: Док/панель завдань - gap: Розрив - width: Ширина - padding: Прокладка - dock_side: Причал -devtools: - load: Навантаження - app_folders: Папки додатків - install_folder: Папка встановлення - custom_config_file: Завантажте власний конфігураційний файл - data_folder: Папка даних - enable: Увімкнути інструменти розробника - settings_file: Файл налаштувань -apps_configurations: - app: - options: - force: Управління силою - float: Плавати - pinned: Закріплений - unmanage: Неемінь - ok_edit: Оновити - options_label: Додаткові варіанти - monitor: Моніторинг - category: Категорія - title_create: Створення {{Ім'я}} - ok_readonly: Редагувати як нове - title_readonly: Перегляд {{Ім'я}} - category_placeholder: Ні - monitor_placeholder: Ні - workspace_placeholder: Ні - workspace: Робоча область - title_edit: Редагування {{Ім'я}} - ok_create: Створити - name: Назва - bindings: Зобов’язання (ПРИМІТКА Обидва варіанти потрібні) - identifier: - and: І - add_block: Додати блок - matching_strategy: Стратегія відповідності - kind: Ідентифікувати - remove: Видалити блок - or: Або - negation: Заперечувати відповідність - id: Ідентифікатор - delete: Видаляти - confirm_delete: Ви впевнені, що хочете видалити цю конфігурацію? - swap: Обміняти - bundled_title: Конфігурація додатка в комплекті з Seelen - export: Експорт - confirm_delete_title: Підтвердьте видалення - import: Імпорт - search: Обшук - bundled_msg: >- - Ці конфігурації в комплекті не підлягають редагуванню та розроблені для - того, щоб забезпечити вам найкращий досвід без налаштування. Вони - автоматично налаштовують для вас найпоширеніші програми. - new: Новачок -extras: - links: Офіційні посилання - relaunch: Відновлювати - github: Гітб - exit: Кинути/вийти - discord: Розбрат - version: Версія -shortcuts: - labels: - move_to_workspace_5: Перехід до робочої області 5 - move_to_workspace_4: Переходити до робочої області 4 - move_to_workspace_2: Перехід до робочої області 2 - focus_latest: Фокус найновіший - switch_workspace_0: Перехід на робочу область 0 - switch_workspace_7: Перехід на робочу область 7 - switch_workspace_2: Перехід на робочу область 2 - switch_workspace_1: Перехід на робочу область 1 - increase_width: Збільшити ширину - switch_workspace_3: Перехід на робочу область 3 - move_to_workspace_9: Переходити до робочої області 9 - decrease_height: Зниження висоти - increase_height: Збільшити висоту - reserve_stack: Резерв - send_to_workspace_1: Надіслати на робочу область 1 - move_to_workspace_8: Перехід до робочої області 8 - switch_workspace_6: Перехід на робочу область 6 - send_to_workspace_9: Надіслати на робочу область 9 - restore_sizes: Відновити розміри - focus_top: Фокус - move_to_workspace_1: Переходити до робочої області 1 - reserve_bottom: ЗАБЕЗПЕЧЕННЯ - send_to_workspace_3: Надіслати на робочу область 3 - send_to_workspace_8: Надіслати на робочу область 8 - move_to_workspace_6: Переходити до робочої області 6 - switch_workspace_9: Перехід на робочу область 9 - focus_bottom: Фокус дно - reserve_left: Резерв зліва - move_to_workspace_0: Перехід до робочої області 0 - send_to_workspace_5: Надіслати на робочу область 5 - switch_workspace_5: Перехід на робочу область 5 - reserve_top: Резервувати топ - decrease_width: Зменшення ширини - switch_workspace_8: Перехід на робочу область 8 - send_to_workspace_4: Надіслати на робочу область 4 - reserve_right: Резервуйте праворуч - move_to_workspace_3: Переходити до робочої області 3 - send_to_workspace_2: Надіслати на робочу область 2 - switch_workspace_4: Перехід на робочу область 4 - move_to_workspace_7: Перехід до робочої області 7 - reserve_float: Резервне плавання - send_to_workspace_0: Надіслати на робочу область 0 - focus_left: Фокус ліворуч - send_to_workspace_6: Надіслати на робочу область 6 - focus_right: Фокус правильно - send_to_workspace_7: Надіслати на робочу область 7 - enable_tooltip: Вимкніть, якщо ви реалізуєте власні ярлики за допомогою API Seelen Core - enable: Увімкнути інтегровані ярлики (AHK) -delete: Видаляти -inProgress: В процесі... -cancel: Скасувати -save: Заощадити -open: ВІДЧИНЕНО -quit: Кинути -loading: Завантаження ... +sides: + right: Право + left: Лівий + top: Топ + bottom: Дно +header: + labels: + specific_apps: Конкретні програми + info: Інформація + seelen_bar: Панель інструментів вишуканих + general: Загальний + seelen_weg: Док/панель завдань + monitors: Монітори + developer: Розробник + seelen_wm: Менеджер вікон + shortcuts: Ярлики +start: + title: Ласкаво просимо! + message_accent: Оптимізуйте свою продуктивність стилем! + message: >- + Ласкаво просимо в інтерфейс SEELEN, Ultimate Desktop Envirtional із + включеним менеджером з плитки Windows для покращення вашого досвіду Windows + 11! Вивчіть нову еру ефективності та багатозадачності за допомогою нашого + інтуїтивного інтерфейсу та розширених функцій. +general: + theme: + enabled: Увімкнено теми + added: Тема вже додана + description: Опис + author: Автор + tags: Теги + add: Додати тему + label: Інформація про тему + placeholder: Виберіть тему + selected: Обраний + available: Доступний + language: Мова + startup: Бігати на стартап? + icon_pack: + label: Пакети значків + accent_color: Акцентний колір +toolbar: + placeholder: + select: Структура панелі інструментів + description: Опис + author: Автор + enable: Увімкнути панель інструментів вишуканих + height: Висота +wm: + border: + width: Ширина кордону + enable: Увімкнути кордон вікна + offset: Зміщення кордону + enable: Увімкніть менеджер вікон + description: Опис + resize_delta: Змінити розмір дельти (%) + layout: Макет + disabled_windows10: Менеджер вікон недоступний для Windows 10. + author: Автор + workspace_offset: Зсув робочих просторів (поля) + space_between_containers: Простір між контейнерами + workspace_padding: Прокладка робочих просторів +weg: + items: + label: Предмети + zoom_size: Збільшений розмір (використовується для тем) + size: Розмір товару + gap: Простір між предметами + visible_separators: Видимі сепаратори + enable: Увімкнути док/панель завдань + margin: Націнка + auto_hide: Автомати + label: Док/панель завдань + gap: Розрив + width: Ширина + padding: Прокладка + dock_side: Причал +devtools: + load: Навантаження + app_folders: Папки додатків + install_folder: Папка встановлення + custom_config_file: Завантажте власний конфігураційний файл + data_folder: Папка даних + enable: Увімкнути інструменти розробника + settings_file: Файл налаштувань +apps_configurations: + app: + options: + force: Управління силою + float: Плавати + pinned: Закріплений + unmanage: Неемінь + ok_edit: Оновити + options_label: Додаткові варіанти + monitor: Моніторинг + category: Категорія + title_create: Створення {{Ім'я}} + ok_readonly: Редагувати як нове + title_readonly: Перегляд {{Ім'я}} + category_placeholder: Ні + monitor_placeholder: Ні + workspace_placeholder: Ні + workspace: Робоча область + title_edit: Редагування {{Ім'я}} + ok_create: Створити + name: Назва + bindings: Зобов’язання (ПРИМІТКА Обидва варіанти потрібні) + identifier: + and: І + add_block: Додати блок + matching_strategy: Стратегія відповідності + kind: Ідентифікувати + remove: Видалити блок + or: Або + negation: Заперечувати відповідність + id: Ідентифікатор + delete: Видаляти + confirm_delete: Ви впевнені, що хочете видалити цю конфігурацію? + swap: Обміняти + bundled_title: Конфігурація додатка в комплекті з Seelen + export: Експорт + confirm_delete_title: Підтвердьте видалення + import: Імпорт + search: Обшук + bundled_msg: >- + Ці конфігурації в комплекті не підлягають редагуванню та розроблені для + того, щоб забезпечити вам найкращий досвід без налаштування. Вони + автоматично налаштовують для вас найпоширеніші програми. + new: Новачок +extras: + links: Офіційні посилання + relaunch: Відновлювати + github: Гітб + exit: Кинути/вийти + discord: Розбрат + version: Версія +shortcuts: + labels: + move_to_workspace_5: Перехід до робочої області 5 + move_to_workspace_4: Переходити до робочої області 4 + move_to_workspace_2: Перехід до робочої області 2 + focus_latest: Фокус найновіший + switch_workspace_0: Перехід на робочу область 0 + switch_workspace_7: Перехід на робочу область 7 + switch_workspace_2: Перехід на робочу область 2 + switch_workspace_1: Перехід на робочу область 1 + increase_width: Збільшити ширину + switch_workspace_3: Перехід на робочу область 3 + move_to_workspace_9: Переходити до робочої області 9 + decrease_height: Зниження висоти + increase_height: Збільшити висоту + reserve_stack: Резерв + send_to_workspace_1: Надіслати на робочу область 1 + move_to_workspace_8: Перехід до робочої області 8 + switch_workspace_6: Перехід на робочу область 6 + send_to_workspace_9: Надіслати на робочу область 9 + restore_sizes: Відновити розміри + focus_top: Фокус + move_to_workspace_1: Переходити до робочої області 1 + reserve_bottom: ЗАБЕЗПЕЧЕННЯ + send_to_workspace_3: Надіслати на робочу область 3 + send_to_workspace_8: Надіслати на робочу область 8 + move_to_workspace_6: Переходити до робочої області 6 + switch_workspace_9: Перехід на робочу область 9 + focus_bottom: Фокус дно + reserve_left: Резерв зліва + move_to_workspace_0: Перехід до робочої області 0 + send_to_workspace_5: Надіслати на робочу область 5 + switch_workspace_5: Перехід на робочу область 5 + reserve_top: Резервувати топ + decrease_width: Зменшення ширини + switch_workspace_8: Перехід на робочу область 8 + send_to_workspace_4: Надіслати на робочу область 4 + reserve_right: Резервуйте праворуч + move_to_workspace_3: Переходити до робочої області 3 + send_to_workspace_2: Надіслати на робочу область 2 + switch_workspace_4: Перехід на робочу область 4 + move_to_workspace_7: Перехід до робочої області 7 + reserve_float: Резервне плавання + send_to_workspace_0: Надіслати на робочу область 0 + focus_left: Фокус ліворуч + send_to_workspace_6: Надіслати на робочу область 6 + focus_right: Фокус правильно + send_to_workspace_7: Надіслати на робочу область 7 + enable_tooltip: Вимкніть, якщо ви реалізуєте власні ярлики за допомогою API Seelen Core + enable: Увімкнути інтегровані ярлики (AHK) +delete: Видаляти +inProgress: В процесі... +cancel: Скасувати +save: Заощадити +open: ВІДЧИНЕНО +quit: Кинути +loading: Завантаження ... diff --git a/src/apps/settings/i18n/translations/ur.yml b/src/apps/settings/i18n/translations/ur.yml index 7f3b9528..8a601e7e 100644 --- a/src/apps/settings/i18n/translations/ur.yml +++ b/src/apps/settings/i18n/translations/ur.yml @@ -1,194 +1,194 @@ -sides: - left: بائیں - right: دائیں - bottom: نیچے - top: اوپر -header: - labels: - info: معلومات - seelen_weg: گودی/ٹاسک بار - developer: ڈویلپر - general: جنرل - seelen_bar: فینسی ٹول بار - specific_apps: مخصوص ایپس - seelen_wm: ونڈو مینیجر - shortcuts: شارٹ کٹ - monitors: مانیٹر -start: - title: خوش آمدید! - message_accent: اپنی پیداواری صلاحیت کو انداز کے ساتھ بہتر بنائیں! - message: >- - آپ کے ونڈوز 11 کے تجربے کو بڑھانے کے لئے شامل ٹائلنگ ونڈوز مینیجر کے ساتھ - حتمی ڈیسک ٹاپ ماحول ، سیلین UI میں خوش آمدید! ہمارے بدیہی انٹرفیس اور جدید - خصوصیات کے ساتھ کارکردگی اور ملٹی ٹاسکنگ کے ایک نئے دور کو دریافت کریں۔ -general: - theme: - enabled: قابل تھیمز - author: مصنف - add: تھیم شامل کریں - label: تھیم کی معلومات - tags: ٹیگز - added: تھیم پہلے ہی شامل کیا گیا ہے - description: تفصیل - placeholder: تھیم منتخب کریں - selected: منتخب شدہ - available: دستیاب - language: زبان - startup: اسٹارٹ اپ پر چلائیں؟ - icon_pack: - label: آئیکن پیک - accent_color: لہجہ رنگ -toolbar: - placeholder: - description: تفصیل - author: مصنف - select: ٹول بار کا ڈھانچہ - enable: فینسی ٹول بار کو فعال کریں - height: اونچائی -wm: - border: - enable: ونڈو کی بارڈر کو فعال کریں - width: بارڈر کی چوڑائی - offset: بارڈر آفسیٹ - layout: ترتیب - description: تفصیل - workspace_offset: ورک اسپیس آفسیٹ (مارجن) - space_between_containers: کنٹینرز کے درمیان جگہ - disabled_windows10: ونڈو مینیجر ونڈوز 10 کے لئے دستیاب نہیں ہے۔ - resize_delta: ڈیلٹا کا سائز (٪) - author: مصنف - enable: ونڈو مینیجر کو فعال کریں - workspace_padding: ورک اسپیس پیڈنگ -weg: - items: - label: اشیاء - zoom_size: زوم سائز (تھیمز کے لئے استعمال کیا جاتا ہے) - size: آئٹم کا سائز - gap: اشیاء کے درمیان جگہ - visible_separators: مرئی جداکار - auto_hide: خود بخود چھپ جانا - margin: مارجن - dock_side: گودی کی طرف - gap: گیپ - padding: بھرتی - width: چوڑائی - enable: گودی/ٹاسک بار کو فعال کریں - label: گودی/ٹاسک بار -devtools: - custom_config_file: کسٹم کنفیگ فائل لوڈ کریں - data_folder: ڈیٹا فولڈر - load: بوجھ - settings_file: ترتیبات فائل - enable: ڈویلپر ٹولز کو فعال کریں - install_folder: انسٹالیشن فولڈر - app_folders: ایپ فولڈرز -apps_configurations: - app: - options: - pinned: پن - unmanage: غیر منظم - float: فلوٹ - force: فورس کا انتظام کریں - category: قسم - ok_edit: اپ ڈیٹ - ok_create: بنانا - bindings: بائنڈنگ (نوٹ دونوں اختیارات کی ضرورت ہے) - title_readonly: '{{نام}} دیکھ رہا ہے' - workspace: ورک اسپیس - monitor_placeholder: کوئی نہیں - ok_readonly: نئے کے طور پر ترمیم کریں - category_placeholder: کوئی نہیں - monitor: مانیٹر - options_label: اضافی اختیارات - name: نام - title_edit: ترمیم {{نام}} - workspace_placeholder: کوئی نہیں - title_create: '{{نام}} بنانا' - identifier: - and: اور - remove: بلاک کو حذف کریں - kind: بذریعہ شناخت کریں - add_block: بلاک شامل کریں - id: شناخت کنندہ - or: یا - matching_strategy: مماثل حکمت عملی - negation: نفی مماثل - new: نئی - search: تلاش - swap: تبادلہ - export: برآمد - delete: حذف کریں - bundled_msg: >- - یہ بنڈل تشکیلات قابل تدوین نہیں ہیں اور آپ کو حسب ضرورت کے بغیر بہترین تجربہ - فراہم کرنے کے لئے ڈیزائن کی گئی ہیں۔ وہ خود بخود آپ کے لئے سب سے عام ایپلی - کیشنز کو تشکیل دیتے ہیں۔ - confirm_delete: کیا آپ واقعی اس ترتیب کو حذف کرنا چاہتے ہیں؟ - bundled_title: ایپ کنفیگ سیلن کے ساتھ بنڈل - import: درآمد - confirm_delete_title: حذف کرنے کی تصدیق کریں -extras: - links: سرکاری لنکس - discord: تنازعات - relaunch: دوبارہ لانچ - github: گٹ ہب - version: ورژن - exit: چھوڑ دیں/باہر نکلیں -shortcuts: - labels: - reserve_stack: ریزرو اسٹیک - move_to_workspace_4: ورک اسپیس 4 میں منتقل کریں - reserve_top: ریزرو ٹاپ - move_to_workspace_5: ورک اسپیس 5 میں منتقل کریں - send_to_workspace_2: ورک اسپیس 2 پر بھیجیں - switch_workspace_8: ورک اسپیس 8 پر سوئچ کریں - decrease_height: اونچائی میں کمی - switch_workspace_2: ورک اسپیس 2 پر سوئچ کریں - reserve_float: ریزرو فلوٹ - send_to_workspace_1: ورک اسپیس 1 کو بھیجیں - focus_latest: تازہ ترین توجہ مرکوز کریں - send_to_workspace_5: ورک اسپیس 5 کو بھیجیں - increase_width: چوڑائی میں اضافہ - focus_right: صحیح توجہ مرکوز کریں - move_to_workspace_8: ورک اسپیس 8 میں منتقل کریں - switch_workspace_6: ورک اسپیس 6 پر سوئچ کریں - switch_workspace_9: ورک اسپیس 9 پر سوئچ کریں - focus_bottom: فوکس نیچے - send_to_workspace_8: ورک اسپیس 8 کو بھیجیں - move_to_workspace_3: ورک اسپیس 3 میں منتقل کریں - send_to_workspace_0: ورک اسپیس 0 پر بھیجیں - focus_top: فوکس ٹاپ - reserve_left: ریزرو بائیں - send_to_workspace_9: ورک اسپیس 9 کو بھیجیں - focus_left: فوکس بائیں - send_to_workspace_7: ورک اسپیس 7 کو بھیجیں - move_to_workspace_6: ورک اسپیس 6 میں منتقل کریں - switch_workspace_5: ورک اسپیس 5 پر سوئچ کریں - send_to_workspace_3: ورک اسپیس 3 کو بھیجیں - reserve_bottom: ریزرو نیچے - move_to_workspace_0: ورک اسپیس 0 میں منتقل کریں - switch_workspace_1: ورک اسپیس 1 پر سوئچ کریں - switch_workspace_4: ورک اسپیس 4 پر سوئچ کریں - move_to_workspace_1: ورک اسپیس 1 میں منتقل کریں - switch_workspace_3: ورک اسپیس 3 پر سوئچ کریں - switch_workspace_7: ورک اسپیس 7 پر سوئچ کریں - reserve_right: ٹھیک ہے - switch_workspace_0: ورک اسپیس 0 پر سوئچ کریں - move_to_workspace_7: ورک اسپیس 7 میں منتقل کریں - send_to_workspace_6: ورک اسپیس 6 کو بھیجیں - increase_height: اونچائی میں اضافہ - decrease_width: چوڑائی کو کم کرنا - send_to_workspace_4: ورک اسپیس 4 کو بھیجیں - restore_sizes: سائز کو بحال کریں - move_to_workspace_9: ورک اسپیس 9 میں منتقل کریں - move_to_workspace_2: ورک اسپیس 2 میں منتقل کریں - enable_tooltip: >- - اگر آپ سیلین کور API کا استعمال کرتے ہوئے اپنے شارٹ کٹ کو نافذ کریں گے تو - غیر فعال کریں - enable: مربوط شارٹ کٹ (اے ایچ کے) کو فعال کریں -inProgress: کام جاری ہے... -save: بچت کریں -delete: حذف کریں -quit: چھوڑ دیں -loading: لوڈنگ ... -cancel: منسوخ کریں -open: کھلا +sides: + left: بائیں + right: دائیں + bottom: نیچے + top: اوپر +header: + labels: + info: معلومات + seelen_weg: گودی/ٹاسک بار + developer: ڈویلپر + general: جنرل + seelen_bar: فینسی ٹول بار + specific_apps: مخصوص ایپس + seelen_wm: ونڈو مینیجر + shortcuts: شارٹ کٹ + monitors: مانیٹر +start: + title: خوش آمدید! + message_accent: اپنی پیداواری صلاحیت کو انداز کے ساتھ بہتر بنائیں! + message: >- + آپ کے ونڈوز 11 کے تجربے کو بڑھانے کے لئے شامل ٹائلنگ ونڈوز مینیجر کے ساتھ + حتمی ڈیسک ٹاپ ماحول ، سیلین UI میں خوش آمدید! ہمارے بدیہی انٹرفیس اور جدید + خصوصیات کے ساتھ کارکردگی اور ملٹی ٹاسکنگ کے ایک نئے دور کو دریافت کریں۔ +general: + theme: + enabled: قابل تھیمز + author: مصنف + add: تھیم شامل کریں + label: تھیم کی معلومات + tags: ٹیگز + added: تھیم پہلے ہی شامل کیا گیا ہے + description: تفصیل + placeholder: تھیم منتخب کریں + selected: منتخب شدہ + available: دستیاب + language: زبان + startup: اسٹارٹ اپ پر چلائیں؟ + icon_pack: + label: آئیکن پیک + accent_color: لہجہ رنگ +toolbar: + placeholder: + description: تفصیل + author: مصنف + select: ٹول بار کا ڈھانچہ + enable: فینسی ٹول بار کو فعال کریں + height: اونچائی +wm: + border: + enable: ونڈو کی بارڈر کو فعال کریں + width: بارڈر کی چوڑائی + offset: بارڈر آفسیٹ + layout: ترتیب + description: تفصیل + workspace_offset: ورک اسپیس آفسیٹ (مارجن) + space_between_containers: کنٹینرز کے درمیان جگہ + disabled_windows10: ونڈو مینیجر ونڈوز 10 کے لئے دستیاب نہیں ہے۔ + resize_delta: ڈیلٹا کا سائز (٪) + author: مصنف + enable: ونڈو مینیجر کو فعال کریں + workspace_padding: ورک اسپیس پیڈنگ +weg: + items: + label: اشیاء + zoom_size: زوم سائز (تھیمز کے لئے استعمال کیا جاتا ہے) + size: آئٹم کا سائز + gap: اشیاء کے درمیان جگہ + visible_separators: مرئی جداکار + auto_hide: خود بخود چھپ جانا + margin: مارجن + dock_side: گودی کی طرف + gap: گیپ + padding: بھرتی + width: چوڑائی + enable: گودی/ٹاسک بار کو فعال کریں + label: گودی/ٹاسک بار +devtools: + custom_config_file: کسٹم کنفیگ فائل لوڈ کریں + data_folder: ڈیٹا فولڈر + load: بوجھ + settings_file: ترتیبات فائل + enable: ڈویلپر ٹولز کو فعال کریں + install_folder: انسٹالیشن فولڈر + app_folders: ایپ فولڈرز +apps_configurations: + app: + options: + pinned: پن + unmanage: غیر منظم + float: فلوٹ + force: فورس کا انتظام کریں + category: قسم + ok_edit: اپ ڈیٹ + ok_create: بنانا + bindings: بائنڈنگ (نوٹ دونوں اختیارات کی ضرورت ہے) + title_readonly: '{{نام}} دیکھ رہا ہے' + workspace: ورک اسپیس + monitor_placeholder: کوئی نہیں + ok_readonly: نئے کے طور پر ترمیم کریں + category_placeholder: کوئی نہیں + monitor: مانیٹر + options_label: اضافی اختیارات + name: نام + title_edit: ترمیم {{نام}} + workspace_placeholder: کوئی نہیں + title_create: '{{نام}} بنانا' + identifier: + and: اور + remove: بلاک کو حذف کریں + kind: بذریعہ شناخت کریں + add_block: بلاک شامل کریں + id: شناخت کنندہ + or: یا + matching_strategy: مماثل حکمت عملی + negation: نفی مماثل + new: نئی + search: تلاش + swap: تبادلہ + export: برآمد + delete: حذف کریں + bundled_msg: >- + یہ بنڈل تشکیلات قابل تدوین نہیں ہیں اور آپ کو حسب ضرورت کے بغیر بہترین تجربہ + فراہم کرنے کے لئے ڈیزائن کی گئی ہیں۔ وہ خود بخود آپ کے لئے سب سے عام ایپلی + کیشنز کو تشکیل دیتے ہیں۔ + confirm_delete: کیا آپ واقعی اس ترتیب کو حذف کرنا چاہتے ہیں؟ + bundled_title: ایپ کنفیگ سیلن کے ساتھ بنڈل + import: درآمد + confirm_delete_title: حذف کرنے کی تصدیق کریں +extras: + links: سرکاری لنکس + discord: تنازعات + relaunch: دوبارہ لانچ + github: گٹ ہب + version: ورژن + exit: چھوڑ دیں/باہر نکلیں +shortcuts: + labels: + reserve_stack: ریزرو اسٹیک + move_to_workspace_4: ورک اسپیس 4 میں منتقل کریں + reserve_top: ریزرو ٹاپ + move_to_workspace_5: ورک اسپیس 5 میں منتقل کریں + send_to_workspace_2: ورک اسپیس 2 پر بھیجیں + switch_workspace_8: ورک اسپیس 8 پر سوئچ کریں + decrease_height: اونچائی میں کمی + switch_workspace_2: ورک اسپیس 2 پر سوئچ کریں + reserve_float: ریزرو فلوٹ + send_to_workspace_1: ورک اسپیس 1 کو بھیجیں + focus_latest: تازہ ترین توجہ مرکوز کریں + send_to_workspace_5: ورک اسپیس 5 کو بھیجیں + increase_width: چوڑائی میں اضافہ + focus_right: صحیح توجہ مرکوز کریں + move_to_workspace_8: ورک اسپیس 8 میں منتقل کریں + switch_workspace_6: ورک اسپیس 6 پر سوئچ کریں + switch_workspace_9: ورک اسپیس 9 پر سوئچ کریں + focus_bottom: فوکس نیچے + send_to_workspace_8: ورک اسپیس 8 کو بھیجیں + move_to_workspace_3: ورک اسپیس 3 میں منتقل کریں + send_to_workspace_0: ورک اسپیس 0 پر بھیجیں + focus_top: فوکس ٹاپ + reserve_left: ریزرو بائیں + send_to_workspace_9: ورک اسپیس 9 کو بھیجیں + focus_left: فوکس بائیں + send_to_workspace_7: ورک اسپیس 7 کو بھیجیں + move_to_workspace_6: ورک اسپیس 6 میں منتقل کریں + switch_workspace_5: ورک اسپیس 5 پر سوئچ کریں + send_to_workspace_3: ورک اسپیس 3 کو بھیجیں + reserve_bottom: ریزرو نیچے + move_to_workspace_0: ورک اسپیس 0 میں منتقل کریں + switch_workspace_1: ورک اسپیس 1 پر سوئچ کریں + switch_workspace_4: ورک اسپیس 4 پر سوئچ کریں + move_to_workspace_1: ورک اسپیس 1 میں منتقل کریں + switch_workspace_3: ورک اسپیس 3 پر سوئچ کریں + switch_workspace_7: ورک اسپیس 7 پر سوئچ کریں + reserve_right: ٹھیک ہے + switch_workspace_0: ورک اسپیس 0 پر سوئچ کریں + move_to_workspace_7: ورک اسپیس 7 میں منتقل کریں + send_to_workspace_6: ورک اسپیس 6 کو بھیجیں + increase_height: اونچائی میں اضافہ + decrease_width: چوڑائی کو کم کرنا + send_to_workspace_4: ورک اسپیس 4 کو بھیجیں + restore_sizes: سائز کو بحال کریں + move_to_workspace_9: ورک اسپیس 9 میں منتقل کریں + move_to_workspace_2: ورک اسپیس 2 میں منتقل کریں + enable_tooltip: >- + اگر آپ سیلین کور API کا استعمال کرتے ہوئے اپنے شارٹ کٹ کو نافذ کریں گے تو + غیر فعال کریں + enable: مربوط شارٹ کٹ (اے ایچ کے) کو فعال کریں +inProgress: کام جاری ہے... +save: بچت کریں +delete: حذف کریں +quit: چھوڑ دیں +loading: لوڈنگ ... +cancel: منسوخ کریں +open: کھلا diff --git a/src/apps/settings/i18n/translations/uz.yml b/src/apps/settings/i18n/translations/uz.yml index 9ae1c29b..626a36c6 100644 --- a/src/apps/settings/i18n/translations/uz.yml +++ b/src/apps/settings/i18n/translations/uz.yml @@ -1,195 +1,195 @@ -sides: - top: Eng yuqori - right: To'g'ri - bottom: Pastki - left: Chapda -header: - labels: - info: Ma `lumot - seelen_wm: Oyna menejeri - seelen_bar: Fashion asboblar paneli - monitors: Monitorlar - developer: Ishlab chiqaruvchi - general: Umumiy - specific_apps: Muayyan ilovalar - shortcuts: Yorliqlar - seelen_weg: Dok / vazifalar paneli -start: - message_accent: O'zingizning mahsuldorligingizni uslub bilan optimallashtiring! - message: >- - Windows 11 tajribangizni oshirish uchun "Windows" bosh murabbiyi bo'lgan - Windows menejeriga ega Seelen UI-ga xush kelibsiz! Bizning intuitiv - interfeysimiz va rivojlangan xususiyatlarimiz bilan samaradorlik va ko'p - bosqichli yangi davrni o'rganing. - title: Xush kelibsiz! -general: - theme: - description: Tavsif - placeholder: Mavzuni tanlang - label: Mavzu haqida ma'lumot - enabled: Mavzular yoqilgan - added: Mavzu allaqachon qo'shilgan - author: Muallif - add: Mavzuni qo'shing - tags: Teglar - available: Mavjud - selected: Tanlangan - language: Til - startup: Ishga tushirishda ishlaydimi? - icon_pack: - label: Ikonka paketlari - accent_color: Urg'u rangi -toolbar: - placeholder: - description: Tavsif - select: Asboblar paneli tuzilishi - author: Muallif - enable: Fashr asboblar panelini yoqing - height: Balandlik -wm: - border: - width: Chegara kengligi - offset: Chegara ofset - enable: Oynaning chegarasini yoqing - description: Tavsif - enable: Oyna boshqaruvchisini yoqish - disabled_windows10: Windows 10 uchun deraza menejeri mavjud emas. - space_between_containers: Idishlar orasidagi bo'shliq - workspace_offset: Ishxonalar ofset (marjalar) - author: Muallif - layout: Tartib - resize_delta: Delta (%) ni o'zgartiring - workspace_padding: Ish plakding -weg: - items: - gap: Buyumlar orasidagi bo'shliq - zoom_size: Zomed o'lchami (mavzular uchun ishlatiladi) - label: Narsalar - size: Element hajmi - visible_separators: Ko'rinadigan ajratuvchi - label: Dok / vazifalar paneli - padding: Plomba - dock_side: Dok - width: Kenglik - auto_hide: Avtomatik yashirish - enable: Dock / vazifalar panelini yoqing - gap: Bo'shliq - margin: Marja -devtools: - install_folder: O'rnatish papkasini o'rnatish - enable: Ishlab chiqaruvchi vositalarni yoqish - app_folders: Ilova papkalari - custom_config_file: Custom Config faylini yuklang - data_folder: Ma'lumotlar papkasi - settings_file: Sozlamalar fayli - load: Yuklamoq -apps_configurations: - app: - options: - force: Kuchni boshqarish - pinned: Zebo - float: Suzmoq - unmanage: Ishtiyoq - options_label: Qo'shimcha variantlar - ok_readonly: Yangi sifatida tahrirlash - title_readonly: Ko'rish {{ism}} - title_create: '{{Ism}} yaratish' - monitor: Monitor - bindings: Bog'lash (eslatma ikkalasi ham talab qilinadi) - monitor_placeholder: Hech biri - category_placeholder: Hech biri - name: Ism - workspace: Ish maydoni - workspace_placeholder: Hech biri - category: Tili - ok_create: Yaratmoq - ok_edit: Yangilamoq - title_edit: '{{Ism}} tahrirlash' - identifier: - add_block: Blokni qo'shish - remove: Blokni o'chirish - matching_strategy: Mos keladigan strategiya - negation: Mos kelmaslik - id: Identifikator - or: Yoki - kind: Aniqlang - and: Va - search: Qidirmoq - import: Import - confirm_delete: Ushbu konfiguratsiyani o'chirishni xohlayotganingizga ishonchingiz komilmi? - confirm_delete_title: O'chirishni tasdiqlang - bundled_msg: >- - Ushbu yig'ilgan konfiguratsiyalar tahrirlanmaydi va sizga eng yaxshi - tajribani taqdim etishsiz taqdim etish uchun mo'ljallangan. Ular avtomatik - ravishda siz uchun eng keng tarqalgan dasturlarni sozlaydi. - bundled_title: Dastur konfigurasi Seelen bilan bog'langan - export: Eksport - new: Yangi - delete: O'chirmoq - swap: Almashmoq -extras: - exit: Chiqish / chiqish - links: Rasmiy havolalar - github: Gitul - discord: Kelishmovchilik - version: Versiya - relaunch: Qolma -shortcuts: - labels: - send_to_workspace_1: Ish maydoni 1-ga yuboring - decrease_height: Balandlikni kamaytirish - increase_height: Balandlikni oshirish - switch_workspace_7: Ish maydoni 7-ga o'ting - move_to_workspace_5: Ish maydoni 5 ga o'ting 5 - switch_workspace_0: Ish maydoni 0 ga o'ting - switch_workspace_6: Ish maydoni 6 ga o'tish - reserve_bottom: Zaxira pastki - move_to_workspace_1: Ish maydoni 1 ga o'ting 1 - move_to_workspace_6: Ish maydoni 6-ga o'ting - focus_right: Joylashtirish - move_to_workspace_8: Ish maydoni 8 ga o'ting 8 - decrease_width: Kenglikni kamaytirish - send_to_workspace_7: Ish maydoni 7-ga yuboring - move_to_workspace_0: Ish maydoni 0 ga o'ting - reserve_top: Zaxira tepasi - send_to_workspace_9: Ish maydoni 9-ga yuboring - switch_workspace_8: Ish maydoni 8 ga o'tish - move_to_workspace_3: Ish maydoni 3 ga o'ting - reserve_right: Qo'riqxona - increase_width: Kenglikni oshirish - reserve_stack: Zaxira to'plami - switch_workspace_9: Ish maydoni 9 ga o'tish 9 - focus_latest: Eng so'nggi - move_to_workspace_2: Ish maydoni 2-ga o'ting - focus_left: Fince chap - move_to_workspace_9: Ish maydoniga o'tish 9 - switch_workspace_3: Ish maydoni 3 ga o'tish - restore_sizes: O'lchamlarini tiklash - send_to_workspace_5: Ish maydoni 5-ga yuboring 5 - focus_top: Face Top - move_to_workspace_4: Ish maydoni 4-ga o'ting - send_to_workspace_4: Ish maydoni 4-ga yuboring - send_to_workspace_8: Ish maydoni 8-ga yuboring - switch_workspace_2: Ish maydoni 2-ga o'ting - focus_bottom: Fokus suvi - reserve_float: Suzmoq - send_to_workspace_2: Ish maydoni 2-ga yuboring - switch_workspace_5: Ish maydoni 5 ga o'tish - reserve_left: Zaxira chap - send_to_workspace_6: Ish maydoni 6-ga yuboring - move_to_workspace_7: Ish maydoni 7-ga o'ting - switch_workspace_4: Ish maydoni 4-ga o'ting - switch_workspace_1: Ish maydoni 1 ga o'tish - send_to_workspace_3: Ish maydoni 3-ga yuboring - send_to_workspace_0: Ish maydoni 0 ga yuboring - enable: Birlashtirilgan yorliqlarni yoqish (AHK) - enable_tooltip: >- - Agar siz Seelen Core API yordamida o'z yorlig'ingizni amalga oshirsangiz, - o'chiring -inProgress: Jarayonda... -open: Ochiq -save: Tejash -loading: Yuklash ... -cancel: Bekor qilmoq -delete: O'chirmoq -quit: Ketmoq +sides: + top: Eng yuqori + right: To'g'ri + bottom: Pastki + left: Chapda +header: + labels: + info: Ma `lumot + seelen_wm: Oyna menejeri + seelen_bar: Fashion asboblar paneli + monitors: Monitorlar + developer: Ishlab chiqaruvchi + general: Umumiy + specific_apps: Muayyan ilovalar + shortcuts: Yorliqlar + seelen_weg: Dok / vazifalar paneli +start: + message_accent: O'zingizning mahsuldorligingizni uslub bilan optimallashtiring! + message: >- + Windows 11 tajribangizni oshirish uchun "Windows" bosh murabbiyi bo'lgan + Windows menejeriga ega Seelen UI-ga xush kelibsiz! Bizning intuitiv + interfeysimiz va rivojlangan xususiyatlarimiz bilan samaradorlik va ko'p + bosqichli yangi davrni o'rganing. + title: Xush kelibsiz! +general: + theme: + description: Tavsif + placeholder: Mavzuni tanlang + label: Mavzu haqida ma'lumot + enabled: Mavzular yoqilgan + added: Mavzu allaqachon qo'shilgan + author: Muallif + add: Mavzuni qo'shing + tags: Teglar + available: Mavjud + selected: Tanlangan + language: Til + startup: Ishga tushirishda ishlaydimi? + icon_pack: + label: Ikonka paketlari + accent_color: Urg'u rangi +toolbar: + placeholder: + description: Tavsif + select: Asboblar paneli tuzilishi + author: Muallif + enable: Fashr asboblar panelini yoqing + height: Balandlik +wm: + border: + width: Chegara kengligi + offset: Chegara ofset + enable: Oynaning chegarasini yoqing + description: Tavsif + enable: Oyna boshqaruvchisini yoqish + disabled_windows10: Windows 10 uchun deraza menejeri mavjud emas. + space_between_containers: Idishlar orasidagi bo'shliq + workspace_offset: Ishxonalar ofset (marjalar) + author: Muallif + layout: Tartib + resize_delta: Delta (%) ni o'zgartiring + workspace_padding: Ish plakding +weg: + items: + gap: Buyumlar orasidagi bo'shliq + zoom_size: Zomed o'lchami (mavzular uchun ishlatiladi) + label: Narsalar + size: Element hajmi + visible_separators: Ko'rinadigan ajratuvchi + label: Dok / vazifalar paneli + padding: Plomba + dock_side: Dok + width: Kenglik + auto_hide: Avtomatik yashirish + enable: Dock / vazifalar panelini yoqing + gap: Bo'shliq + margin: Marja +devtools: + install_folder: O'rnatish papkasini o'rnatish + enable: Ishlab chiqaruvchi vositalarni yoqish + app_folders: Ilova papkalari + custom_config_file: Custom Config faylini yuklang + data_folder: Ma'lumotlar papkasi + settings_file: Sozlamalar fayli + load: Yuklamoq +apps_configurations: + app: + options: + force: Kuchni boshqarish + pinned: Zebo + float: Suzmoq + unmanage: Ishtiyoq + options_label: Qo'shimcha variantlar + ok_readonly: Yangi sifatida tahrirlash + title_readonly: Ko'rish {{ism}} + title_create: '{{Ism}} yaratish' + monitor: Monitor + bindings: Bog'lash (eslatma ikkalasi ham talab qilinadi) + monitor_placeholder: Hech biri + category_placeholder: Hech biri + name: Ism + workspace: Ish maydoni + workspace_placeholder: Hech biri + category: Tili + ok_create: Yaratmoq + ok_edit: Yangilamoq + title_edit: '{{Ism}} tahrirlash' + identifier: + add_block: Blokni qo'shish + remove: Blokni o'chirish + matching_strategy: Mos keladigan strategiya + negation: Mos kelmaslik + id: Identifikator + or: Yoki + kind: Aniqlang + and: Va + search: Qidirmoq + import: Import + confirm_delete: Ushbu konfiguratsiyani o'chirishni xohlayotganingizga ishonchingiz komilmi? + confirm_delete_title: O'chirishni tasdiqlang + bundled_msg: >- + Ushbu yig'ilgan konfiguratsiyalar tahrirlanmaydi va sizga eng yaxshi + tajribani taqdim etishsiz taqdim etish uchun mo'ljallangan. Ular avtomatik + ravishda siz uchun eng keng tarqalgan dasturlarni sozlaydi. + bundled_title: Dastur konfigurasi Seelen bilan bog'langan + export: Eksport + new: Yangi + delete: O'chirmoq + swap: Almashmoq +extras: + exit: Chiqish / chiqish + links: Rasmiy havolalar + github: Gitul + discord: Kelishmovchilik + version: Versiya + relaunch: Qolma +shortcuts: + labels: + send_to_workspace_1: Ish maydoni 1-ga yuboring + decrease_height: Balandlikni kamaytirish + increase_height: Balandlikni oshirish + switch_workspace_7: Ish maydoni 7-ga o'ting + move_to_workspace_5: Ish maydoni 5 ga o'ting 5 + switch_workspace_0: Ish maydoni 0 ga o'ting + switch_workspace_6: Ish maydoni 6 ga o'tish + reserve_bottom: Zaxira pastki + move_to_workspace_1: Ish maydoni 1 ga o'ting 1 + move_to_workspace_6: Ish maydoni 6-ga o'ting + focus_right: Joylashtirish + move_to_workspace_8: Ish maydoni 8 ga o'ting 8 + decrease_width: Kenglikni kamaytirish + send_to_workspace_7: Ish maydoni 7-ga yuboring + move_to_workspace_0: Ish maydoni 0 ga o'ting + reserve_top: Zaxira tepasi + send_to_workspace_9: Ish maydoni 9-ga yuboring + switch_workspace_8: Ish maydoni 8 ga o'tish + move_to_workspace_3: Ish maydoni 3 ga o'ting + reserve_right: Qo'riqxona + increase_width: Kenglikni oshirish + reserve_stack: Zaxira to'plami + switch_workspace_9: Ish maydoni 9 ga o'tish 9 + focus_latest: Eng so'nggi + move_to_workspace_2: Ish maydoni 2-ga o'ting + focus_left: Fince chap + move_to_workspace_9: Ish maydoniga o'tish 9 + switch_workspace_3: Ish maydoni 3 ga o'tish + restore_sizes: O'lchamlarini tiklash + send_to_workspace_5: Ish maydoni 5-ga yuboring 5 + focus_top: Face Top + move_to_workspace_4: Ish maydoni 4-ga o'ting + send_to_workspace_4: Ish maydoni 4-ga yuboring + send_to_workspace_8: Ish maydoni 8-ga yuboring + switch_workspace_2: Ish maydoni 2-ga o'ting + focus_bottom: Fokus suvi + reserve_float: Suzmoq + send_to_workspace_2: Ish maydoni 2-ga yuboring + switch_workspace_5: Ish maydoni 5 ga o'tish + reserve_left: Zaxira chap + send_to_workspace_6: Ish maydoni 6-ga yuboring + move_to_workspace_7: Ish maydoni 7-ga o'ting + switch_workspace_4: Ish maydoni 4-ga o'ting + switch_workspace_1: Ish maydoni 1 ga o'tish + send_to_workspace_3: Ish maydoni 3-ga yuboring + send_to_workspace_0: Ish maydoni 0 ga yuboring + enable: Birlashtirilgan yorliqlarni yoqish (AHK) + enable_tooltip: >- + Agar siz Seelen Core API yordamida o'z yorlig'ingizni amalga oshirsangiz, + o'chiring +inProgress: Jarayonda... +open: Ochiq +save: Tejash +loading: Yuklash ... +cancel: Bekor qilmoq +delete: O'chirmoq +quit: Ketmoq diff --git a/src/apps/settings/i18n/translations/vi.yml b/src/apps/settings/i18n/translations/vi.yml index 23892e7a..c5b99619 100644 --- a/src/apps/settings/i18n/translations/vi.yml +++ b/src/apps/settings/i18n/translations/vi.yml @@ -1,193 +1,193 @@ -sides: - right: Phải - top: Đứng đầu - bottom: Đáy - left: Bên trái -header: - labels: - info: Thông tin - seelen_bar: Thanh công cụ ưa thích - general: Tổng quan - developer: Nhà phát triển - specific_apps: Ứng dụng cụ thể - monitors: Màn hình - seelen_weg: Dock/Thanh tác vụ - seelen_wm: Quản lý cửa sổ - shortcuts: Phím tắt -start: - message: >- - Chào mừng bạn đến Seelen UI, môi trường máy tính để bàn cuối cùng với Trình - quản lý Windows được kết hợp để nâng cao trải nghiệm Windows 11 của bạn! - Khám phá một kỷ nguyên mới của hiệu quả và đa nhiệm với giao diện trực quan - và các tính năng nâng cao của chúng tôi. - message_accent: Tối ưu hóa năng suất của bạn với phong cách! - title: Chào mừng! -general: - theme: - description: Sự miêu tả - placeholder: Chọn chủ đề - author: Tác giả - add: Thêm chủ đề - added: Chủ đề đã được thêm vào - label: Thông tin chủ đề - tags: Tags - enabled: Cho phép các chủ đề - selected: Đã chọn - available: Có sẵn - startup: Chạy khi khởi động? - language: Ngôn ngữ - icon_pack: - label: Gói biểu tượng - accent_color: Màu nhấn -toolbar: - placeholder: - author: Tác giả - description: Sự miêu tả - select: Cấu trúc thanh công cụ - height: Chiều cao - enable: Kích hoạt thanh công cụ ưa thích -wm: - border: - width: Chiều rộng biên giới - offset: Biên giới bù đắp - enable: Bật biên giới của cửa sổ - description: Sự miêu tả - author: Tác giả - layout: Cách trình bày - enable: Bật trình quản lý cửa sổ - resize_delta: Thay đổi kích thước delta (%) - space_between_containers: Không gian giữa các container - workspace_padding: Không gian làm việc đệm - disabled_windows10: Trình quản lý cửa sổ không có sẵn cho Windows 10. - workspace_offset: Không gian làm việc bù (lề) -weg: - items: - size: Kích thước mục - label: Mặt hàng - zoom_size: Kích thước phóng to (được sử dụng cho chủ đề) - gap: Không gian giữa các mặt hàng - visible_separators: Phân tách có thể nhìn thấy - width: Chiều rộng - margin: Lề - gap: Khoảng cách - enable: Bật Dock/Thanh tác vụ - padding: Đệm - label: Dock/Thanh tác vụ - dock_side: Phía bến tàu - auto_hide: Tự động ẩn -devtools: - load: Trọng tải - app_folders: Thư mục ứng dụng - install_folder: Thư mục cài đặt - custom_config_file: Tải tệp cấu hình tùy chỉnh - settings_file: Cài đặt tập tin - data_folder: Thư mục dữ liệu - enable: Kích hoạt các công cụ nhà phát triển -apps_configurations: - app: - options: - float: Trôi nổi - force: Quản lý lực lượng - pinned: Ghim - unmanage: Không quản lý - category_placeholder: Không có - category: Loại - ok_edit: Cập nhật - monitor_placeholder: Không có - name: Tên - workspace_placeholder: Không có - ok_create: Tạo nên - title_edit: Chỉnh sửa {{name}} - bindings: Binding (Lưu ý cả hai tùy chọn đều được yêu cầu) - monitor: Màn hình - title_readonly: Xem {{name}} - options_label: Tùy chọn bổ sung - workspace: Không gian làm việc - ok_readonly: Chỉnh sửa như mới - title_create: Tạo {{name}} - identifier: - and: VÀ - or: HOẶC - negation: Phủ nhận sự phù hợp - id: Định danh - remove: Xóa khối - matching_strategy: Chiến lược phù hợp - kind: Xác định bởi - add_block: Thêm khối - export: Xuất khẩu - delete: Xóa bỏ - search: Tìm kiếm - swap: Tráo đổi - new: Mới - import: Nhập khẩu - bundled_title: Ứng dụng Cấu hình đi kèm với Seelen - confirm_delete: Bạn có chắc bạn muốn xóa cấu hình/s này không? - confirm_delete_title: Xác nhận xóa - bundled_msg: >- - Các cấu hình đi kèm này không thể chỉnh sửa và được thiết kế để cung cấp cho - bạn trải nghiệm tốt nhất mà không cần tùy chỉnh. Chúng tự động định cấu hình - các ứng dụng phổ biến nhất cho bạn. -extras: - version: Phiên bản - discord: Bất hòa - links: Liên kết chính thức - exit: Thoát/Thoát - github: GitHub - relaunch: Khởi động lại -shortcuts: - labels: - move_to_workspace_4: Di chuyển đến không gian làm việc 4 - focus_right: Tập trung đúng - switch_workspace_4: Chuyển sang không gian làm việc 4 - send_to_workspace_5: Gửi đến không gian làm việc 5 - send_to_workspace_8: Gửi đến không gian làm việc 8 - reserve_right: Đặt trước đúng - send_to_workspace_9: Gửi đến không gian làm việc 9 - reserve_top: Dự trữ hàng đầu - focus_bottom: Focus bottom - switch_workspace_1: Chuyển sang không gian làm việc 1 - switch_workspace_0: Chuyển sang không gian làm việc 0 - reserve_stack: Ngân hàng dự trữ - switch_workspace_3: Chuyển sang không gian làm việc 3 - increase_height: Tăng chiều cao - move_to_workspace_7: Di chuyển đến không gian làm việc 7 - focus_top: Tập trung hàng đầu - move_to_workspace_6: Di chuyển đến không gian làm việc 6 - move_to_workspace_5: Di chuyển đến không gian làm việc 5 - focus_latest: Tập trung mới nhất - send_to_workspace_6: Gửi đến không gian làm việc 6 - send_to_workspace_3: Gửi đến không gian làm việc 3 - switch_workspace_6: Chuyển sang không gian làm việc 6 - reserve_float: Dự trữ nổi - switch_workspace_2: Chuyển sang không gian làm việc 2 - move_to_workspace_2: Di chuyển đến không gian làm việc 2 - decrease_width: Giảm chiều rộng - send_to_workspace_4: Gửi đến không gian làm việc 4 - increase_width: Tăng chiều rộng - switch_workspace_7: Chuyển sang không gian làm việc 7 - move_to_workspace_1: Di chuyển đến không gian làm việc 1 - switch_workspace_8: Chuyển sang không gian làm việc 8 - decrease_height: Giảm chiều cao - move_to_workspace_3: Di chuyển đến không gian làm việc 3 - move_to_workspace_0: Di chuyển đến không gian làm việc 0 - switch_workspace_5: Chuyển sang không gian làm việc 5 - switch_workspace_9: Chuyển sang không gian làm việc 9 - restore_sizes: Khôi phục kích thước - reserve_bottom: Dự trữ đáy - send_to_workspace_1: Gửi đến không gian làm việc 1 - move_to_workspace_8: Di chuyển đến không gian làm việc 8 - move_to_workspace_9: Di chuyển đến không gian làm việc 9 - send_to_workspace_0: Gửi đến không gian làm việc 0 - send_to_workspace_2: Gửi đến Workspace 2 - reserve_left: Dự trữ trái - send_to_workspace_7: Gửi đến không gian làm việc 7 - focus_left: Tập trung trái - enable: Bật các phím tắt tích hợp (AHK) - enable_tooltip: Tắt nếu bạn sẽ triển khai các phím tắt của riêng mình bằng API SEELEN Core -loading: Đang tải... -open: Mở -quit: Từ bỏ -delete: Xóa bỏ -inProgress: Trong tiến trình... -save: Cứu -cancel: Hủy bỏ +sides: + right: Phải + top: Đứng đầu + bottom: Đáy + left: Bên trái +header: + labels: + info: Thông tin + seelen_bar: Thanh công cụ ưa thích + general: Tổng quan + developer: Nhà phát triển + specific_apps: Ứng dụng cụ thể + monitors: Màn hình + seelen_weg: Dock/Thanh tác vụ + seelen_wm: Quản lý cửa sổ + shortcuts: Phím tắt +start: + message: >- + Chào mừng bạn đến Seelen UI, môi trường máy tính để bàn cuối cùng với Trình + quản lý Windows được kết hợp để nâng cao trải nghiệm Windows 11 của bạn! + Khám phá một kỷ nguyên mới của hiệu quả và đa nhiệm với giao diện trực quan + và các tính năng nâng cao của chúng tôi. + message_accent: Tối ưu hóa năng suất của bạn với phong cách! + title: Chào mừng! +general: + theme: + description: Sự miêu tả + placeholder: Chọn chủ đề + author: Tác giả + add: Thêm chủ đề + added: Chủ đề đã được thêm vào + label: Thông tin chủ đề + tags: Tags + enabled: Cho phép các chủ đề + selected: Đã chọn + available: Có sẵn + startup: Chạy khi khởi động? + language: Ngôn ngữ + icon_pack: + label: Gói biểu tượng + accent_color: Màu nhấn +toolbar: + placeholder: + author: Tác giả + description: Sự miêu tả + select: Cấu trúc thanh công cụ + height: Chiều cao + enable: Kích hoạt thanh công cụ ưa thích +wm: + border: + width: Chiều rộng biên giới + offset: Biên giới bù đắp + enable: Bật biên giới của cửa sổ + description: Sự miêu tả + author: Tác giả + layout: Cách trình bày + enable: Bật trình quản lý cửa sổ + resize_delta: Thay đổi kích thước delta (%) + space_between_containers: Không gian giữa các container + workspace_padding: Không gian làm việc đệm + disabled_windows10: Trình quản lý cửa sổ không có sẵn cho Windows 10. + workspace_offset: Không gian làm việc bù (lề) +weg: + items: + size: Kích thước mục + label: Mặt hàng + zoom_size: Kích thước phóng to (được sử dụng cho chủ đề) + gap: Không gian giữa các mặt hàng + visible_separators: Phân tách có thể nhìn thấy + width: Chiều rộng + margin: Lề + gap: Khoảng cách + enable: Bật Dock/Thanh tác vụ + padding: Đệm + label: Dock/Thanh tác vụ + dock_side: Phía bến tàu + auto_hide: Tự động ẩn +devtools: + load: Trọng tải + app_folders: Thư mục ứng dụng + install_folder: Thư mục cài đặt + custom_config_file: Tải tệp cấu hình tùy chỉnh + settings_file: Cài đặt tập tin + data_folder: Thư mục dữ liệu + enable: Kích hoạt các công cụ nhà phát triển +apps_configurations: + app: + options: + float: Trôi nổi + force: Quản lý lực lượng + pinned: Ghim + unmanage: Không quản lý + category_placeholder: Không có + category: Loại + ok_edit: Cập nhật + monitor_placeholder: Không có + name: Tên + workspace_placeholder: Không có + ok_create: Tạo nên + title_edit: Chỉnh sửa {{name}} + bindings: Binding (Lưu ý cả hai tùy chọn đều được yêu cầu) + monitor: Màn hình + title_readonly: Xem {{name}} + options_label: Tùy chọn bổ sung + workspace: Không gian làm việc + ok_readonly: Chỉnh sửa như mới + title_create: Tạo {{name}} + identifier: + and: VÀ + or: HOẶC + negation: Phủ nhận sự phù hợp + id: Định danh + remove: Xóa khối + matching_strategy: Chiến lược phù hợp + kind: Xác định bởi + add_block: Thêm khối + export: Xuất khẩu + delete: Xóa bỏ + search: Tìm kiếm + swap: Tráo đổi + new: Mới + import: Nhập khẩu + bundled_title: Ứng dụng Cấu hình đi kèm với Seelen + confirm_delete: Bạn có chắc bạn muốn xóa cấu hình/s này không? + confirm_delete_title: Xác nhận xóa + bundled_msg: >- + Các cấu hình đi kèm này không thể chỉnh sửa và được thiết kế để cung cấp cho + bạn trải nghiệm tốt nhất mà không cần tùy chỉnh. Chúng tự động định cấu hình + các ứng dụng phổ biến nhất cho bạn. +extras: + version: Phiên bản + discord: Bất hòa + links: Liên kết chính thức + exit: Thoát/Thoát + github: GitHub + relaunch: Khởi động lại +shortcuts: + labels: + move_to_workspace_4: Di chuyển đến không gian làm việc 4 + focus_right: Tập trung đúng + switch_workspace_4: Chuyển sang không gian làm việc 4 + send_to_workspace_5: Gửi đến không gian làm việc 5 + send_to_workspace_8: Gửi đến không gian làm việc 8 + reserve_right: Đặt trước đúng + send_to_workspace_9: Gửi đến không gian làm việc 9 + reserve_top: Dự trữ hàng đầu + focus_bottom: Focus bottom + switch_workspace_1: Chuyển sang không gian làm việc 1 + switch_workspace_0: Chuyển sang không gian làm việc 0 + reserve_stack: Ngân hàng dự trữ + switch_workspace_3: Chuyển sang không gian làm việc 3 + increase_height: Tăng chiều cao + move_to_workspace_7: Di chuyển đến không gian làm việc 7 + focus_top: Tập trung hàng đầu + move_to_workspace_6: Di chuyển đến không gian làm việc 6 + move_to_workspace_5: Di chuyển đến không gian làm việc 5 + focus_latest: Tập trung mới nhất + send_to_workspace_6: Gửi đến không gian làm việc 6 + send_to_workspace_3: Gửi đến không gian làm việc 3 + switch_workspace_6: Chuyển sang không gian làm việc 6 + reserve_float: Dự trữ nổi + switch_workspace_2: Chuyển sang không gian làm việc 2 + move_to_workspace_2: Di chuyển đến không gian làm việc 2 + decrease_width: Giảm chiều rộng + send_to_workspace_4: Gửi đến không gian làm việc 4 + increase_width: Tăng chiều rộng + switch_workspace_7: Chuyển sang không gian làm việc 7 + move_to_workspace_1: Di chuyển đến không gian làm việc 1 + switch_workspace_8: Chuyển sang không gian làm việc 8 + decrease_height: Giảm chiều cao + move_to_workspace_3: Di chuyển đến không gian làm việc 3 + move_to_workspace_0: Di chuyển đến không gian làm việc 0 + switch_workspace_5: Chuyển sang không gian làm việc 5 + switch_workspace_9: Chuyển sang không gian làm việc 9 + restore_sizes: Khôi phục kích thước + reserve_bottom: Dự trữ đáy + send_to_workspace_1: Gửi đến không gian làm việc 1 + move_to_workspace_8: Di chuyển đến không gian làm việc 8 + move_to_workspace_9: Di chuyển đến không gian làm việc 9 + send_to_workspace_0: Gửi đến không gian làm việc 0 + send_to_workspace_2: Gửi đến Workspace 2 + reserve_left: Dự trữ trái + send_to_workspace_7: Gửi đến không gian làm việc 7 + focus_left: Tập trung trái + enable: Bật các phím tắt tích hợp (AHK) + enable_tooltip: Tắt nếu bạn sẽ triển khai các phím tắt của riêng mình bằng API SEELEN Core +loading: Đang tải... +open: Mở +quit: Từ bỏ +delete: Xóa bỏ +inProgress: Trong tiến trình... +save: Cứu +cancel: Hủy bỏ diff --git a/src/apps/settings/i18n/translations/yo.yml b/src/apps/settings/i18n/translations/yo.yml index 53a9a412..c6d84b92 100644 --- a/src/apps/settings/i18n/translations/yo.yml +++ b/src/apps/settings/i18n/translations/yo.yml @@ -1,191 +1,191 @@ -sides: - bottom: Isalẹ - left: Osi - top: Oke - right: Titọ -header: - labels: - seelen_wm: Oluṣakoso window - info: Alaye - seelen_weg: Dock / forkbar - seelen_bar: Ọpa irinṣẹ Fancy - general: Gbogboogbo - developer: Olugbekun - monitors: Awọn diirarito - shortcuts: Awọn ọna abuja - specific_apps: Apps Pataki -start: - message_accent: Njẹ iṣelọpọ rẹ pẹlu aṣa! - message: >- - Kaabọ si Sielen UI, agbegbe tabili ti o gaju pẹlu ipilẹ Windows Manager lati - jẹki iriri Windows rẹ! Ṣawari akoko ti o ni ṣiṣe ati multitasking pẹlu wa - ati awọn ẹya ti ilọsiwaju. - title: Kaabọ! -general: - theme: - added: Akori ti ṣafikun tẹlẹ - enabled: Mu awọn akori ṣiṣẹ - label: Alaye Akori - description: Isapejuwe - placeholder: Yan Akori - tags: Afi ami - add: Fi ọran kun - author: Onkọwe ọkunrin - selected: Ti yan - available: Wa - startup: Ṣiṣe lori ibẹrẹ? - language: Ede - icon_pack: - label: Awọn akopọ aami - accent_color: Awọ ara -toolbar: - placeholder: - author: Onkọwe ọkunrin - select: Ọpa irinṣẹ - description: Isapejuwe - height: Giga - enable: Mu ṣiṣẹ irinṣẹ irinṣẹ Fancy ṣiṣẹ -wm: - border: - enable: Jeki aala window - width: Iwọn aala - offset: Iparun aala - enable: Jeki oluṣakoso window - resize_delta: Tun ṣe Delta (%) - disabled_windows10: Oluṣakoso window ko wa fun Windows 10. - layout: Agbekalẹ - description: Isapejuwe - space_between_containers: Aaye laarin awọn apoti - workspace_offset: Awọn iṣẹ Iṣẹ-iṣẹ (awọn ala) - author: Onkọwe ọkunrin - workspace_padding: Awọn iṣẹ itasi -weg: - items: - visible_separators: Awọn iyatọ ti o han - gap: Aaye laarin awọn ohun kan - size: Iwọn nkan - zoom_size: Iwọn sisun (ti a lo fun awọn akori) - label: Awọn ohun - width: Fifẹ - gap: Alafo - label: Dock / forkbar - enable: Muu dock / forkbar - dock_side: Ẹgbẹ dock - auto_hide: Ibi ipamọ aifọwọyi - margin: Ẹlẹsin - padding: Fidigọdi silẹ -devtools: - app_folders: Awọn folda App - install_folder: Filese Fifi sori ẹrọ - enable: Mu awọn irinṣẹ Oláàmúdà ṣiṣẹ - custom_config_file: Fifuye faili atunto aṣa - settings_file: Faili eto - data_folder: Folda data - load: Ẹru -apps_configurations: - app: - options: - unmanage: Aileyẹ - float: Leke - force: Ṣakoso ṣakoso - pinned: Pin - name: Orukọ - category_placeholder: Ko si - title_readonly: Wiwo {{Orukọ}} - bindings: Dide (Ṣe akiyesi awọn aṣayan mejeeji ni a nilo) - options_label: Awọn aṣayan afikun - workspace_placeholder: Ko si - title_create: Ṣiṣẹda {Orukọ}} - monitor_placeholder: Ko si - category: Ẹya - workspace: Ibi-iṣẹ - title_edit: Ṣiṣatunṣe {{Orukọ}} - ok_create: Lati ṣẹda - ok_readonly: Satunkọ bi tuntun - ok_edit: Imudojuiwọn - monitor: Aṣabojuto - identifier: - negation: Ibaramu tuntun - add_block: Fi dègbé - kind: Ṣe idanimọ nipasẹ - id: Idamo - and: Ati - or: Tabi - matching_strategy: Ibaamu iṣiro - remove: Paarẹ Brow - confirm_delete: Ṣe o da ọ loju pe o fẹ lati pa iṣeto rẹ / s? - delete: Paarẹ - new: Tuntun - confirm_delete_title: Jẹrisi paarẹ - search: Ṣewadii - bundled_title: Ohun elo app ṣepọ pẹlu Selen - swap: Eepo - export: Firanṣẹ si ilẹ okeere - bundled_msg: >- - Awọn atunto ti a dapọ mọ ko ṣe deede ati pe a ṣe apẹrẹ lati fun ọ ni iriri - ti o dara julọ laisi isọdi. Wọn tunto awọn ohun elo ti o wọpọ julọ fun ọ. - import: Aṣagbewọle lati ilẹ okeere -extras: - discord: Di eniyan - github: Gitter - relaunch: Ṣadi - version: Ẹya - links: Awọn ọna asopọ osise - exit: Duro / Jade -shortcuts: - labels: - focus_right: Dojukọ ọtun - increase_width: Gbooro - reserve_right: Reserve ọtun - switch_workspace_3: Yipada si ibi-iṣẹ 3 - switch_workspace_6: Yipada si ibi-iṣẹ 6 - focus_latest: Idojukọ - focus_top: Dojukọ oke - switch_workspace_8: Yipada si ibi-iṣẹ 8 - decrease_height: Dinku iga - reserve_bottom: Isalẹ ifipamọ - send_to_workspace_3: Firanṣẹ si ibi-iṣẹ 3 - send_to_workspace_8: Firanṣẹ si ibi-iṣẹ 8 - send_to_workspace_1: Firanṣẹ si ibi-iṣẹ 1 - move_to_workspace_5: Gbe si ibi-iṣẹ 5 - increase_height: Igasoke giga - move_to_workspace_9: Gbe si ibi-ipa 9 - send_to_workspace_2: Firanṣẹ si ibi-iṣẹ 2 - focus_left: Idojukọ osi - move_to_workspace_3: Gbe si ibi-iṣẹ 3 - reserve_float: Dase leefofo loju omi - switch_workspace_1: Yipada si ibi-iṣẹ 1 - switch_workspace_9: Yipada si ibi-iṣẹ 9 - switch_workspace_2: Yipada si ibi-iṣẹ 2 - move_to_workspace_0: Gbe si ibi-iṣẹ 0 - move_to_workspace_2: Gbe si ibi-iṣẹ 2 - switch_workspace_5: Yipada si ibi-iṣẹ 5 - switch_workspace_4: Yipada si ibi-iṣẹ 4 - send_to_workspace_6: Firanṣẹ si ibi-iṣẹ 6 - send_to_workspace_7: Firanṣẹ si ibi-iṣẹ 7 - reserve_stack: Ipilẹ akopọ - switch_workspace_0: Yipada si ibi-iṣẹ 0 - send_to_workspace_9: Firanṣẹ si ibi-iṣẹ 9 - move_to_workspace_4: Gbe si ibi-iṣẹ 4 - move_to_workspace_8: Gbe si ibi-iṣẹ 8 - move_to_workspace_1: Gbe si Accepace 1 - move_to_workspace_7: Gbe si ibi-iṣẹ 7 - send_to_workspace_0: Firanṣẹ si ibi-iṣẹ 0 - send_to_workspace_5: Firanṣẹ si Ibi-iṣẹ 5 - decrease_width: DIVEELE WA - reserve_top: Reserve oke - restore_sizes: Pada awọn titobi - switch_workspace_7: Yipada si ibi-iṣẹ 7 - move_to_workspace_6: Gbe si ibi-iṣẹ 6 - focus_bottom: Idojukọ Idojukọ - send_to_workspace_4: Firanṣẹ si ibi-iṣẹ 4 - reserve_left: Reserve osi - enable: Mu awọn ọna abuja ti o sopọ mọ (Ahk) - enable_tooltip: Muu Ti o ba yoo ṣe awọn ọna abuja tirẹ nipa lilo APEN mojuto API -delete: Paarẹ -cancel: Fagilee -save: Fipamọ -loading: Loading ... -inProgress: Ni ilọsiwaju ... -quit: Lọ kuro -open: Ṣii +sides: + bottom: Isalẹ + left: Osi + top: Oke + right: Titọ +header: + labels: + seelen_wm: Oluṣakoso window + info: Alaye + seelen_weg: Dock / forkbar + seelen_bar: Ọpa irinṣẹ Fancy + general: Gbogboogbo + developer: Olugbekun + monitors: Awọn diirarito + shortcuts: Awọn ọna abuja + specific_apps: Apps Pataki +start: + message_accent: Njẹ iṣelọpọ rẹ pẹlu aṣa! + message: >- + Kaabọ si Sielen UI, agbegbe tabili ti o gaju pẹlu ipilẹ Windows Manager lati + jẹki iriri Windows rẹ! Ṣawari akoko ti o ni ṣiṣe ati multitasking pẹlu wa + ati awọn ẹya ti ilọsiwaju. + title: Kaabọ! +general: + theme: + added: Akori ti ṣafikun tẹlẹ + enabled: Mu awọn akori ṣiṣẹ + label: Alaye Akori + description: Isapejuwe + placeholder: Yan Akori + tags: Afi ami + add: Fi ọran kun + author: Onkọwe ọkunrin + selected: Ti yan + available: Wa + startup: Ṣiṣe lori ibẹrẹ? + language: Ede + icon_pack: + label: Awọn akopọ aami + accent_color: Awọ ara +toolbar: + placeholder: + author: Onkọwe ọkunrin + select: Ọpa irinṣẹ + description: Isapejuwe + height: Giga + enable: Mu ṣiṣẹ irinṣẹ irinṣẹ Fancy ṣiṣẹ +wm: + border: + enable: Jeki aala window + width: Iwọn aala + offset: Iparun aala + enable: Jeki oluṣakoso window + resize_delta: Tun ṣe Delta (%) + disabled_windows10: Oluṣakoso window ko wa fun Windows 10. + layout: Agbekalẹ + description: Isapejuwe + space_between_containers: Aaye laarin awọn apoti + workspace_offset: Awọn iṣẹ Iṣẹ-iṣẹ (awọn ala) + author: Onkọwe ọkunrin + workspace_padding: Awọn iṣẹ itasi +weg: + items: + visible_separators: Awọn iyatọ ti o han + gap: Aaye laarin awọn ohun kan + size: Iwọn nkan + zoom_size: Iwọn sisun (ti a lo fun awọn akori) + label: Awọn ohun + width: Fifẹ + gap: Alafo + label: Dock / forkbar + enable: Muu dock / forkbar + dock_side: Ẹgbẹ dock + auto_hide: Ibi ipamọ aifọwọyi + margin: Ẹlẹsin + padding: Fidigọdi silẹ +devtools: + app_folders: Awọn folda App + install_folder: Filese Fifi sori ẹrọ + enable: Mu awọn irinṣẹ Oláàmúdà ṣiṣẹ + custom_config_file: Fifuye faili atunto aṣa + settings_file: Faili eto + data_folder: Folda data + load: Ẹru +apps_configurations: + app: + options: + unmanage: Aileyẹ + float: Leke + force: Ṣakoso ṣakoso + pinned: Pin + name: Orukọ + category_placeholder: Ko si + title_readonly: Wiwo {{Orukọ}} + bindings: Dide (Ṣe akiyesi awọn aṣayan mejeeji ni a nilo) + options_label: Awọn aṣayan afikun + workspace_placeholder: Ko si + title_create: Ṣiṣẹda {Orukọ}} + monitor_placeholder: Ko si + category: Ẹya + workspace: Ibi-iṣẹ + title_edit: Ṣiṣatunṣe {{Orukọ}} + ok_create: Lati ṣẹda + ok_readonly: Satunkọ bi tuntun + ok_edit: Imudojuiwọn + monitor: Aṣabojuto + identifier: + negation: Ibaramu tuntun + add_block: Fi dègbé + kind: Ṣe idanimọ nipasẹ + id: Idamo + and: Ati + or: Tabi + matching_strategy: Ibaamu iṣiro + remove: Paarẹ Brow + confirm_delete: Ṣe o da ọ loju pe o fẹ lati pa iṣeto rẹ / s? + delete: Paarẹ + new: Tuntun + confirm_delete_title: Jẹrisi paarẹ + search: Ṣewadii + bundled_title: Ohun elo app ṣepọ pẹlu Selen + swap: Eepo + export: Firanṣẹ si ilẹ okeere + bundled_msg: >- + Awọn atunto ti a dapọ mọ ko ṣe deede ati pe a ṣe apẹrẹ lati fun ọ ni iriri + ti o dara julọ laisi isọdi. Wọn tunto awọn ohun elo ti o wọpọ julọ fun ọ. + import: Aṣagbewọle lati ilẹ okeere +extras: + discord: Di eniyan + github: Gitter + relaunch: Ṣadi + version: Ẹya + links: Awọn ọna asopọ osise + exit: Duro / Jade +shortcuts: + labels: + focus_right: Dojukọ ọtun + increase_width: Gbooro + reserve_right: Reserve ọtun + switch_workspace_3: Yipada si ibi-iṣẹ 3 + switch_workspace_6: Yipada si ibi-iṣẹ 6 + focus_latest: Idojukọ + focus_top: Dojukọ oke + switch_workspace_8: Yipada si ibi-iṣẹ 8 + decrease_height: Dinku iga + reserve_bottom: Isalẹ ifipamọ + send_to_workspace_3: Firanṣẹ si ibi-iṣẹ 3 + send_to_workspace_8: Firanṣẹ si ibi-iṣẹ 8 + send_to_workspace_1: Firanṣẹ si ibi-iṣẹ 1 + move_to_workspace_5: Gbe si ibi-iṣẹ 5 + increase_height: Igasoke giga + move_to_workspace_9: Gbe si ibi-ipa 9 + send_to_workspace_2: Firanṣẹ si ibi-iṣẹ 2 + focus_left: Idojukọ osi + move_to_workspace_3: Gbe si ibi-iṣẹ 3 + reserve_float: Dase leefofo loju omi + switch_workspace_1: Yipada si ibi-iṣẹ 1 + switch_workspace_9: Yipada si ibi-iṣẹ 9 + switch_workspace_2: Yipada si ibi-iṣẹ 2 + move_to_workspace_0: Gbe si ibi-iṣẹ 0 + move_to_workspace_2: Gbe si ibi-iṣẹ 2 + switch_workspace_5: Yipada si ibi-iṣẹ 5 + switch_workspace_4: Yipada si ibi-iṣẹ 4 + send_to_workspace_6: Firanṣẹ si ibi-iṣẹ 6 + send_to_workspace_7: Firanṣẹ si ibi-iṣẹ 7 + reserve_stack: Ipilẹ akopọ + switch_workspace_0: Yipada si ibi-iṣẹ 0 + send_to_workspace_9: Firanṣẹ si ibi-iṣẹ 9 + move_to_workspace_4: Gbe si ibi-iṣẹ 4 + move_to_workspace_8: Gbe si ibi-iṣẹ 8 + move_to_workspace_1: Gbe si Accepace 1 + move_to_workspace_7: Gbe si ibi-iṣẹ 7 + send_to_workspace_0: Firanṣẹ si ibi-iṣẹ 0 + send_to_workspace_5: Firanṣẹ si Ibi-iṣẹ 5 + decrease_width: DIVEELE WA + reserve_top: Reserve oke + restore_sizes: Pada awọn titobi + switch_workspace_7: Yipada si ibi-iṣẹ 7 + move_to_workspace_6: Gbe si ibi-iṣẹ 6 + focus_bottom: Idojukọ Idojukọ + send_to_workspace_4: Firanṣẹ si ibi-iṣẹ 4 + reserve_left: Reserve osi + enable: Mu awọn ọna abuja ti o sopọ mọ (Ahk) + enable_tooltip: Muu Ti o ba yoo ṣe awọn ọna abuja tirẹ nipa lilo APEN mojuto API +delete: Paarẹ +cancel: Fagilee +save: Fipamọ +loading: Loading ... +inProgress: Ni ilọsiwaju ... +quit: Lọ kuro +open: Ṣii diff --git a/src/apps/settings/i18n/translations/zh.yml b/src/apps/settings/i18n/translations/zh.yml index abaad301..c5cd672a 100644 --- a/src/apps/settings/i18n/translations/zh.yml +++ b/src/apps/settings/i18n/translations/zh.yml @@ -1,188 +1,188 @@ -loading: 加载中... -inProgress: 进行中... -cancel: 取消 -save: 保存 -quit: 退出 -open: 打开 -delete: 删除 -sides: - left: 左 - right: 右 - top: 上 - bottom: 下 -header: - labels: - general: 通用 - seelen_bar: 精美工具栏 - seelen_wm: 窗口管理器 - seelen_weg: 停靠栏/任务栏 - monitors: 显示器 - specific_apps: 特定应用 - shortcuts: 快捷键 - developer: 开发者 - info: 信息 -start: - title: 欢迎! - message: >- - 欢迎使用 Seelen UI,这是一个终极的桌面环境,集成了窗口平铺管理器,以增强你的 Windows 11 体验! - 通过我们的直观界面和高级功能,探索一个新的效率和多任务时代。 - message_accent: 用风格优化你的生产力! -general: - startup: 开机启动? - language: 语言 - theme: - label: 主题信息 - placeholder: 选择主题 - author: 作者 - description: 描述 - add: 添加主题 - added: 主题已添加 - enabled: 启用主题 - tags: 标签 - selected: 选定 - available: 可用的 - icon_pack: - label: 图标包 - accent_color: 口音颜色 -toolbar: - enable: 启用精美工具栏 - placeholder: - select: 工具栏结构 - author: 作者 - description: 描述 - height: 高度 -wm: - enable: 启用窗口管理器 - disabled_windows10: 窗口管理器不适用于 Windows 10。 - layout: 布局 - author: 作者 - description: 描述 - space_between_containers: 容器之间的空间 - workspace_padding: 工作区内边距 - workspace_offset: 工作区偏移(边距) - resize_delta: 调整大小增量(%) - border: - enable: 启用窗口边框 - width: 边框宽度 - offset: 边框偏移 -weg: - label: 停靠栏/任务栏 - enable: 启用停靠栏/任务栏 - width: 宽度 - auto_hide: 自动隐藏 - dock_side: 停靠位置 - padding: 内边距 - margin: 边距 - gap: 间距 - items: - label: 项目 - size: 项目大小 - zoom_size: 放大尺寸(用于主题) - gap: 项目间距 - visible_separators: 可见分隔符 -devtools: - enable: 启用开发者工具 - app_folders: 应用程序文件夹 - install_folder: 安装文件夹 - data_folder: 数据文件夹 - settings_file: 设置文件 - custom_config_file: 加载自定义配置文件 - load: 加载 -apps_configurations: - import: 导入 - export: 导出 - delete: 删除 - swap: 交换 - new: 新建 - bundled_title: Seelen 捆绑的应用配置 - bundled_msg: 这些捆绑配置不可编辑,旨在为你提供最佳体验而无需定制。它们会自动配置最常用的应用程序。 - confirm_delete_title: 确认删除 - confirm_delete: 确认要删除此配置吗? - search: 搜索 - app: - name: 名称 - category: 分类 - category_placeholder: 无 - bindings: 绑定(需要两个选项) - monitor: 显示器 - monitor_placeholder: 无 - workspace: 工作区 - workspace_placeholder: 无 - title_edit: 编辑 {{name}} - title_create: 创建 {{name}} - title_readonly: 查看 {{name}} - ok_edit: 更新 - ok_create: 创建 - ok_readonly: 作为新建编辑 - options_label: 额外选项 - options: - float: 浮动 - unmanage: 不管理 - force: 强制管理 - pinned: 固定 - identifier: - remove: 删除块 - id: 标识符 - kind: 标识方式 - matching_strategy: 匹配策略 - negation: 否定匹配 - and: 与 - or: 或 - add_block: 添加块 -extras: - version: 版本 - links: 官方链接 - github: GitHub - discord: Discord - relaunch: 重新启动 - exit: 退出/退出 -shortcuts: - enable: 启用集成快捷键 (ahk) - enable_tooltip: 如果你将使用 Seelen Core API 实现自己的快捷键,请禁用此项 - labels: - reserve_top: 保留顶部 - reserve_bottom: 保留底部 - reserve_left: 保留左侧 - reserve_right: 保留右侧 - reserve_float: 保留浮动 - reserve_stack: 保留堆栈 - focus_top: 聚焦顶部 - focus_bottom: 聚焦底部 - focus_left: 聚焦左侧 - focus_right: 聚焦右侧 - focus_latest: 聚焦最新 - increase_width: 增加宽度 - decrease_width: 减少宽度 - increase_height: 增加高度 - decrease_height: 减少高度 - restore_sizes: 恢复大小 - switch_workspace_0: 切换到工作区 0 - switch_workspace_1: 切换到工作区 1 - switch_workspace_2: 切换到工作区 2 - switch_workspace_3: 切换到工作区 3 - switch_workspace_4: 切换到工作区 4 - switch_workspace_5: 切换到工作区 5 - switch_workspace_6: 切换到工作区 6 - switch_workspace_7: 切换到工作区 7 - switch_workspace_8: 切换到工作区 8 - switch_workspace_9: 切换到工作区 9 - move_to_workspace_0: 移动到工作区 0 - move_to_workspace_1: 移动到工作区 1 - move_to_workspace_2: 移动到工作区 2 - move_to_workspace_3: 移动到工作区 3 - move_to_workspace_4: 移动到工作区 4 - move_to_workspace_5: 移动到工作区 5 - move_to_workspace_6: 移动到工作区 6 - move_to_workspace_7: 移动到工作区 7 - move_to_workspace_8: 移动到工作区 8 - move_to_workspace_9: 移动到工作区 9 - send_to_workspace_0: 发送到工作区 0 - send_to_workspace_1: 发送到工作区 1 - send_to_workspace_2: 发送到工作区 2 - send_to_workspace_3: 发送到工作区 3 - send_to_workspace_4: 发送到工作区 4 - send_to_workspace_5: 发送到工作区 5 - send_to_workspace_6: 发送到工作区 6 - send_to_workspace_7: 发送到工作区 7 - send_to_workspace_8: 发送到工作区 8 - send_to_workspace_9: 发送到工作区 9 +loading: 加载中... +inProgress: 进行中... +cancel: 取消 +save: 保存 +quit: 退出 +open: 打开 +delete: 删除 +sides: + left: 左 + right: 右 + top: 上 + bottom: 下 +header: + labels: + general: 通用 + seelen_bar: 精美工具栏 + seelen_wm: 窗口管理器 + seelen_weg: 停靠栏/任务栏 + monitors: 显示器 + specific_apps: 特定应用 + shortcuts: 快捷键 + developer: 开发者 + info: 信息 +start: + title: 欢迎! + message: >- + 欢迎使用 Seelen UI,这是一个终极的桌面环境,集成了窗口平铺管理器,以增强你的 Windows 11 体验! + 通过我们的直观界面和高级功能,探索一个新的效率和多任务时代。 + message_accent: 用风格优化你的生产力! +general: + startup: 开机启动? + language: 语言 + theme: + label: 主题信息 + placeholder: 选择主题 + author: 作者 + description: 描述 + add: 添加主题 + added: 主题已添加 + enabled: 启用主题 + tags: 标签 + selected: 选定 + available: 可用的 + icon_pack: + label: 图标包 + accent_color: 口音颜色 +toolbar: + enable: 启用精美工具栏 + placeholder: + select: 工具栏结构 + author: 作者 + description: 描述 + height: 高度 +wm: + enable: 启用窗口管理器 + disabled_windows10: 窗口管理器不适用于 Windows 10。 + layout: 布局 + author: 作者 + description: 描述 + space_between_containers: 容器之间的空间 + workspace_padding: 工作区内边距 + workspace_offset: 工作区偏移(边距) + resize_delta: 调整大小增量(%) + border: + enable: 启用窗口边框 + width: 边框宽度 + offset: 边框偏移 +weg: + label: 停靠栏/任务栏 + enable: 启用停靠栏/任务栏 + width: 宽度 + auto_hide: 自动隐藏 + dock_side: 停靠位置 + padding: 内边距 + margin: 边距 + gap: 间距 + items: + label: 项目 + size: 项目大小 + zoom_size: 放大尺寸(用于主题) + gap: 项目间距 + visible_separators: 可见分隔符 +devtools: + enable: 启用开发者工具 + app_folders: 应用程序文件夹 + install_folder: 安装文件夹 + data_folder: 数据文件夹 + settings_file: 设置文件 + custom_config_file: 加载自定义配置文件 + load: 加载 +apps_configurations: + import: 导入 + export: 导出 + delete: 删除 + swap: 交换 + new: 新建 + bundled_title: Seelen 捆绑的应用配置 + bundled_msg: 这些捆绑配置不可编辑,旨在为你提供最佳体验而无需定制。它们会自动配置最常用的应用程序。 + confirm_delete_title: 确认删除 + confirm_delete: 确认要删除此配置吗? + search: 搜索 + app: + name: 名称 + category: 分类 + category_placeholder: 无 + bindings: 绑定(需要两个选项) + monitor: 显示器 + monitor_placeholder: 无 + workspace: 工作区 + workspace_placeholder: 无 + title_edit: 编辑 {{name}} + title_create: 创建 {{name}} + title_readonly: 查看 {{name}} + ok_edit: 更新 + ok_create: 创建 + ok_readonly: 作为新建编辑 + options_label: 额外选项 + options: + float: 浮动 + unmanage: 不管理 + force: 强制管理 + pinned: 固定 + identifier: + remove: 删除块 + id: 标识符 + kind: 标识方式 + matching_strategy: 匹配策略 + negation: 否定匹配 + and: 与 + or: 或 + add_block: 添加块 +extras: + version: 版本 + links: 官方链接 + github: GitHub + discord: Discord + relaunch: 重新启动 + exit: 退出/退出 +shortcuts: + enable: 启用集成快捷键 (ahk) + enable_tooltip: 如果你将使用 Seelen Core API 实现自己的快捷键,请禁用此项 + labels: + reserve_top: 保留顶部 + reserve_bottom: 保留底部 + reserve_left: 保留左侧 + reserve_right: 保留右侧 + reserve_float: 保留浮动 + reserve_stack: 保留堆栈 + focus_top: 聚焦顶部 + focus_bottom: 聚焦底部 + focus_left: 聚焦左侧 + focus_right: 聚焦右侧 + focus_latest: 聚焦最新 + increase_width: 增加宽度 + decrease_width: 减少宽度 + increase_height: 增加高度 + decrease_height: 减少高度 + restore_sizes: 恢复大小 + switch_workspace_0: 切换到工作区 0 + switch_workspace_1: 切换到工作区 1 + switch_workspace_2: 切换到工作区 2 + switch_workspace_3: 切换到工作区 3 + switch_workspace_4: 切换到工作区 4 + switch_workspace_5: 切换到工作区 5 + switch_workspace_6: 切换到工作区 6 + switch_workspace_7: 切换到工作区 7 + switch_workspace_8: 切换到工作区 8 + switch_workspace_9: 切换到工作区 9 + move_to_workspace_0: 移动到工作区 0 + move_to_workspace_1: 移动到工作区 1 + move_to_workspace_2: 移动到工作区 2 + move_to_workspace_3: 移动到工作区 3 + move_to_workspace_4: 移动到工作区 4 + move_to_workspace_5: 移动到工作区 5 + move_to_workspace_6: 移动到工作区 6 + move_to_workspace_7: 移动到工作区 7 + move_to_workspace_8: 移动到工作区 8 + move_to_workspace_9: 移动到工作区 9 + send_to_workspace_0: 发送到工作区 0 + send_to_workspace_1: 发送到工作区 1 + send_to_workspace_2: 发送到工作区 2 + send_to_workspace_3: 发送到工作区 3 + send_to_workspace_4: 发送到工作区 4 + send_to_workspace_5: 发送到工作区 5 + send_to_workspace_6: 发送到工作区 6 + send_to_workspace_7: 发送到工作区 7 + send_to_workspace_8: 发送到工作区 8 + send_to_workspace_9: 发送到工作区 9 diff --git a/src/apps/settings/i18n/translations/zu.yml b/src/apps/settings/i18n/translations/zu.yml index 46739c61..4fb0e75b 100644 --- a/src/apps/settings/i18n/translations/zu.yml +++ b/src/apps/settings/i18n/translations/zu.yml @@ -1,195 +1,195 @@ -sides: - bottom: Esinqeni - top: Isihloko - left: '-Bunxele' - right: Ngakwesokudla -header: - labels: - seelen_wm: Imenenja yewindows - seelen_bar: I-Fancy Toolbar - seelen_weg: Dock / taskbar - general: Jwayelekile - developer: Konjiniyela - info: Ulwazi - specific_apps: Izinhlelo zokusebenza ezikhethekile - monitors: Ukuqapha - shortcuts: Amashoshothi -start: - message: >- - Uyemukelwa ku-Seelen UI, imvelo yokugcina yedeskithophu enomphathi weWindows - ofakiwe wokuthuthukisa isipiliyoni sakho seWindows 11! Hlola inkathi entsha - yokusebenza kahle kanye ne-multitasking nge-interface yethu enembile nezici - ezithuthukile. - message_accent: Lungiselela umkhiqizo wakho ngesitayela! - title: Uyemukelwa! -general: - theme: - description: Ukufanisa - add: Engeza itimu - added: Itimu esevele ingezwe - author: Umlobi - enabled: Izindikimba ezinikwe amandla - label: Imininingwane yetimu - placeholder: Khetha isihloko - tags: Amathegi - available: '-Tholakala' - selected: Ikhethiwe - language: Ulimi - startup: Gijima ekuqaleni? - icon_pack: - label: I-Icon Packs - accent_color: Umbala we-Accent -toolbar: - placeholder: - author: Umlobi - description: Ukufanisa - select: Isakhiwo samathuluzi - height: Ubude - enable: Nika amandla amathuluzi e-fancy -wm: - border: - enable: Nika amandla umngcele wewindi - width: Ububanzi bomngcele - offset: Umngcele we-Offset - resize_delta: Shintsha usayizi DEDTA (%) - layout: Isakhiwo - workspace_offset: Izindawo zokusebenzela (Margins) - author: Umlobi - space_between_containers: Isikhala phakathi kweziqukathi - description: Ukufanisa - disabled_windows10: Imenenja yewindows ayitholakali ngeWindows 10. - workspace_padding: I-Workespashe Padding - enable: Nika amandla umphathi wewindi -weg: - items: - size: Usayizi wento - gap: Isikhala phakathi kwezinto - visible_separators: Abahlukanisi ababonakalayo - label: Into - zoom_size: Usayizi osondeza (osetshenziselwa izingqikithi) - width: Ububanzi - gap: Insungubezi - dock_side: Uhlangothi lwedokodo - enable: Nika amandla i-Dock / Taskbar - auto_hide: Fihla okuzenzakalelayo - padding: Idilidi - margin: Image - label: Dock / taskbar -devtools: - install_folder: Ifolda yokufaka - data_folder: Ifolda yedatha - settings_file: Ifayela lezilungiselelo - load: Thwala - app_folders: Amafolda wohlelo lokusebenza - custom_config_file: Layisha ifayela le-config yangokwezifiso - enable: Nika amandla amathuluzi onjiniyela -apps_configurations: - app: - options: - unmanage: Ugeage - pinned: Uphinisiwe - force: Cindezela Phatha - float: Thwala amaphiko - bindings: Ukubopha (inothi zombili izinketho ziyadingeka) - title_readonly: Ukubuka {{igama}} - title_create: Ukudala {{igama}} - ok_readonly: Hlela njengomusha - category_placeholder: Namunye - monitor: Qapha - name: Ibizo - options_label: Izinketho Ezengeziwe - ok_edit: Buyekeza - monitor_placeholder: Namunye - workspace_placeholder: Namunye - category: Uhlobo - workspace: Indawo - title_edit: Ukuhleleka {{igama}} - ok_create: Dala - identifier: - remove: Susa ibhulokhi - matching_strategy: Isu lokuqondanisa - negation: Hlukana nokufanisa - add_block: Faka ibhlokhi - kind: Khomba ngu - or: Noma - and: Na- - id: Isithombe esithi - export: Thumela kwamanye amazwe - import: Ngenisa ezweni - new: '-Kwanamuhla' - delete: Cisha - bundled_title: I-App Config ehlanganiswe ne-Seleen - confirm_delete: Uqinisekile ukuthi ufuna ukususa lolu hlelo / s? - confirm_delete_title: Qinisekisa ukususa - swap: Shintshela - search: Sesha - bundled_msg: >- - Lokhu kulungiswa okuhlanganisiwe akuhlelekile futhi kuklanyelwe ukukunikeza - okuhlangenwe nakho okuhle kakhulu ngaphandle kokwenza ngokwezifiso. - Balungiselela ngokuzenzakalelayo izicelo ezivame kakhulu kuwe. -extras: - links: Izixhumanisi ezisemthethweni - relaunch: Qondisa amandla ehlehliseyo - exit: Quit / Phuma - version: Ukuhumushela - discord: Ukunqaba - github: Umuthi othile kiki -shortcuts: - labels: - focus_right: Gxila kwesokudla - reserve_top: Beka phezulu - reserve_right: Ukubhuka kwesokudla - focus_top: Gxila phezulu - move_to_workspace_0: Hambisa ku-Workpace 0 - increase_width: Khulisa Ububanzi - switch_workspace_9: Shintshela ku-Workpace 9 - increase_height: Khuphula ukuphakama - restore_sizes: Buyisela osayizi - send_to_workspace_7: Thumela kwi-Workpace 7 - move_to_workspace_4: Hambisa ku-Workpace 4 - send_to_workspace_6: Thumela ku-Workpace 6 - move_to_workspace_7: Hambisa ku-Workpace 7 - move_to_workspace_2: Hambisa ku-Workpace 2 - decrease_width: Yehlisa Ububanzi - focus_latest: Gxila kwakamuva - switch_workspace_5: Shintshela ku-Workpace 5 - send_to_workspace_0: Thumela ku-Workpace 0 - decrease_height: Yehlisa ukuphakama - move_to_workspace_9: Hambisa ku-Workpace 9 - switch_workspace_2: Shintshela ku-Workpace 2 - send_to_workspace_4: Thumela kwi-Workpace 4 - switch_workspace_0: Shintshela ku-Workpace 0 - send_to_workspace_8: Thumela ku-Workpace 8 - reserve_left: Indawo esele - focus_left: Gxila kwesokunxele - move_to_workspace_3: Hambisa ku-Workpace 3 - move_to_workspace_1: Hambisa ku-Workpace 1 - reserve_bottom: Ukubhuka phansi - reserve_stack: Isitaki - move_to_workspace_6: Hambisa ku-Workpace 6 - send_to_workspace_1: Thumela kwi-Workpace 1 - switch_workspace_7: Shintshela ku-Workpace 7 - switch_workspace_3: Shintshela ku-Workpace 3 - move_to_workspace_8: Hambisa ku-Workpace 8 - focus_bottom: Gxila phansi - move_to_workspace_5: Hambisa ku-Workpace 5 - reserve_float: Indawo yokuntanta - send_to_workspace_3: Thumela ku-Workpace 3 - switch_workspace_1: Shintshela ku-Workpace 1 - send_to_workspace_5: Thumela ku-Workpace 5 - send_to_workspace_9: Thumela ku-Workpace 9 - send_to_workspace_2: Thumela ku-Workpace 2 - switch_workspace_4: Shintshela ku-Workpace 4 - switch_workspace_8: Shintshela ku-Workpace 8 - switch_workspace_6: Shintshela ku-Workpace 6 - enable: Nika amandla izinqamuleli ezihlanganisiwe (Ahk) - enable_tooltip: >- - Khubaza uma uzosebenzisa izinqamuleli zakho usebenzisa i-Seelen Core Core - API -inProgress: Kuyaqhubeka... -cancel: Hlikihla -save: Hlenga -quit: Yeka -delete: Cisha -loading: Iyalayisha ... -open: Vula +sides: + bottom: Esinqeni + top: Isihloko + left: '-Bunxele' + right: Ngakwesokudla +header: + labels: + seelen_wm: Imenenja yewindows + seelen_bar: I-Fancy Toolbar + seelen_weg: Dock / taskbar + general: Jwayelekile + developer: Konjiniyela + info: Ulwazi + specific_apps: Izinhlelo zokusebenza ezikhethekile + monitors: Ukuqapha + shortcuts: Amashoshothi +start: + message: >- + Uyemukelwa ku-Seelen UI, imvelo yokugcina yedeskithophu enomphathi weWindows + ofakiwe wokuthuthukisa isipiliyoni sakho seWindows 11! Hlola inkathi entsha + yokusebenza kahle kanye ne-multitasking nge-interface yethu enembile nezici + ezithuthukile. + message_accent: Lungiselela umkhiqizo wakho ngesitayela! + title: Uyemukelwa! +general: + theme: + description: Ukufanisa + add: Engeza itimu + added: Itimu esevele ingezwe + author: Umlobi + enabled: Izindikimba ezinikwe amandla + label: Imininingwane yetimu + placeholder: Khetha isihloko + tags: Amathegi + available: '-Tholakala' + selected: Ikhethiwe + language: Ulimi + startup: Gijima ekuqaleni? + icon_pack: + label: I-Icon Packs + accent_color: Umbala we-Accent +toolbar: + placeholder: + author: Umlobi + description: Ukufanisa + select: Isakhiwo samathuluzi + height: Ubude + enable: Nika amandla amathuluzi e-fancy +wm: + border: + enable: Nika amandla umngcele wewindi + width: Ububanzi bomngcele + offset: Umngcele we-Offset + resize_delta: Shintsha usayizi DEDTA (%) + layout: Isakhiwo + workspace_offset: Izindawo zokusebenzela (Margins) + author: Umlobi + space_between_containers: Isikhala phakathi kweziqukathi + description: Ukufanisa + disabled_windows10: Imenenja yewindows ayitholakali ngeWindows 10. + workspace_padding: I-Workespashe Padding + enable: Nika amandla umphathi wewindi +weg: + items: + size: Usayizi wento + gap: Isikhala phakathi kwezinto + visible_separators: Abahlukanisi ababonakalayo + label: Into + zoom_size: Usayizi osondeza (osetshenziselwa izingqikithi) + width: Ububanzi + gap: Insungubezi + dock_side: Uhlangothi lwedokodo + enable: Nika amandla i-Dock / Taskbar + auto_hide: Fihla okuzenzakalelayo + padding: Idilidi + margin: Image + label: Dock / taskbar +devtools: + install_folder: Ifolda yokufaka + data_folder: Ifolda yedatha + settings_file: Ifayela lezilungiselelo + load: Thwala + app_folders: Amafolda wohlelo lokusebenza + custom_config_file: Layisha ifayela le-config yangokwezifiso + enable: Nika amandla amathuluzi onjiniyela +apps_configurations: + app: + options: + unmanage: Ugeage + pinned: Uphinisiwe + force: Cindezela Phatha + float: Thwala amaphiko + bindings: Ukubopha (inothi zombili izinketho ziyadingeka) + title_readonly: Ukubuka {{igama}} + title_create: Ukudala {{igama}} + ok_readonly: Hlela njengomusha + category_placeholder: Namunye + monitor: Qapha + name: Ibizo + options_label: Izinketho Ezengeziwe + ok_edit: Buyekeza + monitor_placeholder: Namunye + workspace_placeholder: Namunye + category: Uhlobo + workspace: Indawo + title_edit: Ukuhleleka {{igama}} + ok_create: Dala + identifier: + remove: Susa ibhulokhi + matching_strategy: Isu lokuqondanisa + negation: Hlukana nokufanisa + add_block: Faka ibhlokhi + kind: Khomba ngu + or: Noma + and: Na- + id: Isithombe esithi + export: Thumela kwamanye amazwe + import: Ngenisa ezweni + new: '-Kwanamuhla' + delete: Cisha + bundled_title: I-App Config ehlanganiswe ne-Seleen + confirm_delete: Uqinisekile ukuthi ufuna ukususa lolu hlelo / s? + confirm_delete_title: Qinisekisa ukususa + swap: Shintshela + search: Sesha + bundled_msg: >- + Lokhu kulungiswa okuhlanganisiwe akuhlelekile futhi kuklanyelwe ukukunikeza + okuhlangenwe nakho okuhle kakhulu ngaphandle kokwenza ngokwezifiso. + Balungiselela ngokuzenzakalelayo izicelo ezivame kakhulu kuwe. +extras: + links: Izixhumanisi ezisemthethweni + relaunch: Qondisa amandla ehlehliseyo + exit: Quit / Phuma + version: Ukuhumushela + discord: Ukunqaba + github: Umuthi othile kiki +shortcuts: + labels: + focus_right: Gxila kwesokudla + reserve_top: Beka phezulu + reserve_right: Ukubhuka kwesokudla + focus_top: Gxila phezulu + move_to_workspace_0: Hambisa ku-Workpace 0 + increase_width: Khulisa Ububanzi + switch_workspace_9: Shintshela ku-Workpace 9 + increase_height: Khuphula ukuphakama + restore_sizes: Buyisela osayizi + send_to_workspace_7: Thumela kwi-Workpace 7 + move_to_workspace_4: Hambisa ku-Workpace 4 + send_to_workspace_6: Thumela ku-Workpace 6 + move_to_workspace_7: Hambisa ku-Workpace 7 + move_to_workspace_2: Hambisa ku-Workpace 2 + decrease_width: Yehlisa Ububanzi + focus_latest: Gxila kwakamuva + switch_workspace_5: Shintshela ku-Workpace 5 + send_to_workspace_0: Thumela ku-Workpace 0 + decrease_height: Yehlisa ukuphakama + move_to_workspace_9: Hambisa ku-Workpace 9 + switch_workspace_2: Shintshela ku-Workpace 2 + send_to_workspace_4: Thumela kwi-Workpace 4 + switch_workspace_0: Shintshela ku-Workpace 0 + send_to_workspace_8: Thumela ku-Workpace 8 + reserve_left: Indawo esele + focus_left: Gxila kwesokunxele + move_to_workspace_3: Hambisa ku-Workpace 3 + move_to_workspace_1: Hambisa ku-Workpace 1 + reserve_bottom: Ukubhuka phansi + reserve_stack: Isitaki + move_to_workspace_6: Hambisa ku-Workpace 6 + send_to_workspace_1: Thumela kwi-Workpace 1 + switch_workspace_7: Shintshela ku-Workpace 7 + switch_workspace_3: Shintshela ku-Workpace 3 + move_to_workspace_8: Hambisa ku-Workpace 8 + focus_bottom: Gxila phansi + move_to_workspace_5: Hambisa ku-Workpace 5 + reserve_float: Indawo yokuntanta + send_to_workspace_3: Thumela ku-Workpace 3 + switch_workspace_1: Shintshela ku-Workpace 1 + send_to_workspace_5: Thumela ku-Workpace 5 + send_to_workspace_9: Thumela ku-Workpace 9 + send_to_workspace_2: Thumela ku-Workpace 2 + switch_workspace_4: Shintshela ku-Workpace 4 + switch_workspace_8: Shintshela ku-Workpace 8 + switch_workspace_6: Shintshela ku-Workpace 6 + enable: Nika amandla izinqamuleli ezihlanganisiwe (Ahk) + enable_tooltip: >- + Khubaza uma uzosebenzisa izinqamuleli zakho usebenzisa i-Seelen Core Core + API +inProgress: Kuyaqhubeka... +cancel: Hlikihla +save: Hlenga +quit: Yeka +delete: Cisha +loading: Iyalayisha ... +open: Vula diff --git a/src/apps/settings/index.html b/src/apps/settings/index.html index cdb9d8bd..009c905a 100644 --- a/src/apps/settings/index.html +++ b/src/apps/settings/index.html @@ -1,34 +1,34 @@ - - - - - - - - - - -
-
-
- -
- Seelen UI -
-
-
- - + + + + + + + + + + +
+
+
+ +
+ Seelen UI +
+
+
+ + diff --git a/src/apps/settings/index.tsx b/src/apps/settings/index.tsx index 7471048e..dee00d69 100644 --- a/src/apps/settings/index.tsx +++ b/src/apps/settings/index.tsx @@ -1,34 +1,34 @@ -import { getRootContainer } from '../shared'; -import { wrapConsole } from '../shared/ConsoleWrapper'; -import i18n, { loadTranslations } from './i18n'; -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; -import { createRoot } from 'react-dom/client'; -import { I18nextProvider } from 'react-i18next'; -import { Provider } from 'react-redux'; - -import { LoadSettingsToStore, registerStoreEvents, store } from './modules/shared/store/infra'; - -import { App } from './app'; - -import './styles/colors.css'; -import './styles/variables.css'; -import './styles/reset.css'; -import './styles/global.css'; - -(async function main() { - wrapConsole(); - getCurrentWebviewWindow().show(); - const container = getRootContainer(); - - await LoadSettingsToStore(); - await registerStoreEvents(); - await loadTranslations(); - - createRoot(container).render( - - - - - , - ); -})(); +import { getRootContainer } from '../shared'; +import { wrapConsole } from '../shared/ConsoleWrapper'; +import i18n, { loadTranslations } from './i18n'; +import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; +import { createRoot } from 'react-dom/client'; +import { I18nextProvider } from 'react-i18next'; +import { Provider } from 'react-redux'; + +import { LoadSettingsToStore, registerStoreEvents, store } from './modules/shared/store/infra'; + +import { App } from './app'; + +import './styles/colors.css'; +import './styles/variables.css'; +import './styles/reset.css'; +import './styles/global.css'; + +(async function main() { + wrapConsole(); + getCurrentWebviewWindow().show(); + const container = getRootContainer(); + + await LoadSettingsToStore(); + await registerStoreEvents(); + await loadTranslations(); + + createRoot(container).render( + + + + + , + ); +})(); diff --git a/src/apps/settings/modules/StartUser/index.module.css b/src/apps/settings/modules/StartUser/index.module.css index 2645ad65..df909a8d 100644 --- a/src/apps/settings/modules/StartUser/index.module.css +++ b/src/apps/settings/modules/StartUser/index.module.css @@ -1,21 +1,21 @@ - -.welcome { - :global(.ant-modal-confirm-content) { - text-align: justify; - b { - font-weight: 600; - } - } - - .icon { - font-size: 23px; - position: relative; - width: 30px; - left: -3px; - top: -8px; - } - - button:focus-visible { - outline: none !important; - } + +.welcome { + :global(.ant-modal-confirm-content) { + text-align: justify; + b { + font-weight: 600; + } + } + + .icon { + font-size: 23px; + position: relative; + width: 30px; + left: -3px; + top: -8px; + } + + button:focus-visible { + outline: none !important; + } } \ No newline at end of file diff --git a/src/apps/settings/modules/StartUser/infra.tsx b/src/apps/settings/modules/StartUser/infra.tsx index f1fdebc9..88df2abf 100644 --- a/src/apps/settings/modules/StartUser/infra.tsx +++ b/src/apps/settings/modules/StartUser/infra.tsx @@ -1,35 +1,35 @@ -import i18n from '../../i18n'; -import { Modal } from 'antd'; - -import { SaveStore, store } from '../shared/store/infra'; -import { startup } from '../shared/tauri/infra'; - -import { RootActions } from '../shared/store/app/reducer'; - -import cs from './index.module.css'; - -export const StartUser = () => { - startup.enable(); - store.dispatch(RootActions.setAutostart(true)); - - const modal = Modal.confirm({ - title: i18n.t('start.title'), - className: cs.welcome, - content: ( -
-

- {i18n.t('start.message')} -

- {i18n.t('start.message_accent')} -
- ), - okText: 'Continue', - onOk: () => { - SaveStore(); - modal.destroy(); - }, - icon:
🎉
, - cancelButtonProps: { style: { display: 'none' } }, - centered: true, - }); -}; +import i18n from '../../i18n'; +import { Modal } from 'antd'; + +import { SaveStore, store } from '../shared/store/infra'; +import { startup } from '../shared/tauri/infra'; + +import { RootActions } from '../shared/store/app/reducer'; + +import cs from './index.module.css'; + +export const StartUser = () => { + startup.enable(); + store.dispatch(RootActions.setAutostart(true)); + + const modal = Modal.confirm({ + title: i18n.t('start.title'), + className: cs.welcome, + content: ( +
+

+ {i18n.t('start.message')} +

+ {i18n.t('start.message_accent')} +
+ ), + okText: 'Continue', + onOk: () => { + SaveStore(); + modal.destroy(); + }, + icon:
🎉
, + cancelButtonProps: { style: { display: 'none' } }, + centered: true, + }); +}; diff --git a/src/apps/settings/modules/WindowManager/border/app.ts b/src/apps/settings/modules/WindowManager/border/app.ts index 617399e4..ae4af871 100644 --- a/src/apps/settings/modules/WindowManager/border/app.ts +++ b/src/apps/settings/modules/WindowManager/border/app.ts @@ -1,16 +1,16 @@ -import { parseAsCamel } from '../../../../shared/schemas'; -import { Border, BorderSchema } from '../../../../shared/schemas/WindowManager'; -import { createSlice } from '@reduxjs/toolkit'; - -import { reducersFor, selectorsFor } from '../../shared/utils/app'; - -const initialState: Border = parseAsCamel(BorderSchema, {}); - -export const BorderSlice = createSlice({ - name: 'windowManager/border', - initialState, - reducers: reducersFor(initialState), - selectors: selectorsFor(initialState), -}); - +import { parseAsCamel } from '../../../../shared/schemas'; +import { Border, BorderSchema } from '../../../../shared/schemas/WindowManager'; +import { createSlice } from '@reduxjs/toolkit'; + +import { reducersFor, selectorsFor } from '../../shared/utils/app'; + +const initialState: Border = parseAsCamel(BorderSchema, {}); + +export const BorderSlice = createSlice({ + name: 'windowManager/border', + initialState, + reducers: reducersFor(initialState), + selectors: selectorsFor(initialState), +}); + export const BorderActions = BorderSlice.actions; \ No newline at end of file diff --git a/src/apps/settings/modules/WindowManager/border/infra.tsx b/src/apps/settings/modules/WindowManager/border/infra.tsx index fd511123..6c48fb95 100644 --- a/src/apps/settings/modules/WindowManager/border/infra.tsx +++ b/src/apps/settings/modules/WindowManager/border/infra.tsx @@ -1,49 +1,49 @@ -import { SettingsOption, SettingsSubGroup } from '../../../components/SettingsBox'; -import { InputNumber, Switch } from 'antd'; -import { useTranslation } from 'react-i18next'; - -import { useAppDispatch, useAppSelector, useDispatchCallback } from '../../shared/utils/infra'; - -import { BorderSelectors } from '../../shared/store/app/selectors'; -import { BorderActions } from './app'; - -export const BorderSettings = () => { - const enabled = useAppSelector(BorderSelectors.enabled); - const offset = useAppSelector(BorderSelectors.offset); - const width = useAppSelector(BorderSelectors.width); - - const dispatch = useAppDispatch(); - const { t } = useTranslation(); - - const toggleEnabled = useDispatchCallback((value: boolean) => { - dispatch(BorderActions.setEnabled(value)); - }); - - const updateOffset = useDispatchCallback((value: number | null) => { - dispatch(BorderActions.setOffset(value || 0)); - }); - - const updateWidth = useDispatchCallback((value: number | null) => { - dispatch(BorderActions.setWidth(value || 0)); - }); - - return ( - - {t('wm.border.enable')} - - - } - > - - {t('wm.border.offset')} - - - - {t('wm.border.width')} - - - - ); -}; +import { SettingsOption, SettingsSubGroup } from '../../../components/SettingsBox'; +import { InputNumber, Switch } from 'antd'; +import { useTranslation } from 'react-i18next'; + +import { useAppDispatch, useAppSelector, useDispatchCallback } from '../../shared/utils/infra'; + +import { BorderSelectors } from '../../shared/store/app/selectors'; +import { BorderActions } from './app'; + +export const BorderSettings = () => { + const enabled = useAppSelector(BorderSelectors.enabled); + const offset = useAppSelector(BorderSelectors.offset); + const width = useAppSelector(BorderSelectors.width); + + const dispatch = useAppDispatch(); + const { t } = useTranslation(); + + const toggleEnabled = useDispatchCallback((value: boolean) => { + dispatch(BorderActions.setEnabled(value)); + }); + + const updateOffset = useDispatchCallback((value: number | null) => { + dispatch(BorderActions.setOffset(value || 0)); + }); + + const updateWidth = useDispatchCallback((value: number | null) => { + dispatch(BorderActions.setWidth(value || 0)); + }); + + return ( + + {t('wm.border.enable')} + + + } + > + + {t('wm.border.offset')} + + + + {t('wm.border.width')} + + + + ); +}; diff --git a/src/apps/settings/modules/WindowManager/main/app.ts b/src/apps/settings/modules/WindowManager/main/app.ts index 4380778e..2b21eb0a 100644 --- a/src/apps/settings/modules/WindowManager/main/app.ts +++ b/src/apps/settings/modules/WindowManager/main/app.ts @@ -1,25 +1,25 @@ -import { parseAsCamel } from '../../../../shared/schemas'; -import { WindowManager, WindowManagerSchema } from '../../../../shared/schemas/WindowManager'; -import { createSlice } from '@reduxjs/toolkit'; - -import { matcher, reducersFor, selectorsFor } from '../../shared/utils/app'; -import { BorderSlice } from '../border/app'; - -let initialState: WindowManager = parseAsCamel(WindowManagerSchema, {}); - -export const SeelenManagerSlice = createSlice({ - name: 'windowManager', - initialState, - selectors: selectorsFor(initialState), - reducers: { - ...reducersFor(initialState), - }, - extraReducers: (builder) => { - builder - .addMatcher(matcher(BorderSlice), (state, action) => { - state.border = BorderSlice.reducer(state.border, action); - }); - }, -}); - -export const WManagerSettingsActions = SeelenManagerSlice.actions; +import { parseAsCamel } from '../../../../shared/schemas'; +import { WindowManager, WindowManagerSchema } from '../../../../shared/schemas/WindowManager'; +import { createSlice } from '@reduxjs/toolkit'; + +import { matcher, reducersFor, selectorsFor } from '../../shared/utils/app'; +import { BorderSlice } from '../border/app'; + +let initialState: WindowManager = parseAsCamel(WindowManagerSchema, {}); + +export const SeelenManagerSlice = createSlice({ + name: 'windowManager', + initialState, + selectors: selectorsFor(initialState), + reducers: { + ...reducersFor(initialState), + }, + extraReducers: (builder) => { + builder + .addMatcher(matcher(BorderSlice), (state, action) => { + state.border = BorderSlice.reducer(state.border, action); + }); + }, +}); + +export const WManagerSettingsActions = SeelenManagerSlice.actions; diff --git a/src/apps/settings/modules/WindowManager/main/infra/GlobalPaddings.tsx b/src/apps/settings/modules/WindowManager/main/infra/GlobalPaddings.tsx index 6202621e..d4b1d342 100644 --- a/src/apps/settings/modules/WindowManager/main/infra/GlobalPaddings.tsx +++ b/src/apps/settings/modules/WindowManager/main/infra/GlobalPaddings.tsx @@ -1,69 +1,69 @@ -import { SettingsGroup, SettingsOption, SettingsSubGroup } from '../../../../components/SettingsBox'; -import { InputNumber } from 'antd'; -import { useTranslation } from 'react-i18next'; -import { useDispatch } from 'react-redux'; - -import { useAppSelector } from '../../../shared/utils/infra'; - -import { SeelenWmSelectors } from '../../../shared/store/app/selectors'; -import { Rect } from '../../../shared/utils/app/Rect'; -import { WManagerSettingsActions } from '../app'; - -export const GlobalPaddings = () => { - const workspaceGap = useAppSelector(SeelenWmSelectors.workspaceGap); - const workspacePadding = useAppSelector(SeelenWmSelectors.workspacePadding); - const workAreaOffset = useAppSelector(SeelenWmSelectors.globalWorkAreaOffset); - - const dispatch = useDispatch(); - const { t } = useTranslation(); - - const onChangeGlobalOffset = (side: keyof Rect, value: number | null) => { - dispatch( - WManagerSettingsActions.setGlobalWorkAreaOffset({ - ...workAreaOffset, - [side]: value || 0, - }), - ); - }; - - const onChangeDefaultGap = (value: number | null) => { - dispatch(WManagerSettingsActions.setWorkspaceGap(value || 0)); - }; - - const onChangeDefaultPadding = (value: number | null) => { - dispatch(WManagerSettingsActions.setWorkspacePadding(value || 0)); - }; - - return ( - -
- - {t('wm.space_between_containers')} - - - - {t('wm.workspace_padding')} - - -
- - - {t('sides.left')} - - - - {t('sides.top')} - - - - {t('sides.right')} - - - - {t('sides.bottom')} - - - -
- ); -}; +import { SettingsGroup, SettingsOption, SettingsSubGroup } from '../../../../components/SettingsBox'; +import { InputNumber } from 'antd'; +import { useTranslation } from 'react-i18next'; +import { useDispatch } from 'react-redux'; + +import { useAppSelector } from '../../../shared/utils/infra'; + +import { SeelenWmSelectors } from '../../../shared/store/app/selectors'; +import { Rect } from '../../../shared/utils/app/Rect'; +import { WManagerSettingsActions } from '../app'; + +export const GlobalPaddings = () => { + const workspaceGap = useAppSelector(SeelenWmSelectors.workspaceGap); + const workspacePadding = useAppSelector(SeelenWmSelectors.workspacePadding); + const workAreaOffset = useAppSelector(SeelenWmSelectors.globalWorkAreaOffset); + + const dispatch = useDispatch(); + const { t } = useTranslation(); + + const onChangeGlobalOffset = (side: keyof Rect, value: number | null) => { + dispatch( + WManagerSettingsActions.setGlobalWorkAreaOffset({ + ...workAreaOffset, + [side]: value || 0, + }), + ); + }; + + const onChangeDefaultGap = (value: number | null) => { + dispatch(WManagerSettingsActions.setWorkspaceGap(value || 0)); + }; + + const onChangeDefaultPadding = (value: number | null) => { + dispatch(WManagerSettingsActions.setWorkspacePadding(value || 0)); + }; + + return ( + +
+ + {t('wm.space_between_containers')} + + + + {t('wm.workspace_padding')} + + +
+ + + {t('sides.left')} + + + + {t('sides.top')} + + + + {t('sides.right')} + + + + {t('sides.bottom')} + + + +
+ ); +}; diff --git a/src/apps/settings/modules/WindowManager/main/infra/Others.tsx b/src/apps/settings/modules/WindowManager/main/infra/Others.tsx index 7ecb8ebb..f2fed1c1 100644 --- a/src/apps/settings/modules/WindowManager/main/infra/Others.tsx +++ b/src/apps/settings/modules/WindowManager/main/infra/Others.tsx @@ -1,31 +1,31 @@ -import { SettingsGroup, SettingsOption } from '../../../../components/SettingsBox'; -import { InputNumber } from 'antd'; -import { useTranslation } from 'react-i18next'; -import { useDispatch } from 'react-redux'; - -import { useAppSelector } from '../../../shared/utils/infra'; - -import { SeelenWmSelectors } from '../../../shared/store/app/selectors'; -import { WManagerSettingsActions } from '../app'; - -export const OthersConfigs = () => { - const resizeDelta = useAppSelector(SeelenWmSelectors.resizeDelta); - - const dispatch = useDispatch(); - const { t } = useTranslation(); - - const onChangeResizeDelta = (value: number | null) => { - dispatch(WManagerSettingsActions.setResizeDelta(value || 0)); - }; - - return ( - <> - - - {t('wm.resize_delta')} - - - - - ); -}; +import { SettingsGroup, SettingsOption } from '../../../../components/SettingsBox'; +import { InputNumber } from 'antd'; +import { useTranslation } from 'react-i18next'; +import { useDispatch } from 'react-redux'; + +import { useAppSelector } from '../../../shared/utils/infra'; + +import { SeelenWmSelectors } from '../../../shared/store/app/selectors'; +import { WManagerSettingsActions } from '../app'; + +export const OthersConfigs = () => { + const resizeDelta = useAppSelector(SeelenWmSelectors.resizeDelta); + + const dispatch = useDispatch(); + const { t } = useTranslation(); + + const onChangeResizeDelta = (value: number | null) => { + dispatch(WManagerSettingsActions.setResizeDelta(value || 0)); + }; + + return ( + <> + + + {t('wm.resize_delta')} + + + + + ); +}; diff --git a/src/apps/settings/modules/WindowManager/main/infra/index.tsx b/src/apps/settings/modules/WindowManager/main/infra/index.tsx index 79c8518a..472825a4 100644 --- a/src/apps/settings/modules/WindowManager/main/infra/index.tsx +++ b/src/apps/settings/modules/WindowManager/main/infra/index.tsx @@ -1,94 +1,94 @@ -import { SettingsGroup, SettingsOption } from '../../../../components/SettingsBox'; -import { GlobalPaddings } from './GlobalPaddings'; -import { OthersConfigs } from './Others'; -import { invoke } from '@tauri-apps/api/core'; -import { Select, Switch } from 'antd'; -import { useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useDispatch, useSelector } from 'react-redux'; - -import { BorderSettings } from '../../border/infra'; - -import { newSelectors } from '../../../shared/store/app/reducer'; -import { RootSelectors } from '../../../shared/store/app/selectors'; -import { WManagerSettingsActions } from '../app'; - -export function WindowManagerSettings() { - const [isWindows10, setIsWindows10] = useState(false); - - const settings = useSelector(RootSelectors.windowManager); - const layouts = useSelector(newSelectors.availableLayouts); - const defaultLayout = useSelector(newSelectors.windowManager.defaultLayout); - - const dispatch = useDispatch(); - const { t } = useTranslation(); - - useEffect(() => { - invoke('get_win_version').then((ver) => setIsWindows10(ver === 'Windows10')); - }, []); - - const onToggleEnable = (value: boolean) => { - dispatch(WManagerSettingsActions.setEnabled(value)); - }; - - const onSelectLayout = (value: string) => { - dispatch(WManagerSettingsActions.setDefaultLayout(value)); - }; - - const usingLayout = layouts.find((layout) => layout.info.filename === defaultLayout); - - return ( - <> - {isWindows10 && ( - -
-

{t('wm.disabled_windows10')}

-
-
- )} - - - -
- {t('wm.enable')} -
- -
-
- - - -
- {t('wm.layout')}: -
- ({ + key: `layout-${idx}`, + label: layout.info.displayName, + value: layout.info.filename, + }))} + onSelect={onSelectLayout} + /> +
+
+

+ {t('wm.author')}: + {usingLayout?.info.author} +

+

+ {t('wm.description')}: + {usingLayout?.info.description} +

+
+
+ + + + + + + + ); +} diff --git a/src/apps/settings/modules/appsConfigurations/app/filters.ts b/src/apps/settings/modules/appsConfigurations/app/filters.ts index c9ae7c93..06815a2d 100644 --- a/src/apps/settings/modules/appsConfigurations/app/filters.ts +++ b/src/apps/settings/modules/appsConfigurations/app/filters.ts @@ -1,24 +1,24 @@ - -export const getSorterByText = (key: string) => (paramA: anyObject, paramB: anyObject) => { - const a = String(paramA[key]).toLowerCase(); - const b = String(paramB[key]).toLowerCase(); - if (a < b) { - return -1; - } - if (a > b) { - return 1; - } - return 0; -}; - -export const getSorterByBool = (key: string) => (paramA: anyObject, paramB: anyObject) => { - const a = Boolean(paramA[key]); - const b = Boolean(paramB[key]); - if (!a && b) { - return 1; - } - if (a && !b) { - return -1; - } - return 0; + +export const getSorterByText = (key: string) => (paramA: anyObject, paramB: anyObject) => { + const a = String(paramA[key]).toLowerCase(); + const b = String(paramB[key]).toLowerCase(); + if (a < b) { + return -1; + } + if (a > b) { + return 1; + } + return 0; +}; + +export const getSorterByBool = (key: string) => (paramA: anyObject, paramB: anyObject) => { + const a = Boolean(paramA[key]); + const b = Boolean(paramB[key]); + if (!a && b) { + return 1; + } + if (a && !b) { + return -1; + } + return 0; }; \ No newline at end of file diff --git a/src/apps/settings/modules/appsConfigurations/app/reducer.ts b/src/apps/settings/modules/appsConfigurations/app/reducer.ts index 5ae55002..55be39c4 100644 --- a/src/apps/settings/modules/appsConfigurations/app/reducer.ts +++ b/src/apps/settings/modules/appsConfigurations/app/reducer.ts @@ -1,45 +1,45 @@ -import { createSlice, PayloadAction } from '@reduxjs/toolkit'; - -import { AppConfiguration } from '../domain'; - -const initialState: AppConfiguration[] = []; - -interface AppPayload { - idx: number; -} - -export const AppsConfigSlice = createSlice({ - name: 'monitors', - initialState, - reducers: { - delete: (state, action: PayloadAction) => { - state.splice(action.payload, 1); - }, - deleteMany: (state, action: PayloadAction) => { - const newState: any[] = [...state]; - action.payload.forEach((key) => { - newState[key] = undefined; - }); - return newState.filter(Boolean); - }, - push: (state, action: PayloadAction) => { - state.push(...action.payload); - }, - replace: (state, action: PayloadAction) => { - const { idx, app } = action.payload; - state[idx] = app; - }, - swap: (state, action: PayloadAction<[number, number]>) => { - const [idx1, idx2] = action.payload; - const App1 = state[idx1]; - const App2 = state[idx2]; - - if (App1 && App2) { - state[idx1] = App2; - state[idx2] = App1; - } - }, - }, -}); - -export const AppsConfigActions = AppsConfigSlice.actions; +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + +import { AppConfiguration } from '../domain'; + +const initialState: AppConfiguration[] = []; + +interface AppPayload { + idx: number; +} + +export const AppsConfigSlice = createSlice({ + name: 'monitors', + initialState, + reducers: { + delete: (state, action: PayloadAction) => { + state.splice(action.payload, 1); + }, + deleteMany: (state, action: PayloadAction) => { + const newState: any[] = [...state]; + action.payload.forEach((key) => { + newState[key] = undefined; + }); + return newState.filter(Boolean); + }, + push: (state, action: PayloadAction) => { + state.push(...action.payload); + }, + replace: (state, action: PayloadAction) => { + const { idx, app } = action.payload; + state[idx] = app; + }, + swap: (state, action: PayloadAction<[number, number]>) => { + const [idx1, idx2] = action.payload; + const App1 = state[idx1]; + const App2 = state[idx2]; + + if (App1 && App2) { + state[idx1] = App2; + state[idx2] = App1; + } + }, + }, +}); + +export const AppsConfigActions = AppsConfigSlice.actions; diff --git a/src/apps/settings/modules/appsConfigurations/domain.ts b/src/apps/settings/modules/appsConfigurations/domain.ts index 19534b66..b75b7c18 100644 --- a/src/apps/settings/modules/appsConfigurations/domain.ts +++ b/src/apps/settings/modules/appsConfigurations/domain.ts @@ -1,62 +1,62 @@ -import { IdWithIdentifier } from '../../../shared/schemas/AppsConfigurations'; - -export enum ApplicationOptions { - Float = 'float', - Unmanage = 'unmanage', - ForceManage = 'force', - Pinned = 'pinned', -} - -export enum ApplicationIdentifier { - Exe = 'Exe', - Class = 'Class', - Title = 'Title', - Path = 'Path', -} - -export enum MatchingStrategy { - Legacy = 'Legacy', - Equals = 'Equals', - StartsWith = 'StartsWith', - EndsWith = 'EndsWith', - Contains = 'Contains', - Regex = 'Regex', -} - -type AppConfigurationsOptions = { [K in ApplicationOptions]: boolean }; -export interface AppConfiguration extends AppConfigurationsOptions { - name: string; - category: string | null; - workspace: string | null; - monitor: number | null; - identifier: IdWithIdentifier; - isBundled: boolean; -} - -export interface AppConfigurationExtended extends AppConfiguration { - key: number; -} - -export class AppConfiguration { - static default(): AppConfiguration { - return { - name: 'New App', - category: null, - workspace: null, - monitor: null, - identifier: { - id: 'new-app.exe', - kind: ApplicationIdentifier.Exe, - matchingStrategy: MatchingStrategy.Equals, - negation: false, - and: [], - or: [], - }, - isBundled: false, - [ApplicationOptions.Float]: false, - [ApplicationOptions.Unmanage]: false, - [ApplicationOptions.Pinned]: false, - [ApplicationOptions.ForceManage]: false, - }; - } -} +import { IdWithIdentifier } from '../../../shared/schemas/AppsConfigurations'; + +export enum ApplicationOptions { + Float = 'float', + Unmanage = 'unmanage', + ForceManage = 'force', + Pinned = 'pinned', +} + +export enum ApplicationIdentifier { + Exe = 'Exe', + Class = 'Class', + Title = 'Title', + Path = 'Path', +} + +export enum MatchingStrategy { + Legacy = 'Legacy', + Equals = 'Equals', + StartsWith = 'StartsWith', + EndsWith = 'EndsWith', + Contains = 'Contains', + Regex = 'Regex', +} + +type AppConfigurationsOptions = { [K in ApplicationOptions]: boolean }; +export interface AppConfiguration extends AppConfigurationsOptions { + name: string; + category: string | null; + workspace: string | null; + monitor: number | null; + identifier: IdWithIdentifier; + isBundled: boolean; +} + +export interface AppConfigurationExtended extends AppConfiguration { + key: number; +} + +export class AppConfiguration { + static default(): AppConfiguration { + return { + name: 'New App', + category: null, + workspace: null, + monitor: null, + identifier: { + id: 'new-app.exe', + kind: ApplicationIdentifier.Exe, + matchingStrategy: MatchingStrategy.Equals, + negation: false, + and: [], + or: [], + }, + isBundled: false, + [ApplicationOptions.Float]: false, + [ApplicationOptions.Unmanage]: false, + [ApplicationOptions.Pinned]: false, + [ApplicationOptions.ForceManage]: false, + }; + } +} diff --git a/src/apps/settings/modules/appsConfigurations/infra/EditModal.tsx b/src/apps/settings/modules/appsConfigurations/infra/EditModal.tsx index 7431f088..6750bb5b 100644 --- a/src/apps/settings/modules/appsConfigurations/infra/EditModal.tsx +++ b/src/apps/settings/modules/appsConfigurations/infra/EditModal.tsx @@ -1,163 +1,163 @@ -import { IdWithIdentifier } from '../../../../shared/schemas/AppsConfigurations'; -import { SettingsGroup, SettingsOption, SettingsSubGroup } from '../../../components/SettingsBox'; -import { Identifier } from './Identifier'; -import { createSelector } from '@reduxjs/toolkit'; -import { ConfigProvider, Input, Modal, Select, Switch } from 'antd'; -import React, { useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; - -import { ownSelector, RootSelectors } from '../../shared/store/app/selectors'; - -import { RootState } from '../../shared/store/domain'; -import { AppConfiguration, AppConfigurationExtended, ApplicationOptions } from '../domain'; - -import cs from './index.module.css'; - -interface Props { - idx?: number; - open: boolean; - onSave: (app: AppConfigurationExtended) => void; - onCancel: () => void; - isNew?: boolean; - readonlyApp?: AppConfigurationExtended; -} - -const getAppSelector = (idx: number | undefined, isNew: boolean) => - createSelector([ownSelector], (state: RootState) => { - return idx != null && !isNew ? state.appsConfigurations[idx]! : AppConfiguration.default(); - }); - -export const EditAppModal = ({ idx, onCancel, onSave, isNew, open, readonlyApp }: Props) => { - const { t } = useTranslation(); - - const monitors = useSelector(RootSelectors.monitors); - const _app = useSelector(getAppSelector(idx, !!isNew)); - const initialState = readonlyApp || _app; - const isReadonly = !!readonlyApp; - - const [app, setApp] = useState(initialState); - - useEffect(() => { - if (isNew && !open) { - // reset state on close - setApp(initialState); - } - }, [open]); - - const onInternalSave = () => { - onSave(app as AppConfigurationExtended); - }; - - const updateName = (e: React.ChangeEvent) => - setApp({ ...app, name: e.target.value }); - const updateCategory = (e: React.ChangeEvent) => - setApp({ ...app, category: e.target.value || null }); - - const onChangeIdentifier = (identifier: IdWithIdentifier) => setApp({ ...app, identifier }); - - const onSelectMonitor = (value: number | null) => setApp({ ...app, monitor: value }); - const onSelectWorkspace = (value: string | null) => setApp({ ...app, workspace: value }); - - const onChangeOption = (option: ApplicationOptions, value: boolean) => - setApp({ ...app, [option]: value }); - - const monitorsOptions = monitors.map((_, i) => ({ label: `Monitor ${i + 1}`, value: i })); - const workspaceOptions = - app.monitor != null && monitors[app.monitor] - ? monitors[app.monitor]?.workspaces.map(({ name }) => ({ label: name, value: name })) - : []; - - let title = t('apps_configurations.app.title_edit'); - let okText = t('apps_configurations.app.ok_edit'); - - if (isNew) { - title = t('apps_configurations.app.title_create'); - okText = t('apps_configurations.app.ok_create'); - } - - if (isReadonly) { - title = t('apps_configurations.app.title_readonly'); - okText = t('apps_configurations.app.ok_readonly'); - } - - return ( - - - {!!readonlyApp && ( - - {t('apps_configurations.bundled_title')} -

{t('apps_configurations.bundled_msg')}

-
- )} - - -
- - {t('apps_configurations.app.name')} - - - - {t('apps_configurations.app.category')} - - -
-
- - - - - - - {t('apps_configurations.app.monitor')} - - - - - - - - {Object.values(ApplicationOptions).map((value, i) => ( - - {t(`apps_configurations.app.options.${value}`)} - - - ))} - - -
-
- ); -}; +import { IdWithIdentifier } from '../../../../shared/schemas/AppsConfigurations'; +import { SettingsGroup, SettingsOption, SettingsSubGroup } from '../../../components/SettingsBox'; +import { Identifier } from './Identifier'; +import { createSelector } from '@reduxjs/toolkit'; +import { ConfigProvider, Input, Modal, Select, Switch } from 'antd'; +import React, { useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; + +import { ownSelector, RootSelectors } from '../../shared/store/app/selectors'; + +import { RootState } from '../../shared/store/domain'; +import { AppConfiguration, AppConfigurationExtended, ApplicationOptions } from '../domain'; + +import cs from './index.module.css'; + +interface Props { + idx?: number; + open: boolean; + onSave: (app: AppConfigurationExtended) => void; + onCancel: () => void; + isNew?: boolean; + readonlyApp?: AppConfigurationExtended; +} + +const getAppSelector = (idx: number | undefined, isNew: boolean) => + createSelector([ownSelector], (state: RootState) => { + return idx != null && !isNew ? state.appsConfigurations[idx]! : AppConfiguration.default(); + }); + +export const EditAppModal = ({ idx, onCancel, onSave, isNew, open, readonlyApp }: Props) => { + const { t } = useTranslation(); + + const monitors = useSelector(RootSelectors.monitors); + const _app = useSelector(getAppSelector(idx, !!isNew)); + const initialState = readonlyApp || _app; + const isReadonly = !!readonlyApp; + + const [app, setApp] = useState(initialState); + + useEffect(() => { + if (isNew && !open) { + // reset state on close + setApp(initialState); + } + }, [open]); + + const onInternalSave = () => { + onSave(app as AppConfigurationExtended); + }; + + const updateName = (e: React.ChangeEvent) => + setApp({ ...app, name: e.target.value }); + const updateCategory = (e: React.ChangeEvent) => + setApp({ ...app, category: e.target.value || null }); + + const onChangeIdentifier = (identifier: IdWithIdentifier) => setApp({ ...app, identifier }); + + const onSelectMonitor = (value: number | null) => setApp({ ...app, monitor: value }); + const onSelectWorkspace = (value: string | null) => setApp({ ...app, workspace: value }); + + const onChangeOption = (option: ApplicationOptions, value: boolean) => + setApp({ ...app, [option]: value }); + + const monitorsOptions = monitors.map((_, i) => ({ label: `Monitor ${i + 1}`, value: i })); + const workspaceOptions = + app.monitor != null && monitors[app.monitor] + ? monitors[app.monitor]?.workspaces.map(({ name }) => ({ label: name, value: name })) + : []; + + let title = t('apps_configurations.app.title_edit'); + let okText = t('apps_configurations.app.ok_edit'); + + if (isNew) { + title = t('apps_configurations.app.title_create'); + okText = t('apps_configurations.app.ok_create'); + } + + if (isReadonly) { + title = t('apps_configurations.app.title_readonly'); + okText = t('apps_configurations.app.ok_readonly'); + } + + return ( + + + {!!readonlyApp && ( + + {t('apps_configurations.bundled_title')} +

{t('apps_configurations.bundled_msg')}

+
+ )} + + +
+ + {t('apps_configurations.app.name')} + + + + {t('apps_configurations.app.category')} + + +
+
+ + + + + + + {t('apps_configurations.app.monitor')} + + + + + + + + {Object.values(ApplicationOptions).map((value, i) => ( + + {t(`apps_configurations.app.options.${value}`)} + + + ))} + + +
+
+ ); +}; diff --git a/src/apps/settings/modules/appsConfigurations/infra/Identifier.module.css b/src/apps/settings/modules/appsConfigurations/infra/Identifier.module.css index 5f9c9f5b..b8f21e79 100644 --- a/src/apps/settings/modules/appsConfigurations/infra/Identifier.module.css +++ b/src/apps/settings/modules/appsConfigurations/infra/Identifier.module.css @@ -1,7 +1,7 @@ - -.removeButton { - display: flex; - gap: 6px; - align-items: center; - justify-content: center; + +.removeButton { + display: flex; + gap: 6px; + align-items: center; + justify-content: center; } \ No newline at end of file diff --git a/src/apps/settings/modules/appsConfigurations/infra/Identifier.tsx b/src/apps/settings/modules/appsConfigurations/infra/Identifier.tsx index 33795d94..6fcc2dc6 100644 --- a/src/apps/settings/modules/appsConfigurations/infra/Identifier.tsx +++ b/src/apps/settings/modules/appsConfigurations/infra/Identifier.tsx @@ -1,136 +1,136 @@ -import { Icon } from '../../../../shared/components/Icon'; -import { - ApplicationIdentifier, - IdWithIdentifier, - MatchingStrategy, -} from '../../../../shared/schemas/AppsConfigurations'; -import { SettingsGroup, SettingsOption } from '../../../components/SettingsBox'; -import { Button, Input, Select, Switch } from 'antd'; -import { useTranslation } from 'react-i18next'; - -import { OptionsFromEnum } from '../../shared/utils/app'; - -import cs from './Identifier.module.css'; - -interface Props { - identifier: IdWithIdentifier; - onChange: (id: IdWithIdentifier) => void; - onRemove?: () => void; -} - -export function Identifier({ identifier, onChange, onRemove }: Props) { - const { id, kind, matchingStrategy } = identifier; - - const { t } = useTranslation(); - - const onChangeId = (e: React.ChangeEvent) => { - onChange({ ...identifier, id: e.target.value }); - }; - - const onSelectKind = (value: ApplicationIdentifier) => { - onChange({ ...identifier, kind: value }); - }; - - const onSelectMatchingStrategy = (value: MatchingStrategy) => { - onChange({ ...identifier, matchingStrategy: value }); - }; - - const onChangeNegation = (value: boolean) => { - onChange({ ...identifier, negation: value }); - }; - - const onChangeAndItem = (idx: number, value: IdWithIdentifier) => { - onChange({ ...identifier, and: identifier.and.map((id, i) => (i === idx ? value : id)) }); - }; - - const onChangeOrItem = (idx: number, value: IdWithIdentifier) => { - onChange({ ...identifier, or: identifier.or.map((id, i) => (i === idx ? value : id)) }); - }; - - const onRemoveAndItem = (idx: number) => { - onChange({ ...identifier, and: identifier.and.filter((_, i) => i !== idx) }); - }; - - const onRemoveOrItem = (idx: number) => { - onChange({ ...identifier, or: identifier.or.filter((_, i) => i !== idx) }); - }; - - const onAddAndItem = () => { - onChange({ ...identifier, and: [IdWithIdentifier.default(), ...identifier.and] }); - }; - - const onAddOrItem = () => { - onChange({ ...identifier, or: [IdWithIdentifier.default(), ...identifier.or] }); - }; - - return ( - -
- {onRemove && ( - - {t('apps_configurations.identifier.remove')} - - - )} - - {t('apps_configurations.identifier.id')} - - - - {t('apps_configurations.identifier.kind')} - - - - {t('apps_configurations.identifier.negation')} - - - -
- - - {t('apps_configurations.identifier.and')} - - - {identifier.and.map((id, idx) => ( - onChangeAndItem(idx, value)} - onRemove={() => onRemoveAndItem(idx)} - /> - ))} - - - {t('apps_configurations.identifier.or')} - - - {identifier.or.map((id, idx) => ( - onChangeOrItem(idx, value)} - onRemove={() => onRemoveOrItem(idx)} - /> - ))} -
-
- ); -} +import { Icon } from '../../../../shared/components/Icon'; +import { + ApplicationIdentifier, + IdWithIdentifier, + MatchingStrategy, +} from '../../../../shared/schemas/AppsConfigurations'; +import { SettingsGroup, SettingsOption } from '../../../components/SettingsBox'; +import { Button, Input, Select, Switch } from 'antd'; +import { useTranslation } from 'react-i18next'; + +import { OptionsFromEnum } from '../../shared/utils/app'; + +import cs from './Identifier.module.css'; + +interface Props { + identifier: IdWithIdentifier; + onChange: (id: IdWithIdentifier) => void; + onRemove?: () => void; +} + +export function Identifier({ identifier, onChange, onRemove }: Props) { + const { id, kind, matchingStrategy } = identifier; + + const { t } = useTranslation(); + + const onChangeId = (e: React.ChangeEvent) => { + onChange({ ...identifier, id: e.target.value }); + }; + + const onSelectKind = (value: ApplicationIdentifier) => { + onChange({ ...identifier, kind: value }); + }; + + const onSelectMatchingStrategy = (value: MatchingStrategy) => { + onChange({ ...identifier, matchingStrategy: value }); + }; + + const onChangeNegation = (value: boolean) => { + onChange({ ...identifier, negation: value }); + }; + + const onChangeAndItem = (idx: number, value: IdWithIdentifier) => { + onChange({ ...identifier, and: identifier.and.map((id, i) => (i === idx ? value : id)) }); + }; + + const onChangeOrItem = (idx: number, value: IdWithIdentifier) => { + onChange({ ...identifier, or: identifier.or.map((id, i) => (i === idx ? value : id)) }); + }; + + const onRemoveAndItem = (idx: number) => { + onChange({ ...identifier, and: identifier.and.filter((_, i) => i !== idx) }); + }; + + const onRemoveOrItem = (idx: number) => { + onChange({ ...identifier, or: identifier.or.filter((_, i) => i !== idx) }); + }; + + const onAddAndItem = () => { + onChange({ ...identifier, and: [IdWithIdentifier.default(), ...identifier.and] }); + }; + + const onAddOrItem = () => { + onChange({ ...identifier, or: [IdWithIdentifier.default(), ...identifier.or] }); + }; + + return ( + +
+ {onRemove && ( + + {t('apps_configurations.identifier.remove')} + + + )} + + {t('apps_configurations.identifier.id')} + + + + {t('apps_configurations.identifier.kind')} + + + + {t('apps_configurations.identifier.negation')} + + + +
+ + + {t('apps_configurations.identifier.and')} + + + {identifier.and.map((id, idx) => ( + onChangeAndItem(idx, value)} + onRemove={() => onRemoveAndItem(idx)} + /> + ))} + + + {t('apps_configurations.identifier.or')} + + + {identifier.or.map((id, idx) => ( + onChangeOrItem(idx, value)} + onRemove={() => onRemoveOrItem(idx)} + /> + ))} +
+
+ ); +} diff --git a/src/apps/settings/modules/appsConfigurations/infra/index.module.css b/src/apps/settings/modules/appsConfigurations/infra/index.module.css index c95e815c..ba5f7ae1 100644 --- a/src/apps/settings/modules/appsConfigurations/infra/index.module.css +++ b/src/apps/settings/modules/appsConfigurations/infra/index.module.css @@ -1,61 +1,61 @@ -.newBtn { - width: 100%; - background-color: var(--color-green-600); - padding: 0; - - &:hover { - background-color: var(--color-green-700) !important; - } -} - -.actions { - button { - width: 100%; - } -} - -.table { - :global(.ant-pagination-options) { - display: none; - } - - :global(.ant-empty) { - margin: 119px; - } - - :global(.ant-table-body) { - :global(.ant-table-cell) { - text-wrap: nowrap; - text-overflow: ellipsis; - overflow: hidden; - } - } - - :global(.ant-pagination) { - margin-top: 10px !important; - margin-bottom: 0 !important; - } -} - - -.editModal { - :global(.ant-modal-body) { - padding-right: 10px; - } - - :global(.ant-select) { - min-width: 150px; - } -} - -.footer { - display: flex; - gap: 10px; - align-items: center; - position: absolute; - bottom: 15px; - - button { - width: 80px; - } +.newBtn { + width: 100%; + background-color: var(--color-green-600); + padding: 0; + + &:hover { + background-color: var(--color-green-700) !important; + } +} + +.actions { + button { + width: 100%; + } +} + +.table { + :global(.ant-pagination-options) { + display: none; + } + + :global(.ant-empty) { + margin: 119px; + } + + :global(.ant-table-body) { + :global(.ant-table-cell) { + text-wrap: nowrap; + text-overflow: ellipsis; + overflow: hidden; + } + } + + :global(.ant-pagination) { + margin-top: 10px !important; + margin-bottom: 0 !important; + } +} + + +.editModal { + :global(.ant-modal-body) { + padding-right: 10px; + } + + :global(.ant-select) { + min-width: 150px; + } +} + +.footer { + display: flex; + gap: 10px; + align-items: center; + position: absolute; + bottom: 15px; + + button { + width: 80px; + } } \ No newline at end of file diff --git a/src/apps/settings/modules/appsConfigurations/infra/infra.tsx b/src/apps/settings/modules/appsConfigurations/infra/infra.tsx index 65b40da1..8b37226a 100644 --- a/src/apps/settings/modules/appsConfigurations/infra/infra.tsx +++ b/src/apps/settings/modules/appsConfigurations/infra/infra.tsx @@ -1,256 +1,256 @@ -import { ExportApps, ImportApps } from '../../shared/store/storeApi'; -import { EditAppModal } from './EditModal'; -import { Button, Input, Modal, Switch, Table, Tooltip } from 'antd'; -import { ColumnsType, ColumnType } from 'antd/es/table'; -import { TFunction } from 'i18next'; -import { cloneDeep } from 'lodash'; -import { ChangeEvent, useCallback, useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useDispatch } from 'react-redux'; - -import { useAppSelector } from '../../shared/utils/infra'; - -import { RootSelectors } from '../../shared/store/app/selectors'; -import { StateAppsToYamlApps, YamlToState_Apps } from '../../shared/store/app/StateBridge'; -import { cx, debounce } from '../../shared/utils/app'; -import { getSorterByBool, getSorterByText } from '../app/filters'; -import { AppsConfigActions } from '../app/reducer'; - -import { AppConfiguration, AppConfigurationExtended, ApplicationOptions } from '../domain'; - -import cs from './index.module.css'; - -const ReadonlySwitch = (value: boolean, record: AppConfigurationExtended, _index: number) => { - return ( - - ); -}; - -const getColumns = (t: TFunction): ColumnsType => { - return [ - { - title: t('apps_configurations.app.name'), - dataIndex: 'name', - key: 'name', - fixed: 'left', - width: 120, - sorter: getSorterByText('name'), - render: (name) => ( - - {name} - - ), - }, - { - title: t('apps_configurations.app.category'), - dataIndex: 'category', - key: 'category', - width: 120, - render(value, _record, _index) { - return value || '-'; - }, - sorter: getSorterByText('category'), - }, - ...Object.values(ApplicationOptions).map( - (option) => - ({ - title: t(`apps_configurations.app.options.${option}`), - dataIndex: option, - key: option, - align: 'center', - width: 140, - render: ReadonlySwitch, - sorter: getSorterByBool(option), - } as ColumnType), - ), - { - title: , - key: 'operation', - fixed: 'right', - align: 'center', - width: 56, - render: (_, record, index) => , - }, - ]; -}; - -function ActionsTitle() { - const [isModalOpen, setIsModalOpen] = useState(false); - - const dispatch = useDispatch(); - const { t } = useTranslation(); - - const showModal = () => setIsModalOpen(true); - const onCancel = () => setIsModalOpen(false); - const onSave = (app: AppConfiguration) => { - dispatch(AppsConfigActions.push([app])); - setIsModalOpen(false); - }; - - return ( -
- - -
- ); -} - -function Actions({ record }: { record: AppConfigurationExtended; index: number }) { - const [isModalOpen, setIsModalOpen] = useState(false); - const dispatch = useDispatch(); - - const showModal = () => setIsModalOpen(true); - const onCancel = () => setIsModalOpen(false); - const onSave = (app: AppConfigurationExtended) => { - if (record.isBundled) { - let newApp = cloneDeep(app); - newApp.isBundled = false; - dispatch(AppsConfigActions.push([newApp])); - } else { - dispatch(AppsConfigActions.replace({ idx: record.key, app })); - } - setIsModalOpen(false); - }; - - return ( -
- {isModalOpen && ( - - )} - -
- ); -} - -export function AppsConfiguration() { - const [delay, setDelay] = useState(300); - const [loading, setLoading] = useState(true); - const [selectedAppsKey, setSelectedAppsKey] = useState([]); - const [searched, setSearched] = useState(''); - const [data, setData] = useState([]); - - const apps = useAppSelector(RootSelectors.appsConfigurations); - - useEffect(() => { - const data: AppConfigurationExtended[] = []; - - apps.forEach((app, index) => data.unshift({ ...app, key: index })); - - setTimeout(() => { - setData( - data.filter((app) => { - return ( - app.name.toLowerCase().includes(searched) || - app.identifier.id.toLowerCase().includes(searched) || - app.identifier.and.some((id) => id.id.toLowerCase().includes(searched)) || - app.identifier.or.some((id) => id.id.toLowerCase().includes(searched)) - ); - }), - ); - setLoading(false); - setDelay(0); - }, delay); - }, [apps, searched]); - - const dispatch = useDispatch(); - const { t } = useTranslation(); - - const importApps = useCallback(async () => { - const yamlApps = await ImportApps(); - const newApps = YamlToState_Apps(yamlApps); - dispatch(AppsConfigActions.push(newApps)); - }, []); - - const performSwap = useCallback(() => { - dispatch(AppsConfigActions.swap(selectedAppsKey as [number, number])); - }, [selectedAppsKey]); - - const exportApps = useCallback(() => { - const appsToExport = selectedAppsKey.map((key) => apps[key]!); - ExportApps(StateAppsToYamlApps(appsToExport)); - }, [apps, selectedAppsKey]); - - const confirmDelete = useCallback(() => { - const modal = Modal.confirm({ - title: t('apps_configurations.confirm_delete_title'), - content: t('apps_configurations.confirm_delete'), - okText: t('delete'), - onOk: () => { - dispatch(AppsConfigActions.deleteMany(selectedAppsKey)); - setSelectedAppsKey([]); - modal.destroy(); - }, - okButtonProps: { danger: true }, - cancelText: t('cancel'), - centered: true, - }); - }, [selectedAppsKey]); - - const onSearch = useCallback( - debounce((e: ChangeEvent) => { - setSearched(e.target.value.toLowerCase()); - }, 200), - [], - ); - - const columns = getColumns(t); - columns[0]!.title = ( - e.stopPropagation()} - placeholder={t('apps_configurations.search')} - /> - ); - - return ( - <> - -
- - - - -
- - ); -} +import { ExportApps, ImportApps } from '../../shared/store/storeApi'; +import { EditAppModal } from './EditModal'; +import { Button, Input, Modal, Switch, Table, Tooltip } from 'antd'; +import { ColumnsType, ColumnType } from 'antd/es/table'; +import { TFunction } from 'i18next'; +import { cloneDeep } from 'lodash'; +import { ChangeEvent, useCallback, useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useDispatch } from 'react-redux'; + +import { useAppSelector } from '../../shared/utils/infra'; + +import { RootSelectors } from '../../shared/store/app/selectors'; +import { StateAppsToYamlApps, YamlToState_Apps } from '../../shared/store/app/StateBridge'; +import { cx, debounce } from '../../shared/utils/app'; +import { getSorterByBool, getSorterByText } from '../app/filters'; +import { AppsConfigActions } from '../app/reducer'; + +import { AppConfiguration, AppConfigurationExtended, ApplicationOptions } from '../domain'; + +import cs from './index.module.css'; + +const ReadonlySwitch = (value: boolean, record: AppConfigurationExtended, _index: number) => { + return ( + + ); +}; + +const getColumns = (t: TFunction): ColumnsType => { + return [ + { + title: t('apps_configurations.app.name'), + dataIndex: 'name', + key: 'name', + fixed: 'left', + width: 120, + sorter: getSorterByText('name'), + render: (name) => ( + + {name} + + ), + }, + { + title: t('apps_configurations.app.category'), + dataIndex: 'category', + key: 'category', + width: 120, + render(value, _record, _index) { + return value || '-'; + }, + sorter: getSorterByText('category'), + }, + ...Object.values(ApplicationOptions).map( + (option) => + ({ + title: t(`apps_configurations.app.options.${option}`), + dataIndex: option, + key: option, + align: 'center', + width: 140, + render: ReadonlySwitch, + sorter: getSorterByBool(option), + } as ColumnType), + ), + { + title: , + key: 'operation', + fixed: 'right', + align: 'center', + width: 56, + render: (_, record, index) => , + }, + ]; +}; + +function ActionsTitle() { + const [isModalOpen, setIsModalOpen] = useState(false); + + const dispatch = useDispatch(); + const { t } = useTranslation(); + + const showModal = () => setIsModalOpen(true); + const onCancel = () => setIsModalOpen(false); + const onSave = (app: AppConfiguration) => { + dispatch(AppsConfigActions.push([app])); + setIsModalOpen(false); + }; + + return ( +
+ + +
+ ); +} + +function Actions({ record }: { record: AppConfigurationExtended; index: number }) { + const [isModalOpen, setIsModalOpen] = useState(false); + const dispatch = useDispatch(); + + const showModal = () => setIsModalOpen(true); + const onCancel = () => setIsModalOpen(false); + const onSave = (app: AppConfigurationExtended) => { + if (record.isBundled) { + let newApp = cloneDeep(app); + newApp.isBundled = false; + dispatch(AppsConfigActions.push([newApp])); + } else { + dispatch(AppsConfigActions.replace({ idx: record.key, app })); + } + setIsModalOpen(false); + }; + + return ( +
+ {isModalOpen && ( + + )} + +
+ ); +} + +export function AppsConfiguration() { + const [delay, setDelay] = useState(300); + const [loading, setLoading] = useState(true); + const [selectedAppsKey, setSelectedAppsKey] = useState([]); + const [searched, setSearched] = useState(''); + const [data, setData] = useState([]); + + const apps = useAppSelector(RootSelectors.appsConfigurations); + + useEffect(() => { + const data: AppConfigurationExtended[] = []; + + apps.forEach((app, index) => data.unshift({ ...app, key: index })); + + setTimeout(() => { + setData( + data.filter((app) => { + return ( + app.name.toLowerCase().includes(searched) || + app.identifier.id.toLowerCase().includes(searched) || + app.identifier.and.some((id) => id.id.toLowerCase().includes(searched)) || + app.identifier.or.some((id) => id.id.toLowerCase().includes(searched)) + ); + }), + ); + setLoading(false); + setDelay(0); + }, delay); + }, [apps, searched]); + + const dispatch = useDispatch(); + const { t } = useTranslation(); + + const importApps = useCallback(async () => { + const yamlApps = await ImportApps(); + const newApps = YamlToState_Apps(yamlApps); + dispatch(AppsConfigActions.push(newApps)); + }, []); + + const performSwap = useCallback(() => { + dispatch(AppsConfigActions.swap(selectedAppsKey as [number, number])); + }, [selectedAppsKey]); + + const exportApps = useCallback(() => { + const appsToExport = selectedAppsKey.map((key) => apps[key]!); + ExportApps(StateAppsToYamlApps(appsToExport)); + }, [apps, selectedAppsKey]); + + const confirmDelete = useCallback(() => { + const modal = Modal.confirm({ + title: t('apps_configurations.confirm_delete_title'), + content: t('apps_configurations.confirm_delete'), + okText: t('delete'), + onOk: () => { + dispatch(AppsConfigActions.deleteMany(selectedAppsKey)); + setSelectedAppsKey([]); + modal.destroy(); + }, + okButtonProps: { danger: true }, + cancelText: t('cancel'), + centered: true, + }); + }, [selectedAppsKey]); + + const onSearch = useCallback( + debounce((e: ChangeEvent) => { + setSearched(e.target.value.toLowerCase()); + }, 200), + [], + ); + + const columns = getColumns(t); + columns[0]!.title = ( + e.stopPropagation()} + placeholder={t('apps_configurations.search')} + /> + ); + + return ( + <> +
+
+ + + + +
+ + ); +} diff --git a/src/apps/settings/modules/developer/app.ts b/src/apps/settings/modules/developer/app.ts index 951357fc..09d6caac 100644 --- a/src/apps/settings/modules/developer/app.ts +++ b/src/apps/settings/modules/developer/app.ts @@ -1,19 +1,19 @@ -import { path } from '@tauri-apps/api'; -import * as dialog from '@tauri-apps/plugin-dialog'; - -import { LoadSettingsToStore } from '../shared/store/infra'; - -export async function LoadCustomConfigFile() { - const file = await dialog.open({ - defaultPath: await path.homeDir(), - multiple: false, - title: 'Select settings file', - filters: [{ name: 'settings', extensions: ['json'] }], - }); - - if (!file) { - return; - } - - LoadSettingsToStore(file.path); +import { path } from '@tauri-apps/api'; +import * as dialog from '@tauri-apps/plugin-dialog'; + +import { LoadSettingsToStore } from '../shared/store/infra'; + +export async function LoadCustomConfigFile() { + const file = await dialog.open({ + defaultPath: await path.homeDir(), + multiple: false, + title: 'Select settings file', + filters: [{ name: 'settings', extensions: ['json'] }], + }); + + if (!file) { + return; + } + + LoadSettingsToStore(file.path); } \ No newline at end of file diff --git a/src/apps/settings/modules/developer/infra.tsx b/src/apps/settings/modules/developer/infra.tsx index b60eb6b4..58882eec 100644 --- a/src/apps/settings/modules/developer/infra.tsx +++ b/src/apps/settings/modules/developer/infra.tsx @@ -1,69 +1,69 @@ -import { SettingsGroup, SettingsOption, SettingsSubGroup } from '../../components/SettingsBox'; -import { path } from '@tauri-apps/api'; -import { invoke } from '@tauri-apps/api/core'; -import { Button, Switch } from 'antd'; -import { useTranslation } from 'react-i18next'; -import { useDispatch, useSelector } from 'react-redux'; - -import { resolveDataPath } from '../shared/config/infra'; - -import { newSelectors, RootActions } from '../shared/store/app/reducer'; -import { LoadCustomConfigFile } from './app'; - -export function DeveloperTools() { - const devTools = useSelector(newSelectors.devTools); - - const dispatch = useDispatch(); - const { t } = useTranslation(); - - function onToggleDevTools(value: boolean) { - dispatch(RootActions.setDevTools(value)); - } - - async function openSettingsFile() { - invoke('open_file', { path: await resolveDataPath('settings.json') }); - } - - async function openInstallFolder() { - invoke('open_file', { path: await path.resourceDir() }); - } - - async function openDataFolder() { - invoke('open_file', { path: await path.appDataDir() }); - } - - return ( - <> - - - {t('devtools.enable')} - - - - - - - - {t('devtools.install_folder')} - - - - {t('devtools.data_folder')} - - - - - - - - {t('devtools.settings_file')} - - - - {t('devtools.custom_config_file')}: - - - - - ); -} +import { SettingsGroup, SettingsOption, SettingsSubGroup } from '../../components/SettingsBox'; +import { path } from '@tauri-apps/api'; +import { invoke } from '@tauri-apps/api/core'; +import { Button, Switch } from 'antd'; +import { useTranslation } from 'react-i18next'; +import { useDispatch, useSelector } from 'react-redux'; + +import { resolveDataPath } from '../shared/config/infra'; + +import { newSelectors, RootActions } from '../shared/store/app/reducer'; +import { LoadCustomConfigFile } from './app'; + +export function DeveloperTools() { + const devTools = useSelector(newSelectors.devTools); + + const dispatch = useDispatch(); + const { t } = useTranslation(); + + function onToggleDevTools(value: boolean) { + dispatch(RootActions.setDevTools(value)); + } + + async function openSettingsFile() { + invoke('open_file', { path: await resolveDataPath('settings.json') }); + } + + async function openInstallFolder() { + invoke('open_file', { path: await path.resourceDir() }); + } + + async function openDataFolder() { + invoke('open_file', { path: await path.appDataDir() }); + } + + return ( + <> + + + {t('devtools.enable')} + + + + + + + + {t('devtools.install_folder')} + + + + {t('devtools.data_folder')} + + + + + + + + {t('devtools.settings_file')} + + + + {t('devtools.custom_config_file')}: + + + + + ); +} diff --git a/src/apps/settings/modules/fancyToolbar/app.ts b/src/apps/settings/modules/fancyToolbar/app.ts index 11d3cffd..eb20d597 100644 --- a/src/apps/settings/modules/fancyToolbar/app.ts +++ b/src/apps/settings/modules/fancyToolbar/app.ts @@ -1,16 +1,16 @@ -import { parseAsCamel } from '../../../shared/schemas'; -import { FancyToolbar, FancyToolbarSchema } from '../../../shared/schemas/FancyToolbar'; -import { createSlice } from '@reduxjs/toolkit'; - -import { reducersFor, selectorsFor } from '../shared/utils/app'; - -const initialState: FancyToolbar = parseAsCamel(FancyToolbarSchema, {}); - -export const FancyToolbarSlice = createSlice({ - name: 'fancyToolbar', - initialState, - selectors: selectorsFor(initialState), - reducers: reducersFor(initialState), -}); - +import { parseAsCamel } from '../../../shared/schemas'; +import { FancyToolbar, FancyToolbarSchema } from '../../../shared/schemas/FancyToolbar'; +import { createSlice } from '@reduxjs/toolkit'; + +import { reducersFor, selectorsFor } from '../shared/utils/app'; + +const initialState: FancyToolbar = parseAsCamel(FancyToolbarSchema, {}); + +export const FancyToolbarSlice = createSlice({ + name: 'fancyToolbar', + initialState, + selectors: selectorsFor(initialState), + reducers: reducersFor(initialState), +}); + export const FancyToolbarActions = FancyToolbarSlice.actions; \ No newline at end of file diff --git a/src/apps/settings/modules/fancyToolbar/infra.tsx b/src/apps/settings/modules/fancyToolbar/infra.tsx index f5378c58..51032c70 100644 --- a/src/apps/settings/modules/fancyToolbar/infra.tsx +++ b/src/apps/settings/modules/fancyToolbar/infra.tsx @@ -1,83 +1,83 @@ -import { SettingsGroup, SettingsOption } from '../../components/SettingsBox'; -import { InputNumber, Select, Switch } from 'antd'; -import { useTranslation } from 'react-i18next'; -import { useDispatch, useSelector } from 'react-redux'; - -import { newSelectors } from '../shared/store/app/reducer'; -import { RootSelectors } from '../shared/store/app/selectors'; -import { FancyToolbarActions } from './app'; - -export function FancyToolbarSettings() { - const settings = useSelector(RootSelectors.fancyToolbar); - const placeholders = useSelector(newSelectors.availablePlaceholders); - const selectedStructure = useSelector(newSelectors.fancyToolbar.placeholder); - - const dispatch = useDispatch(); - const { t } = useTranslation(); - - const onToggleEnable = (value: boolean) => { - dispatch(FancyToolbarActions.setEnabled(value)); - }; - - const onSelectStructure = (value: string) => { - dispatch(FancyToolbarActions.setPlaceholder(value)); - }; - - const usingStructure = placeholders.find( - (placeholder) => placeholder.info.filename === selectedStructure, - ); - - return ( - <> - - -
- {t('toolbar.enable')} -
- -
-
- - - -
- {t('toolbar.placeholder.select')}: -
- ({ + key: `placeholder-${idx}`, + label: placeholder.info.displayName, + value: placeholder.info.filename, + }))} + onSelect={onSelectStructure} + /> +
+
+

+ {t('toolbar.placeholder.author')}: + {usingStructure?.info.author} +

+

+ {t('toolbar.placeholder.description')}: + {usingStructure?.info.description} +

+
+
+ + + +
+ {t('toolbar.height')} +
+ dispatch(FancyToolbarActions.setHeight(value || 0))} + min={0} + /> +
+
+ + ); +} diff --git a/src/apps/settings/modules/general/main/domain.ts b/src/apps/settings/modules/general/main/domain.ts index 2b84e9f1..0e4eaee5 100644 --- a/src/apps/settings/modules/general/main/domain.ts +++ b/src/apps/settings/modules/general/main/domain.ts @@ -1,18 +1,18 @@ - -export const TAGS_COLORS = [ - 'blue', - 'geekblue', - 'purple', - 'magenta', - 'red', - 'error', - 'volcano', - 'orange', - 'warning', - 'gold', - 'lime', - 'success', - 'green', - 'cyan', - 'processing', + +export const TAGS_COLORS = [ + 'blue', + 'geekblue', + 'purple', + 'magenta', + 'red', + 'error', + 'volcano', + 'orange', + 'warning', + 'gold', + 'lime', + 'success', + 'green', + 'cyan', + 'processing', ]; \ No newline at end of file diff --git a/src/apps/settings/modules/general/main/infra/Colors.tsx b/src/apps/settings/modules/general/main/infra/Colors.tsx index 229002f1..5eb95f44 100644 --- a/src/apps/settings/modules/general/main/infra/Colors.tsx +++ b/src/apps/settings/modules/general/main/infra/Colors.tsx @@ -1,40 +1,40 @@ -import { SettingsGroup, SettingsOption } from '../../../../components/SettingsBox'; -import { invoke } from '@tauri-apps/api/core'; -import { ColorPicker } from 'antd'; -import { useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; - -import { newSelectors } from '../../../shared/store/app/reducer'; - -import cs from './index.module.css'; - -export function Colors() { - const colors = useSelector(newSelectors.colors); - - const { t } = useTranslation(); - - return ( - - - {t('general.accent_color')} -
{ - e.stopPropagation(); - invoke('open_file', { path: 'ms-settings:colors' }).catch(console.error); - }} - > - -
-
-
-
-
-
-
-
-
-
-
- - ); -} +import { SettingsGroup, SettingsOption } from '../../../../components/SettingsBox'; +import { invoke } from '@tauri-apps/api/core'; +import { ColorPicker } from 'antd'; +import { useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; + +import { newSelectors } from '../../../shared/store/app/reducer'; + +import cs from './index.module.css'; + +export function Colors() { + const colors = useSelector(newSelectors.colors); + + const { t } = useTranslation(); + + return ( + + + {t('general.accent_color')} +
{ + e.stopPropagation(); + invoke('open_file', { path: 'ms-settings:colors' }).catch(console.error); + }} + > + +
+
+
+
+
+
+
+
+
+
+
+ + ); +} diff --git a/src/apps/settings/modules/general/main/infra/Themes.tsx b/src/apps/settings/modules/general/main/infra/Themes.tsx index 3d5594b7..6b03394e 100644 --- a/src/apps/settings/modules/general/main/infra/Themes.tsx +++ b/src/apps/settings/modules/general/main/infra/Themes.tsx @@ -1,98 +1,98 @@ -import { Checkbox, Tooltip, Transfer } from 'antd'; -import { Reorder } from 'framer-motion'; -import { useTranslation } from 'react-i18next'; -import { useDispatch, useSelector } from 'react-redux'; - -import { RootActions } from '../../../shared/store/app/reducer'; -import { RootSelectors } from '../../../shared/store/app/selectors'; - -import cs from './index.module.css'; - -export function Themes() { - const themes = useSelector(RootSelectors.availableThemes); - const usingThemes = useSelector(RootSelectors.selectedTheme); - - const dispatch = useDispatch(); - const { t } = useTranslation(); - - const dataSource = themes.map((theme) => ({ - ...theme, - key: theme.info.filename, - title: theme.info.displayName, - disabled: theme.info.filename === 'default', - })); - - return ( - { - dispatch(RootActions.setSelectedTheme(selected as string[])); - }} - className={cs.transfer} - showSelectAll={false} - > - {(props) => { - const { dataSource, selectedKeys, onItemSelect, direction } = props; - - return ( - { - if (direction === 'right') { - dispatch(RootActions.setSelectedTheme(values.map((theme) => theme.info.filename))); - } - }} - axis="y" - values={props.dataSource} - > - {dataSource.map((theme) => { - const key = theme.info.filename; - return ( - -

{theme.info.displayName}

-

- {t('general.theme.author')}: - {theme.info.author} -

-
-
- {t('general.theme.tags')}: -
- {theme.info.tags.map((tag) => ( -
- {tag} -
- ))} -
-

- {t('general.theme.description')}: - {theme.info.description} -

-
- } - > - - onItemSelect(key, e.target.checked)} - > - {theme.info.displayName} - - - - ); - })} - - ); - }} - - ); -} +import { Checkbox, Tooltip, Transfer } from 'antd'; +import { Reorder } from 'framer-motion'; +import { useTranslation } from 'react-i18next'; +import { useDispatch, useSelector } from 'react-redux'; + +import { RootActions } from '../../../shared/store/app/reducer'; +import { RootSelectors } from '../../../shared/store/app/selectors'; + +import cs from './index.module.css'; + +export function Themes() { + const themes = useSelector(RootSelectors.availableThemes); + const usingThemes = useSelector(RootSelectors.selectedTheme); + + const dispatch = useDispatch(); + const { t } = useTranslation(); + + const dataSource = themes.map((theme) => ({ + ...theme, + key: theme.info.filename, + title: theme.info.displayName, + disabled: theme.info.filename === 'default', + })); + + return ( + { + dispatch(RootActions.setSelectedTheme(selected as string[])); + }} + className={cs.transfer} + showSelectAll={false} + > + {(props) => { + const { dataSource, selectedKeys, onItemSelect, direction } = props; + + return ( + { + if (direction === 'right') { + dispatch(RootActions.setSelectedTheme(values.map((theme) => theme.info.filename))); + } + }} + axis="y" + values={props.dataSource} + > + {dataSource.map((theme) => { + const key = theme.info.filename; + return ( + +

{theme.info.displayName}

+

+ {t('general.theme.author')}: + {theme.info.author} +

+
+
+ {t('general.theme.tags')}: +
+ {theme.info.tags.map((tag) => ( +
+ {tag} +
+ ))} +
+

+ {t('general.theme.description')}: + {theme.info.description} +

+
+ } + > + + onItemSelect(key, e.target.checked)} + > + {theme.info.displayName} + + + + ); + })} + + ); + }} + + ); +} diff --git a/src/apps/settings/modules/general/main/infra/Wallpaper.tsx b/src/apps/settings/modules/general/main/infra/Wallpaper.tsx index 2f7f9b01..7bffa0f1 100644 --- a/src/apps/settings/modules/general/main/infra/Wallpaper.tsx +++ b/src/apps/settings/modules/general/main/infra/Wallpaper.tsx @@ -1,46 +1,46 @@ -import { Monitor } from '../../../../components/monitor'; -import { SettingsOption } from '../../../../components/SettingsBox'; -import { invoke } from '@tauri-apps/api/core'; -import { Button } from 'antd'; -import { useTranslation } from 'react-i18next'; -import { useDispatch } from 'react-redux'; - -import { dialog } from '../../../shared/tauri/infra'; - -import { RootActions } from '../../../shared/store/app/reducer'; - -import cs from './index.module.css'; - -export function Wallpaper() { - const { t } = useTranslation(); - const dispatch = useDispatch(); - - async function loadWallpaper() { - const file = await dialog.open({ - title: t('general.wallpaper.select'), - filters: [ - { name: 'images', extensions: ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'tif', 'tiff'] }, - ], - }); - - if (!file) { - return; - } - - await invoke('state_set_wallpaper', { path: file.path }); - dispatch(RootActions.setWallpaper(file.path)); - } - - return ( - <> - - -
- -
-
- - ); -} +import { Monitor } from '../../../../components/monitor'; +import { SettingsOption } from '../../../../components/SettingsBox'; +import { invoke } from '@tauri-apps/api/core'; +import { Button } from 'antd'; +import { useTranslation } from 'react-i18next'; +import { useDispatch } from 'react-redux'; + +import { dialog } from '../../../shared/tauri/infra'; + +import { RootActions } from '../../../shared/store/app/reducer'; + +import cs from './index.module.css'; + +export function Wallpaper() { + const { t } = useTranslation(); + const dispatch = useDispatch(); + + async function loadWallpaper() { + const file = await dialog.open({ + title: t('general.wallpaper.select'), + filters: [ + { name: 'images', extensions: ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'tif', 'tiff'] }, + ], + }); + + if (!file) { + return; + } + + await invoke('state_set_wallpaper', { path: file.path }); + dispatch(RootActions.setWallpaper(file.path)); + } + + return ( + <> + + +
+ +
+
+ + ); +} diff --git a/src/apps/settings/modules/general/main/infra/index.module.css b/src/apps/settings/modules/general/main/infra/index.module.css index 469dded6..a42a79c7 100644 --- a/src/apps/settings/modules/general/main/infra/index.module.css +++ b/src/apps/settings/modules/general/main/infra/index.module.css @@ -1,65 +1,65 @@ -.title { - font-size: 1.2rem; - font-weight: bold; -} - -.transfer { - :global(.ant-transfer-list) { - overflow: hidden; - - :global(.ant-transfer-list-header) { - :global(.ant-transfer-list-header-selected) { - display: none; - } - - :global(.ant-transfer-list-header-title) { - font-weight: 600; - text-align: center; - } - } - - :global(.ant-transfer-list-body) { - background-color: var(--color-gray-50); - padding: 4px 8px; - } - } -} - -.tagList { - display: flex; - align-items: center; - flex-wrap: wrap; - gap: 4px; - - .tag { - display: flex; - align-items: center; - justify-content: center; - padding: 0px 6px; - height: 20px; - border-radius: 6px; - background-color: var(--color-gray-100); - color: var(--color-gray-900); - font-size: 10px; - line-height: 10px; - } -} - -.palette { - width: 100%; - height: 30px; - display: flex; - - > div { - flex: 1; - height: 100%; - } -} - -.wallpaperButton { - flex: 1; - display: flex; - align-items: center; - justify-content: center; - margin-left: 20px; +.title { + font-size: 1.2rem; + font-weight: bold; +} + +.transfer { + :global(.ant-transfer-list) { + overflow: hidden; + + :global(.ant-transfer-list-header) { + :global(.ant-transfer-list-header-selected) { + display: none; + } + + :global(.ant-transfer-list-header-title) { + font-weight: 600; + text-align: center; + } + } + + :global(.ant-transfer-list-body) { + background-color: var(--color-gray-50); + padding: 4px 8px; + } + } +} + +.tagList { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 4px; + + .tag { + display: flex; + align-items: center; + justify-content: center; + padding: 0px 6px; + height: 20px; + border-radius: 6px; + background-color: var(--color-gray-100); + color: var(--color-gray-900); + font-size: 10px; + line-height: 10px; + } +} + +.palette { + width: 100%; + height: 30px; + display: flex; + + > div { + flex: 1; + height: 100%; + } +} + +.wallpaperButton { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + margin-left: 20px; } \ No newline at end of file diff --git a/src/apps/settings/modules/general/main/infra/index.tsx b/src/apps/settings/modules/general/main/infra/index.tsx index 6d921a22..70f27c69 100644 --- a/src/apps/settings/modules/general/main/infra/index.tsx +++ b/src/apps/settings/modules/general/main/infra/index.tsx @@ -1,64 +1,64 @@ -import { LanguageList } from '../../../../../shared/lang'; -import { SettingsGroup, SettingsOption } from '../../../../components/SettingsBox'; -import { Colors } from './Colors'; -import { Themes } from './Themes'; -import { Wallpaper } from './Wallpaper'; -import { Select, Switch } from 'antd'; -import { useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; - -import { startup } from '../../../shared/tauri/infra'; -import { useAppDispatch } from '../../../shared/utils/infra'; - -import { RootActions } from '../../../shared/store/app/reducer'; -import { RootSelectors } from '../../../shared/store/app/selectors'; - -export function General() { - const autostartStatus = useSelector(RootSelectors.autostart); - const language = useSelector(RootSelectors.language); - - const { t } = useTranslation(); - const dispatch = useAppDispatch(); - - const onAutoStart = async (value: boolean) => { - if (value) { - await startup.enable(); - } else { - await startup.disable(); - } - dispatch(RootActions.setAutostart(value)); - }; - - return ( - <> - - - {t('general.startup')} - - - - {t('general.language')}: - dispatch(RootActions.setLanguage(value))} + /> + + + + + + + + + + +
+ {t('general.theme.label')} +
+ +
+ + ); +} diff --git a/src/apps/settings/modules/information/infra.module.css b/src/apps/settings/modules/information/infra.module.css index 1f325129..55410fdb 100644 --- a/src/apps/settings/modules/information/infra.module.css +++ b/src/apps/settings/modules/information/infra.module.css @@ -1,14 +1,14 @@ -.info { - a { - color: var(--color-blue-600); - &:hover { - color: var(--color-blue-800); - } - } - - .version { - font-size: 0.8rem; - font-weight: 700; - color: var(--color-black); - } +.info { + a { + color: var(--color-blue-600); + &:hover { + color: var(--color-blue-800); + } + } + + .version { + font-size: 0.8rem; + font-weight: 700; + color: var(--color-black); + } } \ No newline at end of file diff --git a/src/apps/settings/modules/information/infrastructure.tsx b/src/apps/settings/modules/information/infrastructure.tsx index 99fcd57d..f8859e67 100644 --- a/src/apps/settings/modules/information/infrastructure.tsx +++ b/src/apps/settings/modules/information/infrastructure.tsx @@ -1,74 +1,74 @@ -import { Icon } from '../../../shared/components/Icon'; -import { SettingsGroup, SettingsOption, SettingsSubGroup } from '../../components/SettingsBox'; -import { exit, relaunch } from '@tauri-apps/plugin-process'; -import { Button, Switch } from 'antd'; -import { useTranslation } from 'react-i18next'; -import { useDispatch, useSelector } from 'react-redux'; - -import { EnvConfig } from '../shared/config/infra'; -import cs from './infra.module.css'; - -import { newSelectors, RootActions } from '../shared/store/app/reducer'; - -export function Information() { - const devTools = useSelector(newSelectors.devTools); - - const dispatch = useDispatch(); - const { t } = useTranslation(); - - function onToggleDevTools(value: boolean) { - dispatch(RootActions.setDevTools(value)); - } - - return ( -
- - - - {t('extras.version')}: - v{EnvConfig.version} - - - - - - - - {t('extras.github')}: - - github.com/eythaann/seelen-ui - - - - {t('extras.discord')}: - - discord.gg/ABfASx5ZAJ - - - - - - - - {t('devtools.enable')} - - - - - - - {t('extras.relaunch')} - - - - {t('extras.exit')} - - - -
- ); -} +import { Icon } from '../../../shared/components/Icon'; +import { SettingsGroup, SettingsOption, SettingsSubGroup } from '../../components/SettingsBox'; +import { exit, relaunch } from '@tauri-apps/plugin-process'; +import { Button, Switch } from 'antd'; +import { useTranslation } from 'react-i18next'; +import { useDispatch, useSelector } from 'react-redux'; + +import { EnvConfig } from '../shared/config/infra'; +import cs from './infra.module.css'; + +import { newSelectors, RootActions } from '../shared/store/app/reducer'; + +export function Information() { + const devTools = useSelector(newSelectors.devTools); + + const dispatch = useDispatch(); + const { t } = useTranslation(); + + function onToggleDevTools(value: boolean) { + dispatch(RootActions.setDevTools(value)); + } + + return ( +
+ + + + {t('extras.version')}: + v{EnvConfig.version} + + + + + + + + {t('extras.github')}: + + github.com/eythaann/seelen-ui + + + + {t('extras.discord')}: + + discord.gg/ABfASx5ZAJ + + + + + + + + {t('devtools.enable')} + + + + + + + {t('extras.relaunch')} + + + + {t('extras.exit')} + + + +
+ ); +} diff --git a/src/apps/settings/modules/monitors/layouts/domain.ts b/src/apps/settings/modules/monitors/layouts/domain.ts index 39e84ca3..11b841fa 100644 --- a/src/apps/settings/modules/monitors/layouts/domain.ts +++ b/src/apps/settings/modules/monitors/layouts/domain.ts @@ -1,13 +1,13 @@ - -export enum Layout { - BSP = 'BSP', - COLUMNS = 'Columns', - ROWS = 'Rows', - VERTICAL_STACK = 'VerticalStack', - HORIZONTAL_STACK = 'HorizontalStack', - ULTRAWIDE_VERTICAL_STACK = 'UltrawideVerticalStack', - GRID = 'Grid', -} - -// aspect ratio in base to 720p to 144px (height of monitor in preview) + +export enum Layout { + BSP = 'BSP', + COLUMNS = 'Columns', + ROWS = 'Rows', + VERTICAL_STACK = 'VerticalStack', + HORIZONTAL_STACK = 'HorizontalStack', + ULTRAWIDE_VERTICAL_STACK = 'UltrawideVerticalStack', + GRID = 'Grid', +} + +// aspect ratio in base to 720p to 144px (height of monitor in preview) export const RELATION_ASPECT_RATIO = 5; \ No newline at end of file diff --git a/src/apps/settings/modules/monitors/layouts/infra.module.css b/src/apps/settings/modules/monitors/layouts/infra.module.css index 41e922c6..49c2f98c 100644 --- a/src/apps/settings/modules/monitors/layouts/infra.module.css +++ b/src/apps/settings/modules/monitors/layouts/infra.module.css @@ -1,17 +1,17 @@ - -.colums { - flex: 1; - display: flex; -} - -.rows { - flex: 1; - display: flex; - flex-direction: column; -} - -.window { - flex: 1; - border: 1px dashed var(--color-red-900); - border-radius: 4px; + +.colums { + flex: 1; + display: flex; +} + +.rows { + flex: 1; + display: flex; + flex-direction: column; +} + +.window { + flex: 1; + border: 1px dashed var(--color-red-900); + border-radius: 4px; } \ No newline at end of file diff --git a/src/apps/settings/modules/monitors/layouts/infra.tsx b/src/apps/settings/modules/monitors/layouts/infra.tsx index ef0c05f7..42f1737c 100644 --- a/src/apps/settings/modules/monitors/layouts/infra.tsx +++ b/src/apps/settings/modules/monitors/layouts/infra.tsx @@ -1,237 +1,237 @@ -import { useEffect, useState } from 'react'; - -import cs from './infra.module.css'; - -import { Layout, RELATION_ASPECT_RATIO } from './domain'; - -interface Props { - containerPadding: number; - workspacePadding: number; -} - -const BSPLayoutExample = ({ containerPadding, workspacePadding }: Props) => { - const [counter, setCounter] = useState(1); - - useEffect(() => { - setInterval(() => setCounter((v) => (v >= 4 ? 1 : v + 1)), 1000); - }, []); - - const style = { - gap: containerPadding / RELATION_ASPECT_RATIO, - }; - - return ( -
-
- {counter >= 2 && ( -
-
- {counter >= 3 && ( -
-
- {counter >= 4 &&
} -
- )} -
- )} -
- ); -}; - -const ColumsLayoutExample = ({ containerPadding, workspacePadding }: Props) => { - const [counter, setCounter] = useState(1); - - useEffect(() => { - setInterval(() => setCounter((v) => (v >= 4 ? 1 : v + 1)), 1000); - }, []); - - return ( -
-
- {counter >= 2 &&
} - {counter >= 3 &&
} - {counter >= 4 &&
} -
- ); -}; - -const RowsLayoutExample = ({ containerPadding, workspacePadding }: Props) => { - const [counter, setCounter] = useState(1); - - useEffect(() => { - setInterval(() => setCounter((v) => (v >= 4 ? 1 : v + 1)), 1000); - }, []); - - return ( -
-
- {counter >= 2 &&
} - {counter >= 3 &&
} - {counter >= 4 &&
} -
- ); -}; - -const HorizontalStackLayoutExample = ({ containerPadding, workspacePadding }: Props) => { - const [counter, setCounter] = useState(1); - - useEffect(() => { - setInterval(() => setCounter((v) => (v >= 4 ? 1 : v + 1)), 1000); - }, []); - - const style = { - gap: containerPadding / RELATION_ASPECT_RATIO, - }; - - return ( -
-
- {counter >= 2 && ( -
-
- {counter >= 3 &&
} - {counter >= 4 &&
} -
- )} -
- ); -}; - -const VerticalStackLayoutExample = ({ containerPadding, workspacePadding }: Props) => { - const [counter, setCounter] = useState(1); - - useEffect(() => { - setInterval(() => setCounter((v) => (v >= 4 ? 1 : v + 1)), 1000); - }, []); - - const style = { - gap: containerPadding / RELATION_ASPECT_RATIO, - }; - - return ( -
-
- {counter >= 2 && ( -
-
- {counter >= 3 &&
} - {counter >= 4 &&
} -
- )} -
- ); -}; - -const UltrawideVerticalStackLayoutExample = ({ containerPadding, workspacePadding }: Props) => { - const [counter, setCounter] = useState(1); - - useEffect(() => { - setInterval(() => setCounter((v) => (v >= 4 ? 1 : v + 1)), 1000); - }, []); - - const style = { - gap: containerPadding / RELATION_ASPECT_RATIO, - }; - - return ( -
-
- {counter >= 2 &&
= 3 ? 2 : 1 }} />} - {counter >= 3 && ( -
-
- {counter >= 4 &&
} - {counter >= 5 &&
} -
- )} -
- ); -}; - -const GridLayoutExample = ({ containerPadding, workspacePadding }: Props) => { - const [counter, setCounter] = useState(1); - - useEffect(() => { - setInterval(() => setCounter((v) => (v >= 8 ? 1 : v + 1)), 1000); - }, []); - - const style = { - gap: containerPadding / RELATION_ASPECT_RATIO, - }; - - return ( -
-
-
- {counter >= 4 && counter != 5 &&
} - {counter >= 9 &&
} -
- {counter >= 2 && ( -
-
- {counter >= 3 &&
} - {counter >= 8 &&
} -
- )} - {counter >= 5 && ( -
-
-
- {counter >= 7 &&
} -
- )} -
- ); -}; - -export const LayoutExamples: Record> = { - [Layout.BSP]: BSPLayoutExample, - [Layout.COLUMNS]: ColumsLayoutExample, - [Layout.ROWS]: RowsLayoutExample, - [Layout.HORIZONTAL_STACK]: HorizontalStackLayoutExample, - [Layout.VERTICAL_STACK]: VerticalStackLayoutExample, - [Layout.ULTRAWIDE_VERTICAL_STACK]: UltrawideVerticalStackLayoutExample, - [Layout.GRID]: GridLayoutExample, -}; +import { useEffect, useState } from 'react'; + +import cs from './infra.module.css'; + +import { Layout, RELATION_ASPECT_RATIO } from './domain'; + +interface Props { + containerPadding: number; + workspacePadding: number; +} + +const BSPLayoutExample = ({ containerPadding, workspacePadding }: Props) => { + const [counter, setCounter] = useState(1); + + useEffect(() => { + setInterval(() => setCounter((v) => (v >= 4 ? 1 : v + 1)), 1000); + }, []); + + const style = { + gap: containerPadding / RELATION_ASPECT_RATIO, + }; + + return ( +
+
+ {counter >= 2 && ( +
+
+ {counter >= 3 && ( +
+
+ {counter >= 4 &&
} +
+ )} +
+ )} +
+ ); +}; + +const ColumsLayoutExample = ({ containerPadding, workspacePadding }: Props) => { + const [counter, setCounter] = useState(1); + + useEffect(() => { + setInterval(() => setCounter((v) => (v >= 4 ? 1 : v + 1)), 1000); + }, []); + + return ( +
+
+ {counter >= 2 &&
} + {counter >= 3 &&
} + {counter >= 4 &&
} +
+ ); +}; + +const RowsLayoutExample = ({ containerPadding, workspacePadding }: Props) => { + const [counter, setCounter] = useState(1); + + useEffect(() => { + setInterval(() => setCounter((v) => (v >= 4 ? 1 : v + 1)), 1000); + }, []); + + return ( +
+
+ {counter >= 2 &&
} + {counter >= 3 &&
} + {counter >= 4 &&
} +
+ ); +}; + +const HorizontalStackLayoutExample = ({ containerPadding, workspacePadding }: Props) => { + const [counter, setCounter] = useState(1); + + useEffect(() => { + setInterval(() => setCounter((v) => (v >= 4 ? 1 : v + 1)), 1000); + }, []); + + const style = { + gap: containerPadding / RELATION_ASPECT_RATIO, + }; + + return ( +
+
+ {counter >= 2 && ( +
+
+ {counter >= 3 &&
} + {counter >= 4 &&
} +
+ )} +
+ ); +}; + +const VerticalStackLayoutExample = ({ containerPadding, workspacePadding }: Props) => { + const [counter, setCounter] = useState(1); + + useEffect(() => { + setInterval(() => setCounter((v) => (v >= 4 ? 1 : v + 1)), 1000); + }, []); + + const style = { + gap: containerPadding / RELATION_ASPECT_RATIO, + }; + + return ( +
+
+ {counter >= 2 && ( +
+
+ {counter >= 3 &&
} + {counter >= 4 &&
} +
+ )} +
+ ); +}; + +const UltrawideVerticalStackLayoutExample = ({ containerPadding, workspacePadding }: Props) => { + const [counter, setCounter] = useState(1); + + useEffect(() => { + setInterval(() => setCounter((v) => (v >= 4 ? 1 : v + 1)), 1000); + }, []); + + const style = { + gap: containerPadding / RELATION_ASPECT_RATIO, + }; + + return ( +
+
+ {counter >= 2 &&
= 3 ? 2 : 1 }} />} + {counter >= 3 && ( +
+
+ {counter >= 4 &&
} + {counter >= 5 &&
} +
+ )} +
+ ); +}; + +const GridLayoutExample = ({ containerPadding, workspacePadding }: Props) => { + const [counter, setCounter] = useState(1); + + useEffect(() => { + setInterval(() => setCounter((v) => (v >= 8 ? 1 : v + 1)), 1000); + }, []); + + const style = { + gap: containerPadding / RELATION_ASPECT_RATIO, + }; + + return ( +
+
+
+ {counter >= 4 && counter != 5 &&
} + {counter >= 9 &&
} +
+ {counter >= 2 && ( +
+
+ {counter >= 3 &&
} + {counter >= 8 &&
} +
+ )} + {counter >= 5 && ( +
+
+
+ {counter >= 7 &&
} +
+ )} +
+ ); +}; + +export const LayoutExamples: Record> = { + [Layout.BSP]: BSPLayoutExample, + [Layout.COLUMNS]: ColumsLayoutExample, + [Layout.ROWS]: RowsLayoutExample, + [Layout.HORIZONTAL_STACK]: HorizontalStackLayoutExample, + [Layout.VERTICAL_STACK]: VerticalStackLayoutExample, + [Layout.ULTRAWIDE_VERTICAL_STACK]: UltrawideVerticalStackLayoutExample, + [Layout.GRID]: GridLayoutExample, +}; diff --git a/src/apps/settings/modules/monitors/main/app.ts b/src/apps/settings/modules/monitors/main/app.ts index 31c036f7..b2828497 100644 --- a/src/apps/settings/modules/monitors/main/app.ts +++ b/src/apps/settings/modules/monitors/main/app.ts @@ -1,62 +1,62 @@ -import { parseAsCamel } from '../../../../shared/schemas'; -import { Monitor, MonitorSchema, Workspace, WorkspaceSchema } from '../../../../shared/schemas/Monitors'; -import { createSlice, PayloadAction } from '@reduxjs/toolkit'; - -const initialState: Monitor[] = [parseAsCamel(MonitorSchema, {})]; - -interface ForMonitor { - monitorIdx: number; -} - -interface ForWorkspace extends ForMonitor { - workspaceIdx: number; -} - -export const MonitorsSlice = createSlice({ - name: 'monitors', - initialState, - reducers: { - delete: (state, action: PayloadAction) => { - state.splice(action.payload, 1); - }, - insert: (state, action: PayloadAction) => { - state.splice(action.payload, 0, parseAsCamel(MonitorSchema, {})); - }, - changeEditingWorkspace: (state, action: PayloadAction) => { - const { monitorIdx, workspaceIdx } = action.payload; - const monitor = state[monitorIdx]; - if (!monitor) { - return; - } - monitor.edditingWorkspace = workspaceIdx; - }, - newWorkspace: (state, action: PayloadAction) => { - const { monitorIdx, name } = action.payload; - const monitor = state[monitorIdx]; - if (!monitor) { - return; - } - const newWorkspace = parseAsCamel(WorkspaceSchema, {}); - const length = monitor.workspaces.push(newWorkspace); - newWorkspace.name = name || `Workspace ${length}`; - }, - updateWorkspace: (state: Monitor[], action: PayloadAction) => { - const { workspaceIdx, monitorIdx, key, value } = action.payload; - let workspace = state[monitorIdx]?.workspaces[workspaceIdx]; - if (!workspace) { - return; - } - workspace[key] = value; - }, - updateMonitor: (state: Monitor[], action: PayloadAction) => { - const { monitorIdx, key, value } = action.payload; - const monitor = state[monitorIdx]; - if (!monitor) { - return; - } - monitor[key] = value; - }, - }, -}); - +import { parseAsCamel } from '../../../../shared/schemas'; +import { Monitor, MonitorSchema, Workspace, WorkspaceSchema } from '../../../../shared/schemas/Monitors'; +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + +const initialState: Monitor[] = [parseAsCamel(MonitorSchema, {})]; + +interface ForMonitor { + monitorIdx: number; +} + +interface ForWorkspace extends ForMonitor { + workspaceIdx: number; +} + +export const MonitorsSlice = createSlice({ + name: 'monitors', + initialState, + reducers: { + delete: (state, action: PayloadAction) => { + state.splice(action.payload, 1); + }, + insert: (state, action: PayloadAction) => { + state.splice(action.payload, 0, parseAsCamel(MonitorSchema, {})); + }, + changeEditingWorkspace: (state, action: PayloadAction) => { + const { monitorIdx, workspaceIdx } = action.payload; + const monitor = state[monitorIdx]; + if (!monitor) { + return; + } + monitor.edditingWorkspace = workspaceIdx; + }, + newWorkspace: (state, action: PayloadAction) => { + const { monitorIdx, name } = action.payload; + const monitor = state[monitorIdx]; + if (!monitor) { + return; + } + const newWorkspace = parseAsCamel(WorkspaceSchema, {}); + const length = monitor.workspaces.push(newWorkspace); + newWorkspace.name = name || `Workspace ${length}`; + }, + updateWorkspace: (state: Monitor[], action: PayloadAction) => { + const { workspaceIdx, monitorIdx, key, value } = action.payload; + let workspace = state[monitorIdx]?.workspaces[workspaceIdx]; + if (!workspace) { + return; + } + workspace[key] = value; + }, + updateMonitor: (state: Monitor[], action: PayloadAction) => { + const { monitorIdx, key, value } = action.payload; + const monitor = state[monitorIdx]; + if (!monitor) { + return; + } + monitor[key] = value; + }, + }, +}); + export const MonitorsActions = MonitorsSlice.actions; \ No newline at end of file diff --git a/src/apps/settings/modules/monitors/main/infra.module.css b/src/apps/settings/modules/monitors/main/infra.module.css index 2b06e160..17669c29 100644 --- a/src/apps/settings/modules/monitors/main/infra.module.css +++ b/src/apps/settings/modules/monitors/main/infra.module.css @@ -1,69 +1,69 @@ -.monitors { - display: flex; - flex-direction: column; - gap: 20px; - - .monitor { - height: 100%; - display: flex; - flex-wrap: wrap; - justify-content: center; - align-items: center; - gap: 6px; - - .border { - --padding: 6px; - - background-color: black; - border-radius: 12px; - display: grid; - place-items: center; - padding: var(--padding); - height: calc(144px + var(--padding)); - width: calc(256px + var(--padding)); - - .screen { - border-radius: 8px; - background: linear-gradient( - 40deg, - var(--color-blue-500) 2%, - var(--color-blue-300) 60%, - var(--color-blue-100) 100% - ); - width: 100%; - height: 100%; - display: flex; - } - } - - > button { - flex: 2; - - &.advancedTrigger { - flex: 1; - } - } - } - - .config { - display: grid; - grid-template-columns: min-content 1fr; - align-items: center; - gap: 10px; - - .title { - font-weight: 600; - text-align: center; - font-size: 0.8rem; - margin-bottom: 10px; - } - - .workspaceSelector { - width: 100%; - } - } -} - -.advancedModal { - padding-right: 10px; -} +.monitors { + display: flex; + flex-direction: column; + gap: 20px; + + .monitor { + height: 100%; + display: flex; + flex-wrap: wrap; + justify-content: center; + align-items: center; + gap: 6px; + + .border { + --padding: 6px; + + background-color: black; + border-radius: 12px; + display: grid; + place-items: center; + padding: var(--padding); + height: calc(144px + var(--padding)); + width: calc(256px + var(--padding)); + + .screen { + border-radius: 8px; + background: linear-gradient( + 40deg, + var(--color-blue-500) 2%, + var(--color-blue-300) 60%, + var(--color-blue-100) 100% + ); + width: 100%; + height: 100%; + display: flex; + } + } + + > button { + flex: 2; + + &.advancedTrigger { + flex: 1; + } + } + } + + .config { + display: grid; + grid-template-columns: min-content 1fr; + align-items: center; + gap: 10px; + + .title { + font-weight: 600; + text-align: center; + font-size: 0.8rem; + margin-bottom: 10px; + } + + .workspaceSelector { + width: 100%; + } + } +} + +.advancedModal { + padding-right: 10px; +} diff --git a/src/apps/settings/modules/monitors/main/infra.tsx b/src/apps/settings/modules/monitors/main/infra.tsx index 0154a292..17f95529 100644 --- a/src/apps/settings/modules/monitors/main/infra.tsx +++ b/src/apps/settings/modules/monitors/main/infra.tsx @@ -1,116 +1,116 @@ -import { SettingsGroup } from '../../../components/SettingsBox'; -import { Button, Input, Select, Space } from 'antd'; -import { useState } from 'react'; -import { useDispatch } from 'react-redux'; - -import { useAppSelector } from '../../shared/utils/infra'; -import { LayoutExamples } from '../layouts/infra'; -import { WorkspaceConfig } from '../workspace/infra'; -import cs from './infra.module.css'; -import { AdvancedConfig } from './infra_advanced'; - -import { getMonitorSelector, RootSelectors, SeelenWmSelectors } from '../../shared/store/app/selectors'; -import { defaultOnNull } from '../../shared/utils/app'; -import { MonitorsActions } from './app'; - -export const MonitorConfig = ({ monitorIdx }: { monitorIdx: number }) => { - const [newWorkspaceName, setNewWorkspaceName] = useState(''); - const monitor = useAppSelector(getMonitorSelector(monitorIdx)); - - const dispatch = useDispatch(); - - if (!monitor) { - return null; - } - - const workspace = monitor.workspaces[monitor.edditingWorkspace]!; - const LayoutExample = LayoutExamples[workspace.layout]; - - const containerPadding = defaultOnNull( - workspace.gap, - useAppSelector(SeelenWmSelectors.workspaceGap), - ); - - const workspacePadding = defaultOnNull( - workspace.padding, - useAppSelector(SeelenWmSelectors.workspacePadding), - ); - - const onDelete = () => { - dispatch(MonitorsActions.delete(monitorIdx)); - }; - - const onInsert = () => { - dispatch(MonitorsActions.insert(monitorIdx + 1)); - }; - - const onChangeWorkspace = (workspaceIdx: number) => { - dispatch(MonitorsActions.changeEditingWorkspace({ monitorIdx, workspaceIdx })); - }; - - const onChangeNewWorkspaceName = (event: React.ChangeEvent) => { - setNewWorkspaceName(event.target.value); - }; - const onAddWorkspace = () => { - dispatch(MonitorsActions.newWorkspace({ monitorIdx, name: newWorkspaceName })); - setNewWorkspaceName(''); - }; - - return ( -
-
-
-
- {LayoutExample && } -
-
- - - -
- -
-
Monitor {monitorIdx + 1}
- - - - - )} - options={monitor.workspaces.map((workspace, index) => ({ - label: workspace.name, - value: index, - }))} - onChange={onChangeWorkspace} - /> -
- -
-
- ); -}; - -export function Monitors() { - const monitors = useAppSelector(RootSelectors.monitors); - - return ( -
- {monitors.map((_, index) => ( - - ))} -
- ); -} +import { SettingsGroup } from '../../../components/SettingsBox'; +import { Button, Input, Select, Space } from 'antd'; +import { useState } from 'react'; +import { useDispatch } from 'react-redux'; + +import { useAppSelector } from '../../shared/utils/infra'; +import { LayoutExamples } from '../layouts/infra'; +import { WorkspaceConfig } from '../workspace/infra'; +import cs from './infra.module.css'; +import { AdvancedConfig } from './infra_advanced'; + +import { getMonitorSelector, RootSelectors, SeelenWmSelectors } from '../../shared/store/app/selectors'; +import { defaultOnNull } from '../../shared/utils/app'; +import { MonitorsActions } from './app'; + +export const MonitorConfig = ({ monitorIdx }: { monitorIdx: number }) => { + const [newWorkspaceName, setNewWorkspaceName] = useState(''); + const monitor = useAppSelector(getMonitorSelector(monitorIdx)); + + const dispatch = useDispatch(); + + if (!monitor) { + return null; + } + + const workspace = monitor.workspaces[monitor.edditingWorkspace]!; + const LayoutExample = LayoutExamples[workspace.layout]; + + const containerPadding = defaultOnNull( + workspace.gap, + useAppSelector(SeelenWmSelectors.workspaceGap), + ); + + const workspacePadding = defaultOnNull( + workspace.padding, + useAppSelector(SeelenWmSelectors.workspacePadding), + ); + + const onDelete = () => { + dispatch(MonitorsActions.delete(monitorIdx)); + }; + + const onInsert = () => { + dispatch(MonitorsActions.insert(monitorIdx + 1)); + }; + + const onChangeWorkspace = (workspaceIdx: number) => { + dispatch(MonitorsActions.changeEditingWorkspace({ monitorIdx, workspaceIdx })); + }; + + const onChangeNewWorkspaceName = (event: React.ChangeEvent) => { + setNewWorkspaceName(event.target.value); + }; + const onAddWorkspace = () => { + dispatch(MonitorsActions.newWorkspace({ monitorIdx, name: newWorkspaceName })); + setNewWorkspaceName(''); + }; + + return ( +
+
+
+
+ {LayoutExample && } +
+
+ + + +
+ +
+
Monitor {monitorIdx + 1}
+ + + + + )} + options={monitor.workspaces.map((workspace, index) => ({ + label: workspace.name, + value: index, + }))} + onChange={onChangeWorkspace} + /> +
+ +
+
+ ); +}; + +export function Monitors() { + const monitors = useAppSelector(RootSelectors.monitors); + + return ( +
+ {monitors.map((_, index) => ( + + ))} +
+ ); +} diff --git a/src/apps/settings/modules/monitors/main/infra_advanced.tsx b/src/apps/settings/modules/monitors/main/infra_advanced.tsx index 6360fece..e507d6e1 100644 --- a/src/apps/settings/modules/monitors/main/infra_advanced.tsx +++ b/src/apps/settings/modules/monitors/main/infra_advanced.tsx @@ -1,119 +1,119 @@ -import { SettingsGroup, SettingsOption, SettingsSubGroup } from '../../../components/SettingsBox'; -import { Button, InputNumber, Modal } from 'antd'; -import { useState } from 'react'; -import { useDispatch } from 'react-redux'; - -import { useAppSelector } from '../../shared/utils/infra'; -import cs from './infra.module.css'; - -import { getMonitorSelector, getWorkspaceSelector } from '../../shared/store/app/selectors'; -import { Rect } from '../../shared/utils/app/Rect'; -import { MonitorsActions } from './app'; - -interface Props { - workspaceIdx: number; - monitorIdx: number; -} - -export const AdvancedConfig = ({ workspaceIdx, monitorIdx }: Props) => { - const [isModalOpen, setIsModalOpen] = useState(false); - const workspace = useAppSelector(getWorkspaceSelector(workspaceIdx, monitorIdx)); - const { workAreaOffset } = useAppSelector(getMonitorSelector(monitorIdx))!; - - const dispatch = useDispatch(); - - if (!workspace) { - return; - } - - const showModal = () => { - setIsModalOpen(true); - }; - - const handleOk = () => { - setIsModalOpen(false); - }; - - const handleCancel = () => { - setIsModalOpen(false); - }; - - const resetOffset = () => - dispatch(MonitorsActions.updateMonitor({ monitorIdx, key: 'workAreaOffset', value: null })); - const onChangeOffset = (side: keyof Rect, value: number | null) => { - dispatch( - MonitorsActions.updateMonitor({ - monitorIdx, - key: 'workAreaOffset', - value: { - ...(workAreaOffset || new Rect().toJSON()), - [side]: value || 0, - }, - }), - ); - }; - - return ( - <> - - -
- - - Specifit monitor offsets (margins) - - - } - > - - Left - - - - Top - - - - Right - - - - Bottom - - - - -
-
- - ); -}; +import { SettingsGroup, SettingsOption, SettingsSubGroup } from '../../../components/SettingsBox'; +import { Button, InputNumber, Modal } from 'antd'; +import { useState } from 'react'; +import { useDispatch } from 'react-redux'; + +import { useAppSelector } from '../../shared/utils/infra'; +import cs from './infra.module.css'; + +import { getMonitorSelector, getWorkspaceSelector } from '../../shared/store/app/selectors'; +import { Rect } from '../../shared/utils/app/Rect'; +import { MonitorsActions } from './app'; + +interface Props { + workspaceIdx: number; + monitorIdx: number; +} + +export const AdvancedConfig = ({ workspaceIdx, monitorIdx }: Props) => { + const [isModalOpen, setIsModalOpen] = useState(false); + const workspace = useAppSelector(getWorkspaceSelector(workspaceIdx, monitorIdx)); + const { workAreaOffset } = useAppSelector(getMonitorSelector(monitorIdx))!; + + const dispatch = useDispatch(); + + if (!workspace) { + return; + } + + const showModal = () => { + setIsModalOpen(true); + }; + + const handleOk = () => { + setIsModalOpen(false); + }; + + const handleCancel = () => { + setIsModalOpen(false); + }; + + const resetOffset = () => + dispatch(MonitorsActions.updateMonitor({ monitorIdx, key: 'workAreaOffset', value: null })); + const onChangeOffset = (side: keyof Rect, value: number | null) => { + dispatch( + MonitorsActions.updateMonitor({ + monitorIdx, + key: 'workAreaOffset', + value: { + ...(workAreaOffset || new Rect().toJSON()), + [side]: value || 0, + }, + }), + ); + }; + + return ( + <> + + +
+ + + Specifit monitor offsets (margins) + + + } + > + + Left + + + + Top + + + + Right + + + + Bottom + + + + +
+
+ + ); +}; diff --git a/src/apps/settings/modules/monitors/workspace/app.ts b/src/apps/settings/modules/monitors/workspace/app.ts index 28a263a1..6fb8dce7 100644 --- a/src/apps/settings/modules/monitors/workspace/app.ts +++ b/src/apps/settings/modules/monitors/workspace/app.ts @@ -1,18 +1,18 @@ -import { getWorkspaceSelector, SeelenWmSelectors } from '../../shared/store/app/selectors'; -import { defaultOnNull } from '../../shared/utils/app'; - -import { RootState } from '../../shared/store/domain'; - -export const getWorkspacePaddingSelector = (idx: number, monitorIdx: number) => (state: RootState) => { - return defaultOnNull( - getWorkspaceSelector(idx, monitorIdx)(state)?.padding, - SeelenWmSelectors.workspacePadding(state), - ); -}; - -export const getWorkspaceGapSelector = (idx: number, monitorIdx: number) => (state: RootState) => { - return defaultOnNull( - getWorkspaceSelector(idx, monitorIdx)(state)?.gap, - SeelenWmSelectors.workspaceGap(state), - ); -}; +import { getWorkspaceSelector, SeelenWmSelectors } from '../../shared/store/app/selectors'; +import { defaultOnNull } from '../../shared/utils/app'; + +import { RootState } from '../../shared/store/domain'; + +export const getWorkspacePaddingSelector = (idx: number, monitorIdx: number) => (state: RootState) => { + return defaultOnNull( + getWorkspaceSelector(idx, monitorIdx)(state)?.padding, + SeelenWmSelectors.workspacePadding(state), + ); +}; + +export const getWorkspaceGapSelector = (idx: number, monitorIdx: number) => (state: RootState) => { + return defaultOnNull( + getWorkspaceSelector(idx, monitorIdx)(state)?.gap, + SeelenWmSelectors.workspaceGap(state), + ); +}; diff --git a/src/apps/settings/modules/monitors/workspace/infra.module.css b/src/apps/settings/modules/monitors/workspace/infra.module.css index ed4220e1..e01ae15f 100644 --- a/src/apps/settings/modules/monitors/workspace/infra.module.css +++ b/src/apps/settings/modules/monitors/workspace/infra.module.css @@ -1,5 +1,5 @@ -.workspaceConfig { - :global(.ant-select) { - max-width: 100px; - } -} +.workspaceConfig { + :global(.ant-select) { + max-width: 100px; + } +} diff --git a/src/apps/settings/modules/monitors/workspace/infra.tsx b/src/apps/settings/modules/monitors/workspace/infra.tsx index e8092384..42ec8f13 100644 --- a/src/apps/settings/modules/monitors/workspace/infra.tsx +++ b/src/apps/settings/modules/monitors/workspace/infra.tsx @@ -1,56 +1,56 @@ -import { SettingsOption } from '../../../components/SettingsBox'; -import { InputNumber, Select } from 'antd'; -import { useDispatch } from 'react-redux'; - -import { useAppSelector } from '../../shared/utils/infra'; -import cs from './infra.module.css'; - -import { getWorkspaceSelector } from '../../shared/store/app/selectors'; -import { OptionsFromEnum } from '../../shared/utils/app'; -import { MonitorsActions } from '../main/app'; - -import { Layout } from '../layouts/domain'; - -interface Props { - monitorIdx: number; - workspaceIdx: number; -} - -export const WorkspaceConfig = ({ monitorIdx, workspaceIdx }: Props) => { - const workspace = useAppSelector(getWorkspaceSelector(workspaceIdx, monitorIdx)); - - const dispatch = useDispatch(); - - if (!workspace) { - return null; - } - - const onSelectLayout = (layout: Layout) => { - dispatch(MonitorsActions.updateWorkspace({ monitorIdx, workspaceIdx, key: 'layout', value: layout })); - }; - - const onChangeGap = (value: number | null) => { - dispatch(MonitorsActions.updateWorkspace({ monitorIdx, workspaceIdx, key: 'gap', value })); - }; - - const onChangePadding = (value: number | null) => { - dispatch(MonitorsActions.updateWorkspace({ monitorIdx, workspaceIdx, key: 'padding', value })); - }; - - return ( -
- - padding - - - - gap - - - - layout - + +
+ ); +}; diff --git a/src/apps/settings/modules/seelenweg/app.ts b/src/apps/settings/modules/seelenweg/app.ts index 9a170bb3..2be84dcd 100644 --- a/src/apps/settings/modules/seelenweg/app.ts +++ b/src/apps/settings/modules/seelenweg/app.ts @@ -1,16 +1,16 @@ -import { parseAsCamel } from '../../../shared/schemas'; -import { Seelenweg, SeelenWegSchema } from '../../../shared/schemas/Seelenweg'; -import { createSlice } from '@reduxjs/toolkit'; - -import { reducersFor, selectorsFor } from '../shared/utils/app'; - -const initialState: Seelenweg = parseAsCamel(SeelenWegSchema, {}); - -export const SeelenWegSlice = createSlice({ - name: 'seelenweg', - initialState, - selectors: selectorsFor(initialState), - reducers: reducersFor(initialState), -}); - +import { parseAsCamel } from '../../../shared/schemas'; +import { Seelenweg, SeelenWegSchema } from '../../../shared/schemas/Seelenweg'; +import { createSlice } from '@reduxjs/toolkit'; + +import { reducersFor, selectorsFor } from '../shared/utils/app'; + +const initialState: Seelenweg = parseAsCamel(SeelenWegSchema, {}); + +export const SeelenWegSlice = createSlice({ + name: 'seelenweg', + initialState, + selectors: selectorsFor(initialState), + reducers: reducersFor(initialState), +}); + export const SeelenWegActions = SeelenWegSlice.actions; \ No newline at end of file diff --git a/src/apps/settings/modules/seelenweg/infra.tsx b/src/apps/settings/modules/seelenweg/infra.tsx index 5d37e403..40dea48b 100644 --- a/src/apps/settings/modules/seelenweg/infra.tsx +++ b/src/apps/settings/modules/seelenweg/infra.tsx @@ -1,110 +1,110 @@ -import { SeelenWegHideMode, SeelenWegMode, SeelenWegSide } from '../../../shared/schemas/Seelenweg'; -import { SettingsGroup, SettingsOption, SettingsSubGroup } from '../../components/SettingsBox'; -import { InputNumber, Select, Switch } from 'antd'; -import { useTranslation } from 'react-i18next'; - -import { useAppDispatch, useAppSelector } from '../shared/utils/infra'; - -import { RootSelectors } from '../shared/store/app/selectors'; -import { OptionsFromEnum } from '../shared/utils/app'; -import { SeelenWegActions } from './app'; - -export const SeelenWegSettings = () => { - const settings = useAppSelector(RootSelectors.seelenweg); - - const dispatch = useAppDispatch(); - const { t } = useTranslation(); - - const onToggleEnable = (value: boolean) => { - dispatch(SeelenWegActions.setEnabled(value)); - }; - - return ( - <> - - -
- {t('weg.enable')} -
- -
-
- - - - -
{t('weg.width')}
- dispatch(SeelenWegActions.setHideMode(value))} - /> -
- -
{t('weg.dock_side')}
- dispatch(SeelenWegActions.setMode(value))} + /> +
+ +
{t('weg.auto_hide')}
+ dispatch(SeelenWegActions.setPosition(value))} + /> +
+ +
{t('weg.margin')}
+ dispatch(SeelenWegActions.setMargin(value || 0))} + /> +
+ +
{t('weg.padding')}
+ dispatch(SeelenWegActions.setPadding(value || 0))} + /> +
+
+
+ + + + +
{t('weg.items.size')}
+ dispatch(SeelenWegActions.setSize(value || 0))} + /> +
+ +
{t('weg.items.zoom_size')}
+ dispatch(SeelenWegActions.setZoomSize(value || 0))} + /> +
+ +
{t('weg.items.gap')}
+ dispatch(SeelenWegActions.setSpaceBetweenItems(value || 0))} + /> +
+ +
{t('weg.items.visible_separators')}
+ dispatch(SeelenWegActions.setVisibleSeparators(value))} /> +
+
+
+ + ); +}; diff --git a/src/apps/settings/modules/shared/config/infra.ts b/src/apps/settings/modules/shared/config/infra.ts index 07a41a8e..b2f76a45 100644 --- a/src/apps/settings/modules/shared/config/infra.ts +++ b/src/apps/settings/modules/shared/config/infra.ts @@ -1,9 +1,9 @@ -import { path } from '@tauri-apps/api'; - -export const EnvConfig = { - version: process.env.packageVersion, -}; - -export async function resolveDataPath(...sub: string[]) { - return await path.join(await path.appDataDir(), ...sub); +import { path } from '@tauri-apps/api'; + +export const EnvConfig = { + version: process.env.packageVersion, +}; + +export async function resolveDataPath(...sub: string[]) { + return await path.join(await path.appDataDir(), ...sub); } \ No newline at end of file diff --git a/src/apps/settings/modules/shared/store/app/StateBridge.ts b/src/apps/settings/modules/shared/store/app/StateBridge.ts index a124b117..27c09fc7 100644 --- a/src/apps/settings/modules/shared/store/app/StateBridge.ts +++ b/src/apps/settings/modules/shared/store/app/StateBridge.ts @@ -1,87 +1,87 @@ -import { UserSettings } from '../../../../../../shared.interfaces'; -import { parseAsCamel, VariableConvention } from '../../../../../shared/schemas'; -import { IdWithIdentifierSchema } from '../../../../../shared/schemas/AppsConfigurations'; -import { ISettings } from '../../../../../shared/schemas/Settings'; -import { pick } from 'lodash'; - -import { AppConfiguration, ApplicationOptions } from '../../../appsConfigurations/domain'; -import { RootState } from '../domain'; - -export const YamlToState_Apps = (yaml: anyObject[]): AppConfiguration[] => { - const apps: AppConfiguration[] = []; - - yaml.forEach((ymlApp: anyObject) => { - // filter empty ghost apps used only for add float_identifiers in komorebi cli - if (ymlApp.options || !ymlApp.float_identifiers) { - apps.push({ - name: ymlApp.name, - category: ymlApp.category || null, - monitor: ymlApp.bound_monitor ?? null, - workspace: ymlApp.bound_workspace || null, - identifier: parseAsCamel(IdWithIdentifierSchema, ymlApp.identifier), - isBundled: ymlApp.is_bundled || false, - // options - [ApplicationOptions.Float]: ymlApp.options?.includes(ApplicationOptions.Float) || false, - [ApplicationOptions.Unmanage]: - ymlApp.options?.includes(ApplicationOptions.Unmanage) || false, - [ApplicationOptions.Pinned]: ymlApp.options?.includes(ApplicationOptions.Pinned) || false, - [ApplicationOptions.ForceManage]: - ymlApp.options?.includes(ApplicationOptions.ForceManage) || false, - }); - } - }); - - return apps; -}; - -export const StaticSettingsToState = ( - userSettings: UserSettings, - state: RootState, -): RootState => { - const { jsonSettings, yamlSettings, themes, layouts, placeholders, wallpaper } = userSettings; - - return { - ...state, - ...jsonSettings, - wallpaper, - availableThemes: themes, - availableLayouts: layouts, - availablePlaceholders: placeholders, - appsConfigurations: YamlToState_Apps(yamlSettings), - }; -}; - -export const StateToJsonSettings = (state: RootState): ISettings => { - return pick(state, [ - 'fancyToolbar', - 'windowManager', - 'seelenweg', - 'selectedTheme', - 'monitors', - 'ahkEnabled', - 'ahkVariables', - 'devTools', - 'language', - ]); -}; - -export const StateAppsToYamlApps = ( - appsConfigurations: AppConfiguration[], - template?: boolean, -): anyObject[] => { - return appsConfigurations - .filter((appConfig) => !appConfig.isBundled) - .map((appConfig: AppConfiguration) => { - const options = Object.values(ApplicationOptions).filter((option) => appConfig[option]); - const yamlApp = { - name: appConfig.name, - template: template || undefined, - category: appConfig.category || undefined, - bound_monitor: appConfig.monitor ?? undefined, - bound_workspace: appConfig.workspace || undefined, - identifier: VariableConvention.fromCamelToSnake(appConfig.identifier), - options: options.length ? options : undefined, - }; - return yamlApp; - }); -}; +import { UserSettings } from '../../../../../../shared.interfaces'; +import { parseAsCamel, VariableConvention } from '../../../../../shared/schemas'; +import { IdWithIdentifierSchema } from '../../../../../shared/schemas/AppsConfigurations'; +import { ISettings } from '../../../../../shared/schemas/Settings'; +import { pick } from 'lodash'; + +import { AppConfiguration, ApplicationOptions } from '../../../appsConfigurations/domain'; +import { RootState } from '../domain'; + +export const YamlToState_Apps = (yaml: anyObject[]): AppConfiguration[] => { + const apps: AppConfiguration[] = []; + + yaml.forEach((ymlApp: anyObject) => { + // filter empty ghost apps used only for add float_identifiers in komorebi cli + if (ymlApp.options || !ymlApp.float_identifiers) { + apps.push({ + name: ymlApp.name, + category: ymlApp.category || null, + monitor: ymlApp.bound_monitor ?? null, + workspace: ymlApp.bound_workspace || null, + identifier: parseAsCamel(IdWithIdentifierSchema, ymlApp.identifier), + isBundled: ymlApp.is_bundled || false, + // options + [ApplicationOptions.Float]: ymlApp.options?.includes(ApplicationOptions.Float) || false, + [ApplicationOptions.Unmanage]: + ymlApp.options?.includes(ApplicationOptions.Unmanage) || false, + [ApplicationOptions.Pinned]: ymlApp.options?.includes(ApplicationOptions.Pinned) || false, + [ApplicationOptions.ForceManage]: + ymlApp.options?.includes(ApplicationOptions.ForceManage) || false, + }); + } + }); + + return apps; +}; + +export const StaticSettingsToState = ( + userSettings: UserSettings, + state: RootState, +): RootState => { + const { jsonSettings, yamlSettings, themes, layouts, placeholders, wallpaper } = userSettings; + + return { + ...state, + ...jsonSettings, + wallpaper, + availableThemes: themes, + availableLayouts: layouts, + availablePlaceholders: placeholders, + appsConfigurations: YamlToState_Apps(yamlSettings), + }; +}; + +export const StateToJsonSettings = (state: RootState): ISettings => { + return pick(state, [ + 'fancyToolbar', + 'windowManager', + 'seelenweg', + 'selectedTheme', + 'monitors', + 'ahkEnabled', + 'ahkVariables', + 'devTools', + 'language', + ]); +}; + +export const StateAppsToYamlApps = ( + appsConfigurations: AppConfiguration[], + template?: boolean, +): anyObject[] => { + return appsConfigurations + .filter((appConfig) => !appConfig.isBundled) + .map((appConfig: AppConfiguration) => { + const options = Object.values(ApplicationOptions).filter((option) => appConfig[option]); + const yamlApp = { + name: appConfig.name, + template: template || undefined, + category: appConfig.category || undefined, + bound_monitor: appConfig.monitor ?? undefined, + bound_workspace: appConfig.workspace || undefined, + identifier: VariableConvention.fromCamelToSnake(appConfig.identifier), + options: options.length ? options : undefined, + }; + return yamlApp; + }); +}; diff --git a/src/apps/settings/modules/shared/store/app/reducer.ts b/src/apps/settings/modules/shared/store/app/reducer.ts index cf154c64..0d753530 100644 --- a/src/apps/settings/modules/shared/store/app/reducer.ts +++ b/src/apps/settings/modules/shared/store/app/reducer.ts @@ -1,125 +1,125 @@ -import { StateBuilder } from '../../../../../shared/StateBuilder'; -import { Route } from '../../../../components/navigation/routes'; -import i18n from '../../../../i18n'; -import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { cloneDeep } from 'lodash'; - -import { AppsConfigSlice } from '../../../appsConfigurations/app/reducer'; -import { FancyToolbarSlice } from '../../../fancyToolbar/app'; -import { MonitorsSlice } from '../../../monitors/main/app'; -import { SeelenWegSlice } from '../../../seelenweg/app'; -import { AhkVariablesSlice } from '../../../shortcuts/app'; -import { SeelenManagerSlice } from '../../../WindowManager/main/app'; -import { matcher, reducersFor, selectorsFor } from '../../utils/app'; - -import { RootState } from '../domain'; - -const initialState: RootState = { - lastLoaded: null, - autostart: false, - route: Route.GENERAL, - fancyToolbar: FancyToolbarSlice.getInitialState(), - seelenweg: SeelenWegSlice.getInitialState(), - windowManager: SeelenManagerSlice.getInitialState(), - toBeSaved: false, - monitors: MonitorsSlice.getInitialState(), - appsConfigurations: AppsConfigSlice.getInitialState(), - ahkEnabled: true, - ahkVariables: AhkVariablesSlice.getInitialState(), - availableThemes: [], - availableLayouts: [], - availablePlaceholders: [], - selectedTheme: [], - devTools: false, - language: navigator.language.split('-')[0] || 'en', - colors: { - background: '#ffffff', - foreground: '#000000', - accent_darkest: '#000000', - accent_darker: '#000000', - accent_dark: '#000000', - accent: '#000000', - accent_light: '#000000', - accent_lighter: '#000000', - accent_lightest: '#000000', - complement: null, - }, - wallpaper: null, -}; - -export const RootSlice = createSlice({ - name: 'main', - initialState, - reducers: { - ...reducersFor(initialState), - setState: (_state, action: PayloadAction) => { - i18n.changeLanguage(action.payload.language); - return action.payload; - }, - setLanguage: (state, action: PayloadAction) => { - state.language = action.payload; - state.toBeSaved = true; - i18n.changeLanguage(action.payload); - }, - restoreToLastLoaded: (state) => { - if (state.lastLoaded) { - const newState = cloneDeep(state.lastLoaded); - newState.lastLoaded = cloneDeep(state.lastLoaded); - newState.route = state.route; - newState.colors = state.colors; - i18n.changeLanguage(newState.language); - return newState; - } - return state; - }, - setDevTools: (state, action: PayloadAction) => { - state.toBeSaved = true; - state.devTools = action.payload; - }, - setSelectedTheme: (state, action: PayloadAction) => { - let themes = new Set(action.payload); - if (!themes.has('default')) { - themes.add('default'); - } - state.toBeSaved = true; - state.selectedTheme = Array.from(themes); - }, - removeTheme: (state, action: PayloadAction) => { - state.toBeSaved = true; - state.selectedTheme = state.selectedTheme.filter((x) => x !== action.payload); - }, - }, - selectors: selectorsFor(initialState), - extraReducers: (builder) => { - builder - .addMatcher(matcher(SeelenManagerSlice), (state, action) => { - state.toBeSaved = true; - state.windowManager = SeelenManagerSlice.reducer(state.windowManager, action); - }) - .addMatcher(matcher(SeelenWegSlice), (state, action) => { - state.toBeSaved = true; - state.seelenweg = SeelenWegSlice.reducer(state.seelenweg, action); - }) - .addMatcher(matcher(MonitorsSlice), (state, action) => { - state.toBeSaved = true; - state.monitors = MonitorsSlice.reducer(state.monitors, action); - }) - .addMatcher(matcher(AppsConfigSlice), (state, action) => { - state.toBeSaved = true; - state.appsConfigurations = AppsConfigSlice.reducer(state.appsConfigurations, action); - }) - .addMatcher(matcher(FancyToolbarSlice), (state, action) => { - state.toBeSaved = true; - state.fancyToolbar = FancyToolbarSlice.reducer(state.fancyToolbar, action); - }) - .addMatcher(matcher(AhkVariablesSlice), (state, action) => { - state.toBeSaved = true; - state.ahkVariables = AhkVariablesSlice.reducer(state.ahkVariables, action); - }); - }, -}); - -export const RootActions = RootSlice.actions; -export const RootReducer = RootSlice.reducer; - -export const newSelectors = StateBuilder.compositeSelector(initialState); +import { StateBuilder } from '../../../../../shared/StateBuilder'; +import { Route } from '../../../../components/navigation/routes'; +import i18n from '../../../../i18n'; +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; +import { cloneDeep } from 'lodash'; + +import { AppsConfigSlice } from '../../../appsConfigurations/app/reducer'; +import { FancyToolbarSlice } from '../../../fancyToolbar/app'; +import { MonitorsSlice } from '../../../monitors/main/app'; +import { SeelenWegSlice } from '../../../seelenweg/app'; +import { AhkVariablesSlice } from '../../../shortcuts/app'; +import { SeelenManagerSlice } from '../../../WindowManager/main/app'; +import { matcher, reducersFor, selectorsFor } from '../../utils/app'; + +import { RootState } from '../domain'; + +const initialState: RootState = { + lastLoaded: null, + autostart: false, + route: Route.GENERAL, + fancyToolbar: FancyToolbarSlice.getInitialState(), + seelenweg: SeelenWegSlice.getInitialState(), + windowManager: SeelenManagerSlice.getInitialState(), + toBeSaved: false, + monitors: MonitorsSlice.getInitialState(), + appsConfigurations: AppsConfigSlice.getInitialState(), + ahkEnabled: true, + ahkVariables: AhkVariablesSlice.getInitialState(), + availableThemes: [], + availableLayouts: [], + availablePlaceholders: [], + selectedTheme: [], + devTools: false, + language: navigator.language.split('-')[0] || 'en', + colors: { + background: '#ffffff', + foreground: '#000000', + accent_darkest: '#000000', + accent_darker: '#000000', + accent_dark: '#000000', + accent: '#000000', + accent_light: '#000000', + accent_lighter: '#000000', + accent_lightest: '#000000', + complement: null, + }, + wallpaper: null, +}; + +export const RootSlice = createSlice({ + name: 'main', + initialState, + reducers: { + ...reducersFor(initialState), + setState: (_state, action: PayloadAction) => { + i18n.changeLanguage(action.payload.language); + return action.payload; + }, + setLanguage: (state, action: PayloadAction) => { + state.language = action.payload; + state.toBeSaved = true; + i18n.changeLanguage(action.payload); + }, + restoreToLastLoaded: (state) => { + if (state.lastLoaded) { + const newState = cloneDeep(state.lastLoaded); + newState.lastLoaded = cloneDeep(state.lastLoaded); + newState.route = state.route; + newState.colors = state.colors; + i18n.changeLanguage(newState.language); + return newState; + } + return state; + }, + setDevTools: (state, action: PayloadAction) => { + state.toBeSaved = true; + state.devTools = action.payload; + }, + setSelectedTheme: (state, action: PayloadAction) => { + let themes = new Set(action.payload); + if (!themes.has('default')) { + themes.add('default'); + } + state.toBeSaved = true; + state.selectedTheme = Array.from(themes); + }, + removeTheme: (state, action: PayloadAction) => { + state.toBeSaved = true; + state.selectedTheme = state.selectedTheme.filter((x) => x !== action.payload); + }, + }, + selectors: selectorsFor(initialState), + extraReducers: (builder) => { + builder + .addMatcher(matcher(SeelenManagerSlice), (state, action) => { + state.toBeSaved = true; + state.windowManager = SeelenManagerSlice.reducer(state.windowManager, action); + }) + .addMatcher(matcher(SeelenWegSlice), (state, action) => { + state.toBeSaved = true; + state.seelenweg = SeelenWegSlice.reducer(state.seelenweg, action); + }) + .addMatcher(matcher(MonitorsSlice), (state, action) => { + state.toBeSaved = true; + state.monitors = MonitorsSlice.reducer(state.monitors, action); + }) + .addMatcher(matcher(AppsConfigSlice), (state, action) => { + state.toBeSaved = true; + state.appsConfigurations = AppsConfigSlice.reducer(state.appsConfigurations, action); + }) + .addMatcher(matcher(FancyToolbarSlice), (state, action) => { + state.toBeSaved = true; + state.fancyToolbar = FancyToolbarSlice.reducer(state.fancyToolbar, action); + }) + .addMatcher(matcher(AhkVariablesSlice), (state, action) => { + state.toBeSaved = true; + state.ahkVariables = AhkVariablesSlice.reducer(state.ahkVariables, action); + }); + }, +}); + +export const RootActions = RootSlice.actions; +export const RootReducer = RootSlice.reducer; + +export const newSelectors = StateBuilder.compositeSelector(initialState); diff --git a/src/apps/settings/modules/shared/store/app/selectors.ts b/src/apps/settings/modules/shared/store/app/selectors.ts index 91ef20fa..4fedc089 100644 --- a/src/apps/settings/modules/shared/store/app/selectors.ts +++ b/src/apps/settings/modules/shared/store/app/selectors.ts @@ -1,18 +1,18 @@ -import { RootSlice } from './reducer'; - -import { SeelenWegSlice } from '../../../seelenweg/app'; -import { BorderSlice } from '../../../WindowManager/border/app'; -import { SeelenManagerSlice } from '../../../WindowManager/main/app'; - -import { RootState } from '../domain'; - -export const ownSelector = (state: RootState) => state; -export const RootSelectors = RootSlice.getSelectors(ownSelector); - -export const SeelenWegSelectors = SeelenWegSlice.getSelectors(RootSelectors.seelenweg); -export const SeelenWmSelectors = SeelenManagerSlice.getSelectors(RootSelectors.windowManager); - -export const BorderSelectors = BorderSlice.getSelectors(SeelenWmSelectors.border); - -export const getMonitorSelector = (idx: number) => (state: RootState) => RootSelectors.monitors(state)[idx]; -export const getWorkspaceSelector = (idx: number, monitorIdx: number) => (state: RootState) => getMonitorSelector(monitorIdx)(state)?.workspaces[idx]; +import { RootSlice } from './reducer'; + +import { SeelenWegSlice } from '../../../seelenweg/app'; +import { BorderSlice } from '../../../WindowManager/border/app'; +import { SeelenManagerSlice } from '../../../WindowManager/main/app'; + +import { RootState } from '../domain'; + +export const ownSelector = (state: RootState) => state; +export const RootSelectors = RootSlice.getSelectors(ownSelector); + +export const SeelenWegSelectors = SeelenWegSlice.getSelectors(RootSelectors.seelenweg); +export const SeelenWmSelectors = SeelenManagerSlice.getSelectors(RootSelectors.windowManager); + +export const BorderSelectors = BorderSlice.getSelectors(SeelenWmSelectors.border); + +export const getMonitorSelector = (idx: number) => (state: RootState) => RootSelectors.monitors(state)[idx]; +export const getWorkspaceSelector = (idx: number, monitorIdx: number) => (state: RootState) => getMonitorSelector(monitorIdx)(state)?.workspaces[idx]; diff --git a/src/apps/settings/modules/shared/store/domain.ts b/src/apps/settings/modules/shared/store/domain.ts index 62599c89..1b6eb823 100644 --- a/src/apps/settings/modules/shared/store/domain.ts +++ b/src/apps/settings/modules/shared/store/domain.ts @@ -1,33 +1,33 @@ -import { Layout } from '../../../../shared/schemas/Layout'; -import { Placeholder } from '../../../../shared/schemas/Placeholders'; -import { ISettings } from '../../../../shared/schemas/Settings'; -import { Theme } from '../../../../shared/schemas/Theme'; -import { Route } from '../../../components/navigation/routes'; - -import { AppConfiguration } from '../../appsConfigurations/domain'; - -export interface UIColors { - background: string; - foreground: string; - accent_darkest: string; - accent_darker: string; - accent_dark: string; - accent: string; - accent_light: string; - accent_lighter: string; - accent_lightest: string; - complement: string | null; -} - -export interface RootState extends ISettings { - lastLoaded: this | null; - route: Route; - toBeSaved: boolean; - appsConfigurations: AppConfiguration[]; - availableThemes: Theme[]; - availableLayouts: Layout[]; - availablePlaceholders: Placeholder[]; - autostart: boolean; - colors: UIColors; - wallpaper: string | null; -} +import { Layout } from '../../../../shared/schemas/Layout'; +import { Placeholder } from '../../../../shared/schemas/Placeholders'; +import { ISettings } from '../../../../shared/schemas/Settings'; +import { Theme } from '../../../../shared/schemas/Theme'; +import { Route } from '../../../components/navigation/routes'; + +import { AppConfiguration } from '../../appsConfigurations/domain'; + +export interface UIColors { + background: string; + foreground: string; + accent_darkest: string; + accent_darker: string; + accent_dark: string; + accent: string; + accent_light: string; + accent_lighter: string; + accent_lightest: string; + complement: string | null; +} + +export interface RootState extends ISettings { + lastLoaded: this | null; + route: Route; + toBeSaved: boolean; + appsConfigurations: AppConfiguration[]; + availableThemes: Theme[]; + availableLayouts: Layout[]; + availablePlaceholders: Placeholder[]; + autostart: boolean; + colors: UIColors; + wallpaper: string | null; +} diff --git a/src/apps/settings/modules/shared/store/infra.ts b/src/apps/settings/modules/shared/store/infra.ts index 6932ca31..20df159a 100644 --- a/src/apps/settings/modules/shared/store/infra.ts +++ b/src/apps/settings/modules/shared/store/infra.ts @@ -1,118 +1,118 @@ -import { setColorsAsCssVariables } from '../../../../shared'; -import { parseAsCamel } from '../../../../shared/schemas'; -import { SettingsSchema } from '../../../../shared/schemas/Settings'; -import { Theme } from '../../../../shared/schemas/Theme'; -import { saveUserSettings, UserSettingsLoader } from './storeApi'; -import { configureStore } from '@reduxjs/toolkit'; -import { emit, listen as listenGlobal } from '@tauri-apps/api/event'; -import { Modal } from 'antd'; -import { cloneDeep, debounce } from 'lodash'; - -import { startup } from '../tauri/infra'; - -import { RootActions, RootReducer } from './app/reducer'; -import { - StateAppsToYamlApps, - StateToJsonSettings, - StaticSettingsToState, - YamlToState_Apps, -} from './app/StateBridge'; - -import { RootState, UIColors } from './domain'; - -const IsSavingSettings = { current: false }; - -export const store = configureStore({ - reducer: RootReducer, -}); - -export type AppDispatch = typeof store.dispatch; -export type store = { - dispatch: AppDispatch; - getState: () => RootState; -}; - -export async function registerStoreEvents() { - await listenGlobal('placeholders', async () => { - const userSettings = await new UserSettingsLoader().withPlaceholders().load(); - store.dispatch(RootActions.setAvailablePlaceholders(userSettings.placeholders)); - }); - - await listenGlobal('themes', (event) => { - store.dispatch(RootActions.setAvailableThemes(event.payload)); - }); - - await listenGlobal('colors', (event) => { - setColorsAsCssVariables(event.payload); - store.dispatch(RootActions.setColors(event.payload)); - }); - - await listenGlobal('settings-by-app', (event) => { - store.dispatch(RootActions.setAppsConfigurations(YamlToState_Apps(event.payload))); - }); - - await listenGlobal( - 'settings', - debounce((event) => { - if (IsSavingSettings.current) { - IsSavingSettings.current = false; - return; - } - const currentState = store.getState(); - const newState: RootState = { - ...currentState, - ...parseAsCamel(SettingsSchema, event.payload), - toBeSaved: false, - }; - store.dispatch(RootActions.setState(newState)); - }, 100), - ); - - await emit('register-colors-events'); -} - -export const LoadSettingsToStore = async (customPath?: string) => { - startup.isEnabled().then((value) => { - store.dispatch(RootActions.setAutostart(value)); - }); - - const userSettings = await new UserSettingsLoader() - .withLayouts() - .withPlaceholders() - .withUserApps() - .withWallpaper() - .load(customPath); - - const currentState = store.getState(); - const newState = StaticSettingsToState(userSettings, currentState); - newState.lastLoaded = cloneDeep(newState); - store.dispatch(RootActions.setState(newState)); - - /* // !customPath => avoid start user on manual user loading file - if (!Object.keys(userSettings.jsonSettings).length && !customPath) { - StartUser(); - } */ -}; - -export const SaveStore = async () => { - try { - const currentState = store.getState(); - const settings = { - jsonSettings: StateToJsonSettings(currentState), - yamlSettings: [ - //...StateAppsToYamlApps(currentState.appsTemplates.flatMap((x) => x.apps), true), - ...StateAppsToYamlApps(currentState.appsConfigurations), - ], - }; - - IsSavingSettings.current = true; - await saveUserSettings(settings); - store.dispatch(RootActions.setToBeSaved(false)); - } catch (error) { - Modal.error({ - title: 'Error on Save', - content: String(error), - centered: true, - }); - } -}; +import { setColorsAsCssVariables } from '../../../../shared'; +import { parseAsCamel } from '../../../../shared/schemas'; +import { SettingsSchema } from '../../../../shared/schemas/Settings'; +import { Theme } from '../../../../shared/schemas/Theme'; +import { saveUserSettings, UserSettingsLoader } from './storeApi'; +import { configureStore } from '@reduxjs/toolkit'; +import { emit, listen as listenGlobal } from '@tauri-apps/api/event'; +import { Modal } from 'antd'; +import { cloneDeep, debounce } from 'lodash'; + +import { startup } from '../tauri/infra'; + +import { RootActions, RootReducer } from './app/reducer'; +import { + StateAppsToYamlApps, + StateToJsonSettings, + StaticSettingsToState, + YamlToState_Apps, +} from './app/StateBridge'; + +import { RootState, UIColors } from './domain'; + +const IsSavingSettings = { current: false }; + +export const store = configureStore({ + reducer: RootReducer, +}); + +export type AppDispatch = typeof store.dispatch; +export type store = { + dispatch: AppDispatch; + getState: () => RootState; +}; + +export async function registerStoreEvents() { + await listenGlobal('placeholders', async () => { + const userSettings = await new UserSettingsLoader().withPlaceholders().load(); + store.dispatch(RootActions.setAvailablePlaceholders(userSettings.placeholders)); + }); + + await listenGlobal('themes', (event) => { + store.dispatch(RootActions.setAvailableThemes(event.payload)); + }); + + await listenGlobal('colors', (event) => { + setColorsAsCssVariables(event.payload); + store.dispatch(RootActions.setColors(event.payload)); + }); + + await listenGlobal('settings-by-app', (event) => { + store.dispatch(RootActions.setAppsConfigurations(YamlToState_Apps(event.payload))); + }); + + await listenGlobal( + 'settings', + debounce((event) => { + if (IsSavingSettings.current) { + IsSavingSettings.current = false; + return; + } + const currentState = store.getState(); + const newState: RootState = { + ...currentState, + ...parseAsCamel(SettingsSchema, event.payload), + toBeSaved: false, + }; + store.dispatch(RootActions.setState(newState)); + }, 100), + ); + + await emit('register-colors-events'); +} + +export const LoadSettingsToStore = async (customPath?: string) => { + startup.isEnabled().then((value) => { + store.dispatch(RootActions.setAutostart(value)); + }); + + const userSettings = await new UserSettingsLoader() + .withLayouts() + .withPlaceholders() + .withUserApps() + .withWallpaper() + .load(customPath); + + const currentState = store.getState(); + const newState = StaticSettingsToState(userSettings, currentState); + newState.lastLoaded = cloneDeep(newState); + store.dispatch(RootActions.setState(newState)); + + /* // !customPath => avoid start user on manual user loading file + if (!Object.keys(userSettings.jsonSettings).length && !customPath) { + StartUser(); + } */ +}; + +export const SaveStore = async () => { + try { + const currentState = store.getState(); + const settings = { + jsonSettings: StateToJsonSettings(currentState), + yamlSettings: [ + //...StateAppsToYamlApps(currentState.appsTemplates.flatMap((x) => x.apps), true), + ...StateAppsToYamlApps(currentState.appsConfigurations), + ], + }; + + IsSavingSettings.current = true; + await saveUserSettings(settings); + store.dispatch(RootActions.setToBeSaved(false)); + } catch (error) { + Modal.error({ + title: 'Error on Save', + content: String(error), + centered: true, + }); + } +}; diff --git a/src/apps/settings/modules/shared/store/storeApi.ts b/src/apps/settings/modules/shared/store/storeApi.ts index af784b2e..b4b9473d 100644 --- a/src/apps/settings/modules/shared/store/storeApi.ts +++ b/src/apps/settings/modules/shared/store/storeApi.ts @@ -1,220 +1,220 @@ -import { UserSettings } from '../../../../../shared.interfaces'; -import { parseAsCamel, safeParseAsCamel, VariableConvention } from '../../../../shared/schemas'; -import { Layout, LayoutSchema } from '../../../../shared/schemas/Layout'; -import { ParsePlaceholder } from '../../../../shared/schemas/Placeholders'; -import { SettingsSchema } from '../../../../shared/schemas/Settings'; -import { path } from '@tauri-apps/api'; -import { convertFileSrc, invoke } from '@tauri-apps/api/core'; -import { DirEntry } from '@tauri-apps/plugin-fs'; -import yaml from 'js-yaml'; - -import { resolveDataPath } from '../config/infra'; -import { dialog, fs } from '../tauri/infra'; - -interface Entry extends DirEntry { - path: string; -} - -async function getEntries(folderName: string) { - const bundledPath = await path.join(await path.resourceDir(), 'static', folderName); - const userPath = await path.join(await path.appDataDir(), folderName); - - const entries: Entry[] = []; - - for (const entry of await fs.readDir(bundledPath)) { - entries.push({ - ...entry, - path: await path.join(bundledPath, entry.name), - }); - } - - for (const entry of await fs.readDir(userPath)) { - entries.push({ - ...entry, - path: await path.join(userPath, entry.name), - }); - } - - return entries; -} - -async function loadUserLayouts(ref: UserSettings) { - const defaultLayout = ref.jsonSettings.windowManager.defaultLayout; - let found = false; - - for (const entry of await getEntries('layouts')) { - if (entry.isFile && entry.name.endsWith('.json')) { - let layout: Layout = JSON.parse(await fs.readTextFile(entry.path)); - - layout = safeParseAsCamel(LayoutSchema, layout); - if (!layout) { - continue; - } - - const sanitizedLayout: Layout = { - ...layout, - info: { - ...layout.info, - filename: entry.name, - }, - }; - - if (sanitizedLayout.info.displayName === 'Unknown') { - sanitizedLayout.info.displayName = entry.name; - } - - if (defaultLayout === entry.name) { - found = true; - } - - ref.layouts.push(sanitizedLayout); - } - } - - if (!found) { - ref.jsonSettings.windowManager.defaultLayout = ref.layouts[0]?.info.filename || null; - } -} - -async function loadUserPlaceholders(ref: UserSettings) { - const selectedPlaceholder = ref.jsonSettings.fancyToolbar.placeholder; - - const rawPlaceholders: any[] = await invoke('state_get_placeholders'); - for (const rawPlaceholder of rawPlaceholders) { - let placeholder = ParsePlaceholder(rawPlaceholder); - if (placeholder) { - ref.placeholders.push(placeholder); - } - } - - let usingPlaceholder = ref.placeholders.find((x) => x.info.filename === selectedPlaceholder); - if (!usingPlaceholder) { - ref.jsonSettings.fancyToolbar.placeholder = ref.placeholders[0]?.info.filename || null; - } -} - -export class UserSettingsLoader { - private _withUserApps: boolean = false; - private _withLayouts: boolean = false; - private _withPlaceholders: boolean = false; - private _withThemes: boolean = true; - private _withWallpaper: boolean = true; - - withUserApps() { - this._withUserApps = true; - return this; - } - - withLayouts() { - this._withLayouts = true; - return this; - } - - withPlaceholders() { - this._withPlaceholders = true; - return this; - } - - withWallpaper() { - this._withWallpaper = true; - return this; - } - - withThemes(value: boolean) { - this._withThemes = value; - return this; - } - - async load(customPath?: string): Promise { - const userSettings: UserSettings = { - jsonSettings: parseAsCamel(SettingsSchema, {}), - yamlSettings: [], - themes: [], - layouts: [], - placeholders: [], - env: await invoke('get_user_envs'), - wallpaper: null, - }; - - let data = - customPath && (await fs.exists(customPath)) - ? JSON.parse(await fs.readTextFile(customPath)) - : await invoke('state_get_settings'); - - userSettings.jsonSettings = parseAsCamel(SettingsSchema, data); - - if (this._withUserApps) { - userSettings.yamlSettings = await invoke('state_get_specific_apps_configurations'); - } - - if (this._withThemes) { - userSettings.themes = await invoke('state_get_themes'); - } - - if (this._withLayouts) { - await loadUserLayouts(userSettings); - } - - if (this._withPlaceholders) { - await loadUserPlaceholders(userSettings); - } - - if (this._withWallpaper) { - userSettings.wallpaper = convertFileSrc(await invoke('state_get_wallpaper')); - } - - return userSettings; - } -} - -export async function saveJsonSettings(settings: UserSettings['jsonSettings']) { - const json_route = await resolveDataPath('settings.json'); - await fs.writeTextFile(json_route, JSON.stringify(VariableConvention.fromCamelToSnake(settings), null, 2)); -} - -export async function saveUserSettings(settings: Pick) { - const yaml_route = await resolveDataPath('applications.yml'); - - await saveJsonSettings(settings.jsonSettings); - - await fs.writeTextFile(yaml_route, yaml.dump(settings.yamlSettings)); - - if (settings.jsonSettings.ahkEnabled) { - await invoke('start_seelen_shortcuts'); - } else { - await invoke('kill_seelen_shortcuts'); - } -} - -export async function ImportApps() { - const data: any[] = []; - - const files = await dialog.open({ - defaultPath: await path.resolveResource('static/apps_templates'), - multiple: true, - title: 'Select template', - filters: [{ name: 'apps', extensions: ['yaml', 'yml'] }], - }); - - if (!files) { - return data; - } - - for (const file of [files].flat()) { - const processed = yaml.load(await fs.readTextFile(file.path)); - data.push(...(Array.isArray(processed) ? processed : [])); - } - - return data; -} - -export async function ExportApps(apps: any[]) { - const pathToSave = await dialog.save({ - title: 'Exporting Apps', - defaultPath: await path.join(await path.homeDir(), 'downloads/apps.yaml'), - filters: [{ name: 'apps', extensions: ['yaml', 'yml'] }], - }); - if (pathToSave) { - fs.writeTextFile(pathToSave, yaml.dump(apps)); - } -} +import { UserSettings } from '../../../../../shared.interfaces'; +import { parseAsCamel, safeParseAsCamel, VariableConvention } from '../../../../shared/schemas'; +import { Layout, LayoutSchema } from '../../../../shared/schemas/Layout'; +import { ParsePlaceholder } from '../../../../shared/schemas/Placeholders'; +import { SettingsSchema } from '../../../../shared/schemas/Settings'; +import { path } from '@tauri-apps/api'; +import { convertFileSrc, invoke } from '@tauri-apps/api/core'; +import { DirEntry } from '@tauri-apps/plugin-fs'; +import yaml from 'js-yaml'; + +import { resolveDataPath } from '../config/infra'; +import { dialog, fs } from '../tauri/infra'; + +interface Entry extends DirEntry { + path: string; +} + +async function getEntries(folderName: string) { + const bundledPath = await path.join(await path.resourceDir(), 'static', folderName); + const userPath = await path.join(await path.appDataDir(), folderName); + + const entries: Entry[] = []; + + for (const entry of await fs.readDir(bundledPath)) { + entries.push({ + ...entry, + path: await path.join(bundledPath, entry.name), + }); + } + + for (const entry of await fs.readDir(userPath)) { + entries.push({ + ...entry, + path: await path.join(userPath, entry.name), + }); + } + + return entries; +} + +async function loadUserLayouts(ref: UserSettings) { + const defaultLayout = ref.jsonSettings.windowManager.defaultLayout; + let found = false; + + for (const entry of await getEntries('layouts')) { + if (entry.isFile && entry.name.endsWith('.json')) { + let layout: Layout = JSON.parse(await fs.readTextFile(entry.path)); + + layout = safeParseAsCamel(LayoutSchema, layout); + if (!layout) { + continue; + } + + const sanitizedLayout: Layout = { + ...layout, + info: { + ...layout.info, + filename: entry.name, + }, + }; + + if (sanitizedLayout.info.displayName === 'Unknown') { + sanitizedLayout.info.displayName = entry.name; + } + + if (defaultLayout === entry.name) { + found = true; + } + + ref.layouts.push(sanitizedLayout); + } + } + + if (!found) { + ref.jsonSettings.windowManager.defaultLayout = ref.layouts[0]?.info.filename || null; + } +} + +async function loadUserPlaceholders(ref: UserSettings) { + const selectedPlaceholder = ref.jsonSettings.fancyToolbar.placeholder; + + const rawPlaceholders: any[] = await invoke('state_get_placeholders'); + for (const rawPlaceholder of rawPlaceholders) { + let placeholder = ParsePlaceholder(rawPlaceholder); + if (placeholder) { + ref.placeholders.push(placeholder); + } + } + + let usingPlaceholder = ref.placeholders.find((x) => x.info.filename === selectedPlaceholder); + if (!usingPlaceholder) { + ref.jsonSettings.fancyToolbar.placeholder = ref.placeholders[0]?.info.filename || null; + } +} + +export class UserSettingsLoader { + private _withUserApps: boolean = false; + private _withLayouts: boolean = false; + private _withPlaceholders: boolean = false; + private _withThemes: boolean = true; + private _withWallpaper: boolean = true; + + withUserApps() { + this._withUserApps = true; + return this; + } + + withLayouts() { + this._withLayouts = true; + return this; + } + + withPlaceholders() { + this._withPlaceholders = true; + return this; + } + + withWallpaper() { + this._withWallpaper = true; + return this; + } + + withThemes(value: boolean) { + this._withThemes = value; + return this; + } + + async load(customPath?: string): Promise { + const userSettings: UserSettings = { + jsonSettings: parseAsCamel(SettingsSchema, {}), + yamlSettings: [], + themes: [], + layouts: [], + placeholders: [], + env: await invoke('get_user_envs'), + wallpaper: null, + }; + + let data = + customPath && (await fs.exists(customPath)) + ? JSON.parse(await fs.readTextFile(customPath)) + : await invoke('state_get_settings'); + + userSettings.jsonSettings = parseAsCamel(SettingsSchema, data); + + if (this._withUserApps) { + userSettings.yamlSettings = await invoke('state_get_specific_apps_configurations'); + } + + if (this._withThemes) { + userSettings.themes = await invoke('state_get_themes'); + } + + if (this._withLayouts) { + await loadUserLayouts(userSettings); + } + + if (this._withPlaceholders) { + await loadUserPlaceholders(userSettings); + } + + if (this._withWallpaper) { + userSettings.wallpaper = convertFileSrc(await invoke('state_get_wallpaper')); + } + + return userSettings; + } +} + +export async function saveJsonSettings(settings: UserSettings['jsonSettings']) { + const json_route = await resolveDataPath('settings.json'); + await fs.writeTextFile(json_route, JSON.stringify(VariableConvention.fromCamelToSnake(settings), null, 2)); +} + +export async function saveUserSettings(settings: Pick) { + const yaml_route = await resolveDataPath('applications.yml'); + + await saveJsonSettings(settings.jsonSettings); + + await fs.writeTextFile(yaml_route, yaml.dump(settings.yamlSettings)); + + if (settings.jsonSettings.ahkEnabled) { + await invoke('start_seelen_shortcuts'); + } else { + await invoke('kill_seelen_shortcuts'); + } +} + +export async function ImportApps() { + const data: any[] = []; + + const files = await dialog.open({ + defaultPath: await path.resolveResource('static/apps_templates'), + multiple: true, + title: 'Select template', + filters: [{ name: 'apps', extensions: ['yaml', 'yml'] }], + }); + + if (!files) { + return data; + } + + for (const file of [files].flat()) { + const processed = yaml.load(await fs.readTextFile(file.path)); + data.push(...(Array.isArray(processed) ? processed : [])); + } + + return data; +} + +export async function ExportApps(apps: any[]) { + const pathToSave = await dialog.save({ + title: 'Exporting Apps', + defaultPath: await path.join(await path.homeDir(), 'downloads/apps.yaml'), + filters: [{ name: 'apps', extensions: ['yaml', 'yml'] }], + }); + if (pathToSave) { + fs.writeTextFile(pathToSave, yaml.dump(apps)); + } +} diff --git a/src/apps/settings/modules/shared/tauri/infra.ts b/src/apps/settings/modules/shared/tauri/infra.ts index 05d173cd..2cdbed47 100644 --- a/src/apps/settings/modules/shared/tauri/infra.ts +++ b/src/apps/settings/modules/shared/tauri/infra.ts @@ -1,24 +1,24 @@ -import { invoke } from '@tauri-apps/api/core'; -import * as oldStartup from '@tauri-apps/plugin-autostart'; - -export * as dialog from '@tauri-apps/plugin-dialog'; -export * as fs from '@tauri-apps/plugin-fs'; - -export class startup { - static async enable(): Promise { - await invoke('set_auto_start', { enabled: true }); - } - - static async disable(): Promise { - await invoke('set_auto_start', { enabled: false }); - } - - static async isEnabled(): Promise { - // migration from old autostart to new - if (await oldStartup.isEnabled()) { - await oldStartup.disable(); - await startup.enable(); - } - return await invoke('get_auto_start_status'); - } +import { invoke } from '@tauri-apps/api/core'; +import * as oldStartup from '@tauri-apps/plugin-autostart'; + +export * as dialog from '@tauri-apps/plugin-dialog'; +export * as fs from '@tauri-apps/plugin-fs'; + +export class startup { + static async enable(): Promise { + await invoke('set_auto_start', { enabled: true }); + } + + static async disable(): Promise { + await invoke('set_auto_start', { enabled: false }); + } + + static async isEnabled(): Promise { + // migration from old autostart to new + if (await oldStartup.isEnabled()) { + await oldStartup.disable(); + await startup.enable(); + } + return await invoke('get_auto_start_status'); + } } \ No newline at end of file diff --git a/src/apps/settings/modules/shared/utils/app.ts b/src/apps/settings/modules/shared/utils/app.ts index 9dfbf140..520764fa 100644 --- a/src/apps/settings/modules/shared/utils/app.ts +++ b/src/apps/settings/modules/shared/utils/app.ts @@ -1,78 +1,78 @@ -import { Action, Slice } from '@reduxjs/toolkit'; - -import { HexColor, ReducersFor, SelectorsFor } from './domain'; - -type Args = undefined | string | { [x: string]: boolean | null | undefined }; -export const cx = (...args: Args[]): string => { - return args - .map((arg) => { - if (!arg) { - return; - } - - if (typeof arg === 'string') { - return arg; - } - - return Object.keys(arg) - .map((key) => (arg[key] ? key : '')) - .join(' '); - }) - .join(' '); -}; - -export const matcher = (slice: Slice) => (action: Action) => action.type.startsWith(slice.name); - -export const selectorsFor = (state: T): SelectorsFor => { - const selectors = {} as SelectorsFor; - for (const key in state) { - selectors[key] = (state: T) => state[key]; - } - return selectors; -}; - -export const capitalize = (text: string) => { - return text.slice(0, 1).toUpperCase() + text.slice(1); -}; - -export const reducersFor = (state: T): ReducersFor => { - const reducers: any = {}; - for (const key in state) { - reducers[`set${capitalize(key)}`] = (state: T, action: any) => { - state[key] = action.payload; - }; - } - return reducers; -}; - -export const defaultOnNull = (value: T | null | undefined, onNull: T): T => { - if (value == null) { - return onNull; - } - return value; -}; - -export const validateHexColor = (str: string): HexColor | null => { - if (!str.startsWith('#')) { - return null; - } - return str as HexColor; -}; - -export const OptionsFromEnum = (obj: anyObject) => - Object.values(obj).map((value) => ({ - label: value, - value, - })); - -export function debounce(fn: T, delay: number): T { - let timeoutId: NodeJS.Timeout; - - return function debounced(this: ThisParameterType, ...args: Parameters): void { - const context = this; - clearTimeout(timeoutId); - timeoutId = setTimeout(() => { - fn.apply(context, args); - }, delay); - } as T; -} +import { Action, Slice } from '@reduxjs/toolkit'; + +import { HexColor, ReducersFor, SelectorsFor } from './domain'; + +type Args = undefined | string | { [x: string]: boolean | null | undefined }; +export const cx = (...args: Args[]): string => { + return args + .map((arg) => { + if (!arg) { + return; + } + + if (typeof arg === 'string') { + return arg; + } + + return Object.keys(arg) + .map((key) => (arg[key] ? key : '')) + .join(' '); + }) + .join(' '); +}; + +export const matcher = (slice: Slice) => (action: Action) => action.type.startsWith(slice.name); + +export const selectorsFor = (state: T): SelectorsFor => { + const selectors = {} as SelectorsFor; + for (const key in state) { + selectors[key] = (state: T) => state[key]; + } + return selectors; +}; + +export const capitalize = (text: string) => { + return text.slice(0, 1).toUpperCase() + text.slice(1); +}; + +export const reducersFor = (state: T): ReducersFor => { + const reducers: any = {}; + for (const key in state) { + reducers[`set${capitalize(key)}`] = (state: T, action: any) => { + state[key] = action.payload; + }; + } + return reducers; +}; + +export const defaultOnNull = (value: T | null | undefined, onNull: T): T => { + if (value == null) { + return onNull; + } + return value; +}; + +export const validateHexColor = (str: string): HexColor | null => { + if (!str.startsWith('#')) { + return null; + } + return str as HexColor; +}; + +export const OptionsFromEnum = (obj: anyObject) => + Object.values(obj).map((value) => ({ + label: value, + value, + })); + +export function debounce(fn: T, delay: number): T { + let timeoutId: NodeJS.Timeout; + + return function debounced(this: ThisParameterType, ...args: Parameters): void { + const context = this; + clearTimeout(timeoutId); + timeoutId = setTimeout(() => { + fn.apply(context, args); + }, delay); + } as T; +} diff --git a/src/apps/settings/modules/shared/utils/app/Rect.ts b/src/apps/settings/modules/shared/utils/app/Rect.ts index a38a68ff..93bc950f 100644 --- a/src/apps/settings/modules/shared/utils/app/Rect.ts +++ b/src/apps/settings/modules/shared/utils/app/Rect.ts @@ -1,19 +1,19 @@ -import { ClassBuilder, Deserialize, Serialize } from 'readable-types'; - -export interface Rect { - left: number; - top: number; - right: number; - bottom: number; -} - -export const Rect = new ClassBuilder( - class Rect { - left: number = 0; - top: number = 0; - right: number = 0; - bottom: number = 0; - }, -) - .decorate(Serialize, Deserialize) - .build(); +import { ClassBuilder, Deserialize, Serialize } from 'readable-types'; + +export interface Rect { + left: number; + top: number; + right: number; + bottom: number; +} + +export const Rect = new ClassBuilder( + class Rect { + left: number = 0; + top: number = 0; + right: number = 0; + bottom: number = 0; + }, +) + .decorate(Serialize, Deserialize) + .build(); diff --git a/src/apps/settings/modules/shared/utils/domain.ts b/src/apps/settings/modules/shared/utils/domain.ts index d59b7c2a..1f31f4d7 100644 --- a/src/apps/settings/modules/shared/utils/domain.ts +++ b/src/apps/settings/modules/shared/utils/domain.ts @@ -1,8 +1,8 @@ -import { CaseReducer, PayloadAction } from '@reduxjs/toolkit'; -import { cast } from 'readable-types'; - -export type HexColor = `#${string}`; - -export type SelectorsFor = { [K in keyof T]: (state: T) => T[K] }; - +import { CaseReducer, PayloadAction } from '@reduxjs/toolkit'; +import { cast } from 'readable-types'; + +export type HexColor = `#${string}`; + +export type SelectorsFor = { [K in keyof T]: (state: T) => T[K] }; + export type ReducersFor = { [K in keyof T as `set${Capitalize>}`]: CaseReducer> }; \ No newline at end of file diff --git a/src/apps/settings/modules/shared/utils/infra.ts b/src/apps/settings/modules/shared/utils/infra.ts index a6e2a55c..63216c9e 100644 --- a/src/apps/settings/modules/shared/utils/infra.ts +++ b/src/apps/settings/modules/shared/utils/infra.ts @@ -1,13 +1,13 @@ -import { useCallback } from 'react'; -import { TypedUseSelectorHook, useDispatch, useSelector, useStore } from 'react-redux'; - -import type { AppDispatch, store } from '../store/infra'; - -import { RootState } from '../store/domain'; - -type DispatchFunc = () => AppDispatch; -export const useAppDispatch: DispatchFunc = useDispatch; -export const useAppSelector: TypedUseSelectorHook = useSelector; -export const useAppStore: () => store = useStore; - +import { useCallback } from 'react'; +import { TypedUseSelectorHook, useDispatch, useSelector, useStore } from 'react-redux'; + +import type { AppDispatch, store } from '../store/infra'; + +import { RootState } from '../store/domain'; + +type DispatchFunc = () => AppDispatch; +export const useAppDispatch: DispatchFunc = useDispatch; +export const useAppSelector: TypedUseSelectorHook = useSelector; +export const useAppStore: () => store = useStore; + export const useDispatchCallback = (cb: fn): fn => useCallback(cb, []); \ No newline at end of file diff --git a/src/apps/settings/modules/shortcuts/app.ts b/src/apps/settings/modules/shortcuts/app.ts index 996dd049..167d0f25 100644 --- a/src/apps/settings/modules/shortcuts/app.ts +++ b/src/apps/settings/modules/shortcuts/app.ts @@ -1,87 +1,87 @@ -import { parseAsCamel } from '../../../shared/schemas'; -import { AhkVar, AhkVariables, AhkVariablesSchema } from '../../../shared/schemas/Settings'; -import { createSlice, PayloadAction } from '@reduxjs/toolkit'; - -import { selectorsFor } from '../shared/utils/app'; - -function getAHK(code: string): string | undefined { - if (code.startsWith('Key')) { - return code.replace('Key', ''); - } - - if (code.startsWith('Digit')) { - return code.replace('Digit', ''); - } - - if (code.startsWith('Arrow')) { - return code.replace('Arrow', ''); - } - - if (/F[0-9]+$/.test(code)) { - return code; - } - - if (/Numpad[0-9]$/.test(code)) { - return code; - } - - return; -} - -export function KeyCodeToAHK(e: React.KeyboardEvent) { - e.preventDefault(); - let fancy = ''; - let ahk = ''; - - if (['Control', 'Shift', 'Alt', 'Meta'].includes(e.key)) { - return; - } - - let key = getAHK(e.code); - if (!key) { - return; - } - - if (e.metaKey) { - fancy += 'Win + '; - ahk += '#'; - } - - if (e.ctrlKey) { - fancy += 'Ctrl + '; - ahk += '^'; - } - - if (e.altKey) { - fancy += 'Alt + '; - ahk += '!'; - } - - if (e.shiftKey) { - fancy += 'Shift + '; - ahk += '+'; - } - - fancy += key; - ahk += key.toLocaleLowerCase(); - - return { - fancy, - ahk, - }; -} - -const initialState: AhkVariables = parseAsCamel(AhkVariablesSchema, {}); - -export const AhkVariablesSlice = createSlice({ - name: 'AhkVariables', - initialState, - selectors: selectorsFor(initialState), - reducers: { - setVariable(state, action: PayloadAction<{ name: string; value: AhkVar }>) { - state[action.payload.name] = action.payload.value; - }, - }, -}); - +import { parseAsCamel } from '../../../shared/schemas'; +import { AhkVar, AhkVariables, AhkVariablesSchema } from '../../../shared/schemas/Settings'; +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + +import { selectorsFor } from '../shared/utils/app'; + +function getAHK(code: string): string | undefined { + if (code.startsWith('Key')) { + return code.replace('Key', ''); + } + + if (code.startsWith('Digit')) { + return code.replace('Digit', ''); + } + + if (code.startsWith('Arrow')) { + return code.replace('Arrow', ''); + } + + if (/F[0-9]+$/.test(code)) { + return code; + } + + if (/Numpad[0-9]$/.test(code)) { + return code; + } + + return; +} + +export function KeyCodeToAHK(e: React.KeyboardEvent) { + e.preventDefault(); + let fancy = ''; + let ahk = ''; + + if (['Control', 'Shift', 'Alt', 'Meta'].includes(e.key)) { + return; + } + + let key = getAHK(e.code); + if (!key) { + return; + } + + if (e.metaKey) { + fancy += 'Win + '; + ahk += '#'; + } + + if (e.ctrlKey) { + fancy += 'Ctrl + '; + ahk += '^'; + } + + if (e.altKey) { + fancy += 'Alt + '; + ahk += '!'; + } + + if (e.shiftKey) { + fancy += 'Shift + '; + ahk += '+'; + } + + fancy += key; + ahk += key.toLocaleLowerCase(); + + return { + fancy, + ahk, + }; +} + +const initialState: AhkVariables = parseAsCamel(AhkVariablesSchema, {}); + +export const AhkVariablesSlice = createSlice({ + name: 'AhkVariables', + initialState, + selectors: selectorsFor(initialState), + reducers: { + setVariable(state, action: PayloadAction<{ name: string; value: AhkVar }>) { + state[action.payload.name] = action.payload.value; + }, + }, +}); + export const AhkVariablesActions = AhkVariablesSlice.actions; \ No newline at end of file diff --git a/src/apps/settings/modules/shortcuts/domain.ts b/src/apps/settings/modules/shortcuts/domain.ts index 417a5390..43db7b47 100644 --- a/src/apps/settings/modules/shortcuts/domain.ts +++ b/src/apps/settings/modules/shortcuts/domain.ts @@ -1,4 +1,4 @@ - -export interface Shortcuts { - + +export interface Shortcuts { + } \ No newline at end of file diff --git a/src/apps/settings/modules/shortcuts/infrastructure.tsx b/src/apps/settings/modules/shortcuts/infrastructure.tsx index 9120e3bd..aa18bc71 100644 --- a/src/apps/settings/modules/shortcuts/infrastructure.tsx +++ b/src/apps/settings/modules/shortcuts/infrastructure.tsx @@ -1,63 +1,63 @@ -import { VariableConvention } from '../../../shared/schemas'; -import { SettingsGroup, SettingsOption } from '../../components/SettingsBox'; -import { Input, Switch, Tooltip } from 'antd'; -import { useTranslation } from 'react-i18next'; -import { useDispatch, useSelector } from 'react-redux'; - -import { RootActions } from '../shared/store/app/reducer'; -import { RootSelectors } from '../shared/store/app/selectors'; -import { AhkVariablesActions, KeyCodeToAHK } from './app'; - -export function Shortcuts() { - const ahkEnable = useSelector(RootSelectors.ahkEnabled); - const ahkVariables = useSelector(RootSelectors.ahkVariables); - - const dispatch = useDispatch(); - const { t } = useTranslation(); - - const onChangeEnabled = (value: boolean) => { - dispatch(RootActions.setAhkEnabled(value)); - dispatch(RootActions.setToBeSaved(true)); - }; - - const onChangeVar = (name: string, e: React.KeyboardEvent) => { - const result = KeyCodeToAHK(e); - if (result) { - dispatch(AhkVariablesActions.setVariable({ name, value: result })); - } - }; - - return ( -
- - - - {t('shortcuts.enable')}{' '} - - 🛈 - - - - - - - - { - Object.entries(ahkVariables).map(([key, value]) => { - return ( - -
{t(`shortcuts.labels.${VariableConvention.camelToSnake(key)}`)}
- onChangeVar(key, e)} - /> -
- ); - }) - } -
-
- ); -} +import { VariableConvention } from '../../../shared/schemas'; +import { SettingsGroup, SettingsOption } from '../../components/SettingsBox'; +import { Input, Switch, Tooltip } from 'antd'; +import { useTranslation } from 'react-i18next'; +import { useDispatch, useSelector } from 'react-redux'; + +import { RootActions } from '../shared/store/app/reducer'; +import { RootSelectors } from '../shared/store/app/selectors'; +import { AhkVariablesActions, KeyCodeToAHK } from './app'; + +export function Shortcuts() { + const ahkEnable = useSelector(RootSelectors.ahkEnabled); + const ahkVariables = useSelector(RootSelectors.ahkVariables); + + const dispatch = useDispatch(); + const { t } = useTranslation(); + + const onChangeEnabled = (value: boolean) => { + dispatch(RootActions.setAhkEnabled(value)); + dispatch(RootActions.setToBeSaved(true)); + }; + + const onChangeVar = (name: string, e: React.KeyboardEvent) => { + const result = KeyCodeToAHK(e); + if (result) { + dispatch(AhkVariablesActions.setVariable({ name, value: result })); + } + }; + + return ( +
+ + + + {t('shortcuts.enable')}{' '} + + 🛈 + + + + + + + + { + Object.entries(ahkVariables).map(([key, value]) => { + return ( + +
{t(`shortcuts.labels.${VariableConvention.camelToSnake(key)}`)}
+ onChangeVar(key, e)} + /> +
+ ); + }) + } +
+
+ ); +} diff --git a/src/apps/settings/styles/colors.css b/src/apps/settings/styles/colors.css index ec8ed844..f12ab260 100644 --- a/src/apps/settings/styles/colors.css +++ b/src/apps/settings/styles/colors.css @@ -1,599 +1,599 @@ -:root { - /* Persisted colors variables (not changed on dark mode) */ - --color-persist-white: #ffffff; - --color-persist-gray-50: #fdfdfd; - --color-persist-gray-100: #f8f8f8; - --color-persist-gray-200: #e6e6e6; - --color-persist-gray-300: #d5d5d5; - --color-persist-gray-400: #b1b1b1; - --color-persist-gray-500: #909090; - --color-persist-gray-600: #6d6d6d; - --color-persist-gray-700: #464646; - --color-persist-gray-800: #222222; - --color-persist-gray-900: #151515; - --color-persist-black: #000000; - - --color-persist-blue-100: #e0f2ff; - --color-persist-blue-200: #cae8ff; - --color-persist-blue-300: #b5deff; - --color-persist-blue-400: #96cefd; - --color-persist-blue-500: #78bbfa; - --color-persist-blue-600: #59a7f6; - --color-persist-blue-700: #3892f3; - --color-persist-blue-800: #147af3; - --color-persist-blue-900: #0265dc; - --color-persist-blue-1000: #0054b6; - --color-persist-blue-1100: #004491; - --color-persist-blue-1200: #003571; - --color-persist-blue-1300: #002754; - - --color-persist-green-100: #cef8e0; - --color-persist-green-200: #adf4ce; - --color-persist-green-300: #89ecbc; - --color-persist-green-400: #67dea8; - --color-persist-green-500: #49cc93; - --color-persist-green-600: #2fb880; - --color-persist-green-700: #15a46e; - --color-persist-green-800: #008f5d; - --color-persist-green-900: #007a4d; - --color-persist-green-1000: #00653e; - --color-persist-green-1100: #005132; - --color-persist-green-1200: #053f27; - --color-persist-green-1300: #0a2e1d; - - --color-persist-orange-100: #ffeccc; - --color-persist-orange-200: #ffdfad; - --color-persist-orange-300: #fdd291; - --color-persist-orange-400: #ffbb63; - --color-persist-orange-500: #ffa037; - --color-persist-orange-600: #f68511; - --color-persist-orange-700: #e46f00; - --color-persist-orange-800: #cb5d00; - --color-persist-orange-900: #b14c00; - --color-persist-orange-1000: #953d00; - --color-persist-orange-1100: #7a2f00; - --color-persist-orange-1200: #612300; - --color-persist-orange-1300: #491901; - - --color-persist-red-100: #ffebe7; - --color-persist-red-200: #ffddd6; - --color-persist-red-300: #ffcdc3; - --color-persist-red-400: #ffb7a9; - --color-persist-red-500: #ff9b88; - --color-persist-red-600: #ff7c65; - --color-persist-red-700: #f75c46; - --color-persist-red-800: #ea3829; - --color-persist-red-900: #d31510; - --color-persist-red-1000: #b40000; - --color-persist-red-1100: #930000; - --color-persist-red-1200: #740000; - --color-persist-red-1300: #590000; - - --color-persist-celery-100: #cdfcbf; - --color-persist-celery-200: #aef69d; - --color-persist-celery-300: #96ee85; - --color-persist-celery-400: #72e06a; - --color-persist-celery-500: #4ecf50; - --color-persist-celery-600: #27bb36; - --color-persist-celery-700: #07a721; - --color-persist-celery-800: #009112; - --color-persist-celery-900: #007c0f; - --color-persist-celery-1000: #00670f; - --color-persist-celery-1100: #00530d; - --color-persist-celery-1200: #00400a; - --color-persist-celery-1300: #003007; - - --color-persist-chartreuse-100: #dbfc6e; - --color-persist-chartreuse-200: #cbf443; - --color-persist-chartreuse-300: #bce92a; - --color-persist-chartreuse-400: #aad816; - --color-persist-chartreuse-500: #98c50a; - --color-persist-chartreuse-600: #87b103; - --color-persist-chartreuse-700: #769c00; - --color-persist-chartreuse-800: #678800; - --color-persist-chartreuse-900: #577400; - --color-persist-chartreuse-1000: #486000; - --color-persist-chartreuse-1100: #3a4d00; - --color-persist-chartreuse-1200: #2c3b00; - --color-persist-chartreuse-1300: #212c00; - - --color-persist-cyan-100: #c5f8ff; - --color-persist-cyan-200: #a4f0ff; - --color-persist-cyan-300: #88e7fa; - --color-persist-cyan-400: #60d8f3; - --color-persist-cyan-500: #33c5e8; - --color-persist-cyan-600: #12b0da; - --color-persist-cyan-700: #019cc8; - --color-persist-cyan-800: #0086b4; - --color-persist-cyan-900: #00719f; - --color-persist-cyan-1000: #005d89; - --color-persist-cyan-1100: #004a73; - --color-persist-cyan-1200: #00395d; - --color-persist-cyan-1300: #002a46; - - --color-persist-fuchsia-100: #ffe9fc; - --color-persist-fuchsia-200: #ffdafa; - --color-persist-fuchsia-300: #fec7f8; - --color-persist-fuchsia-400: #fbaef6; - --color-persist-fuchsia-500: #f592f3; - --color-persist-fuchsia-600: #ed74ed; - --color-persist-fuchsia-700: #e055e2; - --color-persist-fuchsia-800: #cd3ace; - --color-persist-fuchsia-900: #b622b7; - --color-persist-fuchsia-1000: #9d039e; - --color-persist-fuchsia-1100: #800081; - --color-persist-fuchsia-1200: #640664; - --color-persist-fuchsia-1300: #470e46; - - --color-persist-indigo-100: #edeeff; - --color-persist-indigo-200: #e0e2ff; - --color-persist-indigo-300: #d3d5ff; - --color-persist-indigo-400: #c1c4ff; - --color-persist-indigo-500: #acafff; - --color-persist-indigo-600: #9599ff; - --color-persist-indigo-700: #7e84fc; - --color-persist-indigo-800: #686df4; - --color-persist-indigo-900: #5258e4; - --color-persist-indigo-1000: #4046ca; - --color-persist-indigo-1100: #3236a8; - --color-persist-indigo-1200: #262986; - --color-persist-indigo-1300: #1b1e64; - - --color-persist-magenta-100: #ffeaf1; - --color-persist-magenta-200: #ffdce8; - --color-persist-magenta-300: #ffcadd; - --color-persist-magenta-400: #ffb2ce; - --color-persist-magenta-500: #ff95bd; - --color-persist-magenta-600: #fa77aa; - --color-persist-magenta-700: #ef5a98; - --color-persist-magenta-800: #de3d82; - --color-persist-magenta-900: #c82269; - --color-persist-magenta-1000: #ad0955; - --color-persist-magenta-1100: #8e0045; - --color-persist-magenta-1200: #700037; - --color-persist-magenta-1300: #54032a; - - --color-persist-purple-100: #f6ebff; - --color-persist-purple-200: #eeddff; - --color-persist-purple-300: #e6d0ff; - --color-persist-purple-400: #dbbbfe; - --color-persist-purple-500: #cca4fd; - --color-persist-purple-600: #bd8bfc; - --color-persist-purple-700: #ae72f9; - --color-persist-purple-800: #9d57f4; - --color-persist-purple-900: #893de7; - --color-persist-purple-1000: #7326d3; - --color-persist-purple-1100: #5d13b7; - --color-persist-purple-1200: #470c94; - --color-persist-purple-1300: #33106a; - - --color-persist-seafoam-100: #cef7f3; - --color-persist-seafoam-200: #aaf1ea; - --color-persist-seafoam-300: #8ce9e2; - --color-persist-seafoam-400: #65dad2; - --color-persist-seafoam-500: #3fc9c1; - --color-persist-seafoam-600: #0fb5ae; - --color-persist-seafoam-700: #00a19a; - --color-persist-seafoam-800: #008c87; - --color-persist-seafoam-900: #007772; - --color-persist-seafoam-1000: #00635f; - --color-persist-seafoam-1100: #0c4f4c; - --color-persist-seafoam-1200: #123c3a; - --color-persist-seafoam-1300: #122c2b; - - --color-persist-yellow-100: #fbf198; - --color-persist-yellow-200: #f8e750; - --color-persist-yellow-300: #f8d904; - --color-persist-yellow-400: #e8c600; - --color-persist-yellow-500: #d7b300; - --color-persist-yellow-600: #c49f00; - --color-persist-yellow-700: #b08c00; - --color-persist-yellow-800: #9b7800; - --color-persist-yellow-900: #856600; - --color-persist-yellow-1000: #705300; - --color-persist-yellow-1100: #5b4300; - --color-persist-yellow-1200: #483300; - --color-persist-yellow-1300: #362500; -} - -@media (prefers-color-scheme: dark) { - :root { - --color-white: #000000; - - --color-gray-50: #151515; - --color-gray-100: #222222; - --color-gray-200: #464646; - --color-gray-300: #6d6d6d; - --color-gray-400: #909090; - --color-gray-500: #b1b1b1; - --color-gray-600: #d5d5d5; - --color-gray-700: #e6e6e6; - --color-gray-800: #f8f8f8; - --color-gray-900: #fdfdfd; - - --color-black: #ffffff; - - --color-blue-100: #003877; - --color-blue-200: #00418a; - --color-blue-300: #004da3; - --color-blue-400: #0059c2; - --color-blue-500: #0367e0; - --color-blue-600: #1379f3; - --color-blue-700: #348ff4; - --color-blue-800: #54a3f6; - --color-blue-900: #72b7f9; - --color-blue-1000: #8fcafc; - --color-blue-1100: #aedbfe; - --color-blue-1200: #cce9ff; - --color-blue-1300: #e8f6ff; - - --color-green-100: #044329; - --color-green-200: #004e2f; - --color-green-300: #005c38; - --color-green-400: #006c43; - --color-green-500: #007d4e; - --color-green-600: #008f5d; - --color-green-700: #12a26c; - --color-green-800: #2bb47d; - --color-green-900: #43c78f; - --color-green-1000: #5ed9a2; - --color-green-1100: #81e9b8; - --color-green-1200: #b1f4d1; - --color-green-1300: #dffaea; - - --color-orange-100: #662500; - --color-orange-200: #752d00; - --color-orange-300: #893700; - --color-orange-400: #9e4200; - --color-orange-500: #b44e00; - --color-orange-600: #ca5d00; - --color-orange-700: #e16d00; - --color-orange-800: #f4810c; - --color-orange-900: #fe9a2e; - --color-orange-1000: #ffb558; - --color-orange-1100: #fdce88; - --color-orange-1200: #ffe1b3; - --color-orange-1300: #fff2dd; - - --color-red-100: #7b0000; - --color-red-200: #8d0000; - --color-red-300: #a50000; - --color-red-400: #be0403; - --color-red-500: #d71913; - --color-red-600: #ea3829; - --color-red-700: #f65843; - --color-red-800: #ff755e; - --color-red-900: #ff9581; - --color-red-1000: #ffb0a1; - --color-red-1100: #ffc9bd; - --color-red-1200: #ffded8; - --color-red-1300: #fff1ee; - - --color-celery-100: #00450a; - --color-celery-200: #00500c; - --color-celery-300: #005e0e; - --color-celery-400: #006d0f; - --color-celery-500: #007f0f; - --color-celery-600: #009112; - --color-celery-700: #04a51e; - --color-celery-800: #22b833; - --color-celery-900: #44ca49; - --color-celery-1000: #69dc63; - --color-celery-1100: #8eeb7f; - --color-celery-1200: #b4f7a2; - --color-celery-1300: #ddfdd3; - - --color-chartreuse-100: #304000; - --color-chartreuse-200: #374a00; - --color-chartreuse-300: #415700; - --color-chartreuse-400: #4c6600; - --color-chartreuse-500: #597600; - --color-chartreuse-600: #668800; - --color-chartreuse-700: #759a00; - --color-chartreuse-800: #84ad01; - --color-chartreuse-900: #94c008; - --color-chartreuse-1000: #a6d312; - --color-chartreuse-1100: #b8e525; - --color-chartreuse-1200: #cdf547; - --color-chartreuse-1300: #e7fe9a; - - --color-cyan-100: #003d62; - --color-cyan-200: #00476f; - --color-cyan-300: #00557f; - --color-cyan-400: #006491; - --color-cyan-500: #0074a2; - --color-cyan-600: #0086b4; - --color-cyan-700: #0099c6; - --color-cyan-800: #0eadd7; - --color-cyan-900: #2cc1e6; - --color-cyan-1000: #54d3f1; - --color-cyan-1100: #7fe4f9; - --color-cyan-1200: #a7f1ff; - --color-cyan-1300: #d7faff; - - --color-fuchsia-100: #6b036a; - --color-fuchsia-200: #7b007b; - --color-fuchsia-300: #900091; - --color-fuchsia-400: #a50da6; - --color-fuchsia-500: #b925b9; - --color-fuchsia-600: #cd39ce; - --color-fuchsia-700: #df51e0; - --color-fuchsia-800: #eb6eec; - --color-fuchsia-900: #f48cf2; - --color-fuchsia-1000: #faa8f5; - --color-fuchsia-1100: #fec2f8; - --color-fuchsia-1200: #ffdbfa; - --color-fuchsia-1300: #ffeffc; - - --color-indigo-100: #282c8c; - --color-indigo-200: #2f34a3; - --color-indigo-300: #393fbb; - --color-indigo-400: #464bd3; - --color-indigo-500: #555be7; - --color-indigo-600: #686df4; - --color-indigo-700: #7c81fb; - --color-indigo-800: #9195ff; - --color-indigo-900: #a7aaff; - --color-indigo-1000: #bcbeff; - --color-indigo-1100: #d0d2ff; - --color-indigo-1200: #e2e4ff; - --color-indigo-1300: #f3f3fe; - - --color-magenta-100: #76003a; - --color-magenta-200: #890042; - --color-magenta-300: #a0004d; - --color-magenta-400: #b6125a; - --color-magenta-500: #cb266d; - --color-magenta-600: #de3d82; - --color-magenta-700: #ed5795; - --color-magenta-800: #f972a7; - --color-magenta-900: #ff8fb9; - --color-magenta-1000: #ffacca; - --color-magenta-1100: #ffc6da; - --color-magenta-1200: #ffdde9; - --color-magenta-1300: #fff0f5; - - --color-purple-100: #4c0d9d; - --color-purple-200: #5911b1; - --color-purple-300: #691cc8; - --color-purple-400: #7a2dda; - --color-purple-500: #8c41e9; - --color-purple-600: #9d57f3; - --color-purple-700: #ac6ff9; - --color-purple-800: #bb87fb; - --color-purple-900: #ca9ffc; - --color-purple-1000: #d7b6fe; - --color-purple-1100: #e4ccfe; - --color-purple-1200: #efdfff; - --color-purple-1300: #f9f0ff; - - --color-seafoam-100: #12413f; - --color-seafoam-200: #0e4c49; - --color-seafoam-300: #045a57; - --color-seafoam-400: #006965; - --color-seafoam-500: #007a75; - --color-seafoam-600: #008c87; - --color-seafoam-700: #009e98; - --color-seafoam-800: #03b2ab; - --color-seafoam-900: #36c5bd; - --color-seafoam-1000: #5dd6cf; - --color-seafoam-1100: #84e6df; - --color-seafoam-1200: #b0f2ec; - --color-seafoam-1300: #dff9f6; - - --color-yellow-100: #4c3600; - --color-yellow-200: #584000; - --color-yellow-300: #674c00; - --color-yellow-400: #775900; - --color-yellow-500: #886800; - --color-yellow-600: #9b7800; - --color-yellow-700: #ae8900; - --color-yellow-800: #c09c00; - --color-yellow-900: #d3ae00; - --color-yellow-1000: #e4c200; - --color-yellow-1100: #f4d500; - --color-yellow-1200: #f9e85c; - --color-yellow-1300: #fcf6bb; - } -} - -@media (prefers-color-scheme: light) { - :root { - --color-white: #ffffff; - - --color-gray-50: #fdfdfd; - --color-gray-100: #f8f8f8; - --color-gray-200: #e6e6e6; - --color-gray-300: #d5d5d5; - --color-gray-400: #b1b1b1; - --color-gray-500: #909090; - --color-gray-600: #6d6d6d; - --color-gray-700: #464646; - --color-gray-800: #222222; - --color-gray-900: #151515; - - --color-black: #000000; - - --color-blue-100: #e0f2ff; - --color-blue-200: #cae8ff; - --color-blue-300: #b5deff; - --color-blue-400: #96cefd; - --color-blue-500: #78bbfa; - --color-blue-600: #59a7f6; - --color-blue-700: #3892f3; - --color-blue-800: #147af3; - --color-blue-900: #0265dc; - --color-blue-1000: #0054b6; - --color-blue-1100: #004491; - --color-blue-1200: #003571; - --color-blue-1300: #002754; - - --color-green-100: #cef8e0; - --color-green-200: #adf4ce; - --color-green-300: #89ecbc; - --color-green-400: #67dea8; - --color-green-500: #49cc93; - --color-green-600: #2fb880; - --color-green-700: #15a46e; - --color-green-800: #008f5d; - --color-green-900: #007a4d; - --color-green-1000: #00653e; - --color-green-1100: #005132; - --color-green-1200: #053f27; - --color-green-1300: #0a2e1d; - - --color-orange-100: #ffeccc; - --color-orange-200: #ffdfad; - --color-orange-300: #fdd291; - --color-orange-400: #ffbb63; - --color-orange-500: #ffa037; - --color-orange-600: #f68511; - --color-orange-700: #e46f00; - --color-orange-800: #cb5d00; - --color-orange-900: #b14c00; - --color-orange-1000: #953d00; - --color-orange-1100: #7a2f00; - --color-orange-1200: #612300; - --color-orange-1300: #491901; - - --color-red-100: #ffebe7; - --color-red-200: #ffddd6; - --color-red-300: #ffcdc3; - --color-red-400: #ffb7a9; - --color-red-500: #ff9b88; - --color-red-600: #ff7c65; - --color-red-700: #f75c46; - --color-red-800: #ea3829; - --color-red-900: #d31510; - --color-red-1000: #b40000; - --color-red-1100: #930000; - --color-red-1200: #740000; - --color-red-1300: #590000; - - --color-celery-100: #cdfcbf; - --color-celery-200: #aef69d; - --color-celery-300: #96ee85; - --color-celery-400: #72e06a; - --color-celery-500: #4ecf50; - --color-celery-600: #27bb36; - --color-celery-700: #07a721; - --color-celery-800: #009112; - --color-celery-900: #007c0f; - --color-celery-1000: #00670f; - --color-celery-1100: #00530d; - --color-celery-1200: #00400a; - --color-celery-1300: #003007; - - --color-chartreuse-100: #dbfc6e; - --color-chartreuse-200: #cbf443; - --color-chartreuse-300: #bce92a; - --color-chartreuse-400: #aad816; - --color-chartreuse-500: #98c50a; - --color-chartreuse-600: #87b103; - --color-chartreuse-700: #769c00; - --color-chartreuse-800: #678800; - --color-chartreuse-900: #577400; - --color-chartreuse-1000: #486000; - --color-chartreuse-1100: #3a4d00; - --color-chartreuse-1200: #2c3b00; - --color-chartreuse-1300: #212c00; - - --color-cyan-100: #c5f8ff; - --color-cyan-200: #a4f0ff; - --color-cyan-300: #88e7fa; - --color-cyan-400: #60d8f3; - --color-cyan-500: #33c5e8; - --color-cyan-600: #12b0da; - --color-cyan-700: #019cc8; - --color-cyan-800: #0086b4; - --color-cyan-900: #00719f; - --color-cyan-1000: #005d89; - --color-cyan-1100: #004a73; - --color-cyan-1200: #00395d; - --color-cyan-1300: #002a46; - - --color-fuchsia-100: #ffe9fc; - --color-fuchsia-200: #ffdafa; - --color-fuchsia-300: #fec7f8; - --color-fuchsia-400: #fbaef6; - --color-fuchsia-500: #f592f3; - --color-fuchsia-600: #ed74ed; - --color-fuchsia-700: #e055e2; - --color-fuchsia-800: #cd3ace; - --color-fuchsia-900: #b622b7; - --color-fuchsia-1000: #9d039e; - --color-fuchsia-1100: #800081; - --color-fuchsia-1200: #640664; - --color-fuchsia-1300: #470e46; - - --color-indigo-100: #edeeff; - --color-indigo-200: #e0e2ff; - --color-indigo-300: #d3d5ff; - --color-indigo-400: #c1c4ff; - --color-indigo-500: #acafff; - --color-indigo-600: #9599ff; - --color-indigo-700: #7e84fc; - --color-indigo-800: #686df4; - --color-indigo-900: #5258e4; - --color-indigo-1000: #4046ca; - --color-indigo-1100: #3236a8; - --color-indigo-1200: #262986; - --color-indigo-1300: #1b1e64; - - --color-magenta-100: #ffeaf1; - --color-magenta-200: #ffdce8; - --color-magenta-300: #ffcadd; - --color-magenta-400: #ffb2ce; - --color-magenta-500: #ff95bd; - --color-magenta-600: #fa77aa; - --color-magenta-700: #ef5a98; - --color-magenta-800: #de3d82; - --color-magenta-900: #c82269; - --color-magenta-1000: #ad0955; - --color-magenta-1100: #8e0045; - --color-magenta-1200: #700037; - --color-magenta-1300: #54032a; - - --color-purple-100: #f6ebff; - --color-purple-200: #eeddff; - --color-purple-300: #e6d0ff; - --color-purple-400: #dbbbfe; - --color-purple-500: #cca4fd; - --color-purple-600: #bd8bfc; - --color-purple-700: #ae72f9; - --color-purple-800: #9d57f4; - --color-purple-900: #893de7; - --color-purple-1000: #7326d3; - --color-purple-1100: #5d13b7; - --color-purple-1200: #470c94; - --color-purple-1300: #33106a; - - --color-seafoam-100: #cef7f3; - --color-seafoam-200: #aaf1ea; - --color-seafoam-300: #8ce9e2; - --color-seafoam-400: #65dad2; - --color-seafoam-500: #3fc9c1; - --color-seafoam-600: #0fb5ae; - --color-seafoam-700: #00a19a; - --color-seafoam-800: #008c87; - --color-seafoam-900: #007772; - --color-seafoam-1000: #00635f; - --color-seafoam-1100: #0c4f4c; - --color-seafoam-1200: #123c3a; - --color-seafoam-1300: #122c2b; - - --color-yellow-100: #fbf198; - --color-yellow-200: #f8e750; - --color-yellow-300: #f8d904; - --color-yellow-400: #e8c600; - --color-yellow-500: #d7b300; - --color-yellow-600: #c49f00; - --color-yellow-700: #b08c00; - --color-yellow-800: #9b7800; - --color-yellow-900: #856600; - --color-yellow-1000: #705300; - --color-yellow-1100: #5b4300; - --color-yellow-1200: #483300; - --color-yellow-1300: #362500; - } -} +:root { + /* Persisted colors variables (not changed on dark mode) */ + --color-persist-white: #ffffff; + --color-persist-gray-50: #fdfdfd; + --color-persist-gray-100: #f8f8f8; + --color-persist-gray-200: #e6e6e6; + --color-persist-gray-300: #d5d5d5; + --color-persist-gray-400: #b1b1b1; + --color-persist-gray-500: #909090; + --color-persist-gray-600: #6d6d6d; + --color-persist-gray-700: #464646; + --color-persist-gray-800: #222222; + --color-persist-gray-900: #151515; + --color-persist-black: #000000; + + --color-persist-blue-100: #e0f2ff; + --color-persist-blue-200: #cae8ff; + --color-persist-blue-300: #b5deff; + --color-persist-blue-400: #96cefd; + --color-persist-blue-500: #78bbfa; + --color-persist-blue-600: #59a7f6; + --color-persist-blue-700: #3892f3; + --color-persist-blue-800: #147af3; + --color-persist-blue-900: #0265dc; + --color-persist-blue-1000: #0054b6; + --color-persist-blue-1100: #004491; + --color-persist-blue-1200: #003571; + --color-persist-blue-1300: #002754; + + --color-persist-green-100: #cef8e0; + --color-persist-green-200: #adf4ce; + --color-persist-green-300: #89ecbc; + --color-persist-green-400: #67dea8; + --color-persist-green-500: #49cc93; + --color-persist-green-600: #2fb880; + --color-persist-green-700: #15a46e; + --color-persist-green-800: #008f5d; + --color-persist-green-900: #007a4d; + --color-persist-green-1000: #00653e; + --color-persist-green-1100: #005132; + --color-persist-green-1200: #053f27; + --color-persist-green-1300: #0a2e1d; + + --color-persist-orange-100: #ffeccc; + --color-persist-orange-200: #ffdfad; + --color-persist-orange-300: #fdd291; + --color-persist-orange-400: #ffbb63; + --color-persist-orange-500: #ffa037; + --color-persist-orange-600: #f68511; + --color-persist-orange-700: #e46f00; + --color-persist-orange-800: #cb5d00; + --color-persist-orange-900: #b14c00; + --color-persist-orange-1000: #953d00; + --color-persist-orange-1100: #7a2f00; + --color-persist-orange-1200: #612300; + --color-persist-orange-1300: #491901; + + --color-persist-red-100: #ffebe7; + --color-persist-red-200: #ffddd6; + --color-persist-red-300: #ffcdc3; + --color-persist-red-400: #ffb7a9; + --color-persist-red-500: #ff9b88; + --color-persist-red-600: #ff7c65; + --color-persist-red-700: #f75c46; + --color-persist-red-800: #ea3829; + --color-persist-red-900: #d31510; + --color-persist-red-1000: #b40000; + --color-persist-red-1100: #930000; + --color-persist-red-1200: #740000; + --color-persist-red-1300: #590000; + + --color-persist-celery-100: #cdfcbf; + --color-persist-celery-200: #aef69d; + --color-persist-celery-300: #96ee85; + --color-persist-celery-400: #72e06a; + --color-persist-celery-500: #4ecf50; + --color-persist-celery-600: #27bb36; + --color-persist-celery-700: #07a721; + --color-persist-celery-800: #009112; + --color-persist-celery-900: #007c0f; + --color-persist-celery-1000: #00670f; + --color-persist-celery-1100: #00530d; + --color-persist-celery-1200: #00400a; + --color-persist-celery-1300: #003007; + + --color-persist-chartreuse-100: #dbfc6e; + --color-persist-chartreuse-200: #cbf443; + --color-persist-chartreuse-300: #bce92a; + --color-persist-chartreuse-400: #aad816; + --color-persist-chartreuse-500: #98c50a; + --color-persist-chartreuse-600: #87b103; + --color-persist-chartreuse-700: #769c00; + --color-persist-chartreuse-800: #678800; + --color-persist-chartreuse-900: #577400; + --color-persist-chartreuse-1000: #486000; + --color-persist-chartreuse-1100: #3a4d00; + --color-persist-chartreuse-1200: #2c3b00; + --color-persist-chartreuse-1300: #212c00; + + --color-persist-cyan-100: #c5f8ff; + --color-persist-cyan-200: #a4f0ff; + --color-persist-cyan-300: #88e7fa; + --color-persist-cyan-400: #60d8f3; + --color-persist-cyan-500: #33c5e8; + --color-persist-cyan-600: #12b0da; + --color-persist-cyan-700: #019cc8; + --color-persist-cyan-800: #0086b4; + --color-persist-cyan-900: #00719f; + --color-persist-cyan-1000: #005d89; + --color-persist-cyan-1100: #004a73; + --color-persist-cyan-1200: #00395d; + --color-persist-cyan-1300: #002a46; + + --color-persist-fuchsia-100: #ffe9fc; + --color-persist-fuchsia-200: #ffdafa; + --color-persist-fuchsia-300: #fec7f8; + --color-persist-fuchsia-400: #fbaef6; + --color-persist-fuchsia-500: #f592f3; + --color-persist-fuchsia-600: #ed74ed; + --color-persist-fuchsia-700: #e055e2; + --color-persist-fuchsia-800: #cd3ace; + --color-persist-fuchsia-900: #b622b7; + --color-persist-fuchsia-1000: #9d039e; + --color-persist-fuchsia-1100: #800081; + --color-persist-fuchsia-1200: #640664; + --color-persist-fuchsia-1300: #470e46; + + --color-persist-indigo-100: #edeeff; + --color-persist-indigo-200: #e0e2ff; + --color-persist-indigo-300: #d3d5ff; + --color-persist-indigo-400: #c1c4ff; + --color-persist-indigo-500: #acafff; + --color-persist-indigo-600: #9599ff; + --color-persist-indigo-700: #7e84fc; + --color-persist-indigo-800: #686df4; + --color-persist-indigo-900: #5258e4; + --color-persist-indigo-1000: #4046ca; + --color-persist-indigo-1100: #3236a8; + --color-persist-indigo-1200: #262986; + --color-persist-indigo-1300: #1b1e64; + + --color-persist-magenta-100: #ffeaf1; + --color-persist-magenta-200: #ffdce8; + --color-persist-magenta-300: #ffcadd; + --color-persist-magenta-400: #ffb2ce; + --color-persist-magenta-500: #ff95bd; + --color-persist-magenta-600: #fa77aa; + --color-persist-magenta-700: #ef5a98; + --color-persist-magenta-800: #de3d82; + --color-persist-magenta-900: #c82269; + --color-persist-magenta-1000: #ad0955; + --color-persist-magenta-1100: #8e0045; + --color-persist-magenta-1200: #700037; + --color-persist-magenta-1300: #54032a; + + --color-persist-purple-100: #f6ebff; + --color-persist-purple-200: #eeddff; + --color-persist-purple-300: #e6d0ff; + --color-persist-purple-400: #dbbbfe; + --color-persist-purple-500: #cca4fd; + --color-persist-purple-600: #bd8bfc; + --color-persist-purple-700: #ae72f9; + --color-persist-purple-800: #9d57f4; + --color-persist-purple-900: #893de7; + --color-persist-purple-1000: #7326d3; + --color-persist-purple-1100: #5d13b7; + --color-persist-purple-1200: #470c94; + --color-persist-purple-1300: #33106a; + + --color-persist-seafoam-100: #cef7f3; + --color-persist-seafoam-200: #aaf1ea; + --color-persist-seafoam-300: #8ce9e2; + --color-persist-seafoam-400: #65dad2; + --color-persist-seafoam-500: #3fc9c1; + --color-persist-seafoam-600: #0fb5ae; + --color-persist-seafoam-700: #00a19a; + --color-persist-seafoam-800: #008c87; + --color-persist-seafoam-900: #007772; + --color-persist-seafoam-1000: #00635f; + --color-persist-seafoam-1100: #0c4f4c; + --color-persist-seafoam-1200: #123c3a; + --color-persist-seafoam-1300: #122c2b; + + --color-persist-yellow-100: #fbf198; + --color-persist-yellow-200: #f8e750; + --color-persist-yellow-300: #f8d904; + --color-persist-yellow-400: #e8c600; + --color-persist-yellow-500: #d7b300; + --color-persist-yellow-600: #c49f00; + --color-persist-yellow-700: #b08c00; + --color-persist-yellow-800: #9b7800; + --color-persist-yellow-900: #856600; + --color-persist-yellow-1000: #705300; + --color-persist-yellow-1100: #5b4300; + --color-persist-yellow-1200: #483300; + --color-persist-yellow-1300: #362500; +} + +@media (prefers-color-scheme: dark) { + :root { + --color-white: #000000; + + --color-gray-50: #151515; + --color-gray-100: #222222; + --color-gray-200: #464646; + --color-gray-300: #6d6d6d; + --color-gray-400: #909090; + --color-gray-500: #b1b1b1; + --color-gray-600: #d5d5d5; + --color-gray-700: #e6e6e6; + --color-gray-800: #f8f8f8; + --color-gray-900: #fdfdfd; + + --color-black: #ffffff; + + --color-blue-100: #003877; + --color-blue-200: #00418a; + --color-blue-300: #004da3; + --color-blue-400: #0059c2; + --color-blue-500: #0367e0; + --color-blue-600: #1379f3; + --color-blue-700: #348ff4; + --color-blue-800: #54a3f6; + --color-blue-900: #72b7f9; + --color-blue-1000: #8fcafc; + --color-blue-1100: #aedbfe; + --color-blue-1200: #cce9ff; + --color-blue-1300: #e8f6ff; + + --color-green-100: #044329; + --color-green-200: #004e2f; + --color-green-300: #005c38; + --color-green-400: #006c43; + --color-green-500: #007d4e; + --color-green-600: #008f5d; + --color-green-700: #12a26c; + --color-green-800: #2bb47d; + --color-green-900: #43c78f; + --color-green-1000: #5ed9a2; + --color-green-1100: #81e9b8; + --color-green-1200: #b1f4d1; + --color-green-1300: #dffaea; + + --color-orange-100: #662500; + --color-orange-200: #752d00; + --color-orange-300: #893700; + --color-orange-400: #9e4200; + --color-orange-500: #b44e00; + --color-orange-600: #ca5d00; + --color-orange-700: #e16d00; + --color-orange-800: #f4810c; + --color-orange-900: #fe9a2e; + --color-orange-1000: #ffb558; + --color-orange-1100: #fdce88; + --color-orange-1200: #ffe1b3; + --color-orange-1300: #fff2dd; + + --color-red-100: #7b0000; + --color-red-200: #8d0000; + --color-red-300: #a50000; + --color-red-400: #be0403; + --color-red-500: #d71913; + --color-red-600: #ea3829; + --color-red-700: #f65843; + --color-red-800: #ff755e; + --color-red-900: #ff9581; + --color-red-1000: #ffb0a1; + --color-red-1100: #ffc9bd; + --color-red-1200: #ffded8; + --color-red-1300: #fff1ee; + + --color-celery-100: #00450a; + --color-celery-200: #00500c; + --color-celery-300: #005e0e; + --color-celery-400: #006d0f; + --color-celery-500: #007f0f; + --color-celery-600: #009112; + --color-celery-700: #04a51e; + --color-celery-800: #22b833; + --color-celery-900: #44ca49; + --color-celery-1000: #69dc63; + --color-celery-1100: #8eeb7f; + --color-celery-1200: #b4f7a2; + --color-celery-1300: #ddfdd3; + + --color-chartreuse-100: #304000; + --color-chartreuse-200: #374a00; + --color-chartreuse-300: #415700; + --color-chartreuse-400: #4c6600; + --color-chartreuse-500: #597600; + --color-chartreuse-600: #668800; + --color-chartreuse-700: #759a00; + --color-chartreuse-800: #84ad01; + --color-chartreuse-900: #94c008; + --color-chartreuse-1000: #a6d312; + --color-chartreuse-1100: #b8e525; + --color-chartreuse-1200: #cdf547; + --color-chartreuse-1300: #e7fe9a; + + --color-cyan-100: #003d62; + --color-cyan-200: #00476f; + --color-cyan-300: #00557f; + --color-cyan-400: #006491; + --color-cyan-500: #0074a2; + --color-cyan-600: #0086b4; + --color-cyan-700: #0099c6; + --color-cyan-800: #0eadd7; + --color-cyan-900: #2cc1e6; + --color-cyan-1000: #54d3f1; + --color-cyan-1100: #7fe4f9; + --color-cyan-1200: #a7f1ff; + --color-cyan-1300: #d7faff; + + --color-fuchsia-100: #6b036a; + --color-fuchsia-200: #7b007b; + --color-fuchsia-300: #900091; + --color-fuchsia-400: #a50da6; + --color-fuchsia-500: #b925b9; + --color-fuchsia-600: #cd39ce; + --color-fuchsia-700: #df51e0; + --color-fuchsia-800: #eb6eec; + --color-fuchsia-900: #f48cf2; + --color-fuchsia-1000: #faa8f5; + --color-fuchsia-1100: #fec2f8; + --color-fuchsia-1200: #ffdbfa; + --color-fuchsia-1300: #ffeffc; + + --color-indigo-100: #282c8c; + --color-indigo-200: #2f34a3; + --color-indigo-300: #393fbb; + --color-indigo-400: #464bd3; + --color-indigo-500: #555be7; + --color-indigo-600: #686df4; + --color-indigo-700: #7c81fb; + --color-indigo-800: #9195ff; + --color-indigo-900: #a7aaff; + --color-indigo-1000: #bcbeff; + --color-indigo-1100: #d0d2ff; + --color-indigo-1200: #e2e4ff; + --color-indigo-1300: #f3f3fe; + + --color-magenta-100: #76003a; + --color-magenta-200: #890042; + --color-magenta-300: #a0004d; + --color-magenta-400: #b6125a; + --color-magenta-500: #cb266d; + --color-magenta-600: #de3d82; + --color-magenta-700: #ed5795; + --color-magenta-800: #f972a7; + --color-magenta-900: #ff8fb9; + --color-magenta-1000: #ffacca; + --color-magenta-1100: #ffc6da; + --color-magenta-1200: #ffdde9; + --color-magenta-1300: #fff0f5; + + --color-purple-100: #4c0d9d; + --color-purple-200: #5911b1; + --color-purple-300: #691cc8; + --color-purple-400: #7a2dda; + --color-purple-500: #8c41e9; + --color-purple-600: #9d57f3; + --color-purple-700: #ac6ff9; + --color-purple-800: #bb87fb; + --color-purple-900: #ca9ffc; + --color-purple-1000: #d7b6fe; + --color-purple-1100: #e4ccfe; + --color-purple-1200: #efdfff; + --color-purple-1300: #f9f0ff; + + --color-seafoam-100: #12413f; + --color-seafoam-200: #0e4c49; + --color-seafoam-300: #045a57; + --color-seafoam-400: #006965; + --color-seafoam-500: #007a75; + --color-seafoam-600: #008c87; + --color-seafoam-700: #009e98; + --color-seafoam-800: #03b2ab; + --color-seafoam-900: #36c5bd; + --color-seafoam-1000: #5dd6cf; + --color-seafoam-1100: #84e6df; + --color-seafoam-1200: #b0f2ec; + --color-seafoam-1300: #dff9f6; + + --color-yellow-100: #4c3600; + --color-yellow-200: #584000; + --color-yellow-300: #674c00; + --color-yellow-400: #775900; + --color-yellow-500: #886800; + --color-yellow-600: #9b7800; + --color-yellow-700: #ae8900; + --color-yellow-800: #c09c00; + --color-yellow-900: #d3ae00; + --color-yellow-1000: #e4c200; + --color-yellow-1100: #f4d500; + --color-yellow-1200: #f9e85c; + --color-yellow-1300: #fcf6bb; + } +} + +@media (prefers-color-scheme: light) { + :root { + --color-white: #ffffff; + + --color-gray-50: #fdfdfd; + --color-gray-100: #f8f8f8; + --color-gray-200: #e6e6e6; + --color-gray-300: #d5d5d5; + --color-gray-400: #b1b1b1; + --color-gray-500: #909090; + --color-gray-600: #6d6d6d; + --color-gray-700: #464646; + --color-gray-800: #222222; + --color-gray-900: #151515; + + --color-black: #000000; + + --color-blue-100: #e0f2ff; + --color-blue-200: #cae8ff; + --color-blue-300: #b5deff; + --color-blue-400: #96cefd; + --color-blue-500: #78bbfa; + --color-blue-600: #59a7f6; + --color-blue-700: #3892f3; + --color-blue-800: #147af3; + --color-blue-900: #0265dc; + --color-blue-1000: #0054b6; + --color-blue-1100: #004491; + --color-blue-1200: #003571; + --color-blue-1300: #002754; + + --color-green-100: #cef8e0; + --color-green-200: #adf4ce; + --color-green-300: #89ecbc; + --color-green-400: #67dea8; + --color-green-500: #49cc93; + --color-green-600: #2fb880; + --color-green-700: #15a46e; + --color-green-800: #008f5d; + --color-green-900: #007a4d; + --color-green-1000: #00653e; + --color-green-1100: #005132; + --color-green-1200: #053f27; + --color-green-1300: #0a2e1d; + + --color-orange-100: #ffeccc; + --color-orange-200: #ffdfad; + --color-orange-300: #fdd291; + --color-orange-400: #ffbb63; + --color-orange-500: #ffa037; + --color-orange-600: #f68511; + --color-orange-700: #e46f00; + --color-orange-800: #cb5d00; + --color-orange-900: #b14c00; + --color-orange-1000: #953d00; + --color-orange-1100: #7a2f00; + --color-orange-1200: #612300; + --color-orange-1300: #491901; + + --color-red-100: #ffebe7; + --color-red-200: #ffddd6; + --color-red-300: #ffcdc3; + --color-red-400: #ffb7a9; + --color-red-500: #ff9b88; + --color-red-600: #ff7c65; + --color-red-700: #f75c46; + --color-red-800: #ea3829; + --color-red-900: #d31510; + --color-red-1000: #b40000; + --color-red-1100: #930000; + --color-red-1200: #740000; + --color-red-1300: #590000; + + --color-celery-100: #cdfcbf; + --color-celery-200: #aef69d; + --color-celery-300: #96ee85; + --color-celery-400: #72e06a; + --color-celery-500: #4ecf50; + --color-celery-600: #27bb36; + --color-celery-700: #07a721; + --color-celery-800: #009112; + --color-celery-900: #007c0f; + --color-celery-1000: #00670f; + --color-celery-1100: #00530d; + --color-celery-1200: #00400a; + --color-celery-1300: #003007; + + --color-chartreuse-100: #dbfc6e; + --color-chartreuse-200: #cbf443; + --color-chartreuse-300: #bce92a; + --color-chartreuse-400: #aad816; + --color-chartreuse-500: #98c50a; + --color-chartreuse-600: #87b103; + --color-chartreuse-700: #769c00; + --color-chartreuse-800: #678800; + --color-chartreuse-900: #577400; + --color-chartreuse-1000: #486000; + --color-chartreuse-1100: #3a4d00; + --color-chartreuse-1200: #2c3b00; + --color-chartreuse-1300: #212c00; + + --color-cyan-100: #c5f8ff; + --color-cyan-200: #a4f0ff; + --color-cyan-300: #88e7fa; + --color-cyan-400: #60d8f3; + --color-cyan-500: #33c5e8; + --color-cyan-600: #12b0da; + --color-cyan-700: #019cc8; + --color-cyan-800: #0086b4; + --color-cyan-900: #00719f; + --color-cyan-1000: #005d89; + --color-cyan-1100: #004a73; + --color-cyan-1200: #00395d; + --color-cyan-1300: #002a46; + + --color-fuchsia-100: #ffe9fc; + --color-fuchsia-200: #ffdafa; + --color-fuchsia-300: #fec7f8; + --color-fuchsia-400: #fbaef6; + --color-fuchsia-500: #f592f3; + --color-fuchsia-600: #ed74ed; + --color-fuchsia-700: #e055e2; + --color-fuchsia-800: #cd3ace; + --color-fuchsia-900: #b622b7; + --color-fuchsia-1000: #9d039e; + --color-fuchsia-1100: #800081; + --color-fuchsia-1200: #640664; + --color-fuchsia-1300: #470e46; + + --color-indigo-100: #edeeff; + --color-indigo-200: #e0e2ff; + --color-indigo-300: #d3d5ff; + --color-indigo-400: #c1c4ff; + --color-indigo-500: #acafff; + --color-indigo-600: #9599ff; + --color-indigo-700: #7e84fc; + --color-indigo-800: #686df4; + --color-indigo-900: #5258e4; + --color-indigo-1000: #4046ca; + --color-indigo-1100: #3236a8; + --color-indigo-1200: #262986; + --color-indigo-1300: #1b1e64; + + --color-magenta-100: #ffeaf1; + --color-magenta-200: #ffdce8; + --color-magenta-300: #ffcadd; + --color-magenta-400: #ffb2ce; + --color-magenta-500: #ff95bd; + --color-magenta-600: #fa77aa; + --color-magenta-700: #ef5a98; + --color-magenta-800: #de3d82; + --color-magenta-900: #c82269; + --color-magenta-1000: #ad0955; + --color-magenta-1100: #8e0045; + --color-magenta-1200: #700037; + --color-magenta-1300: #54032a; + + --color-purple-100: #f6ebff; + --color-purple-200: #eeddff; + --color-purple-300: #e6d0ff; + --color-purple-400: #dbbbfe; + --color-purple-500: #cca4fd; + --color-purple-600: #bd8bfc; + --color-purple-700: #ae72f9; + --color-purple-800: #9d57f4; + --color-purple-900: #893de7; + --color-purple-1000: #7326d3; + --color-purple-1100: #5d13b7; + --color-purple-1200: #470c94; + --color-purple-1300: #33106a; + + --color-seafoam-100: #cef7f3; + --color-seafoam-200: #aaf1ea; + --color-seafoam-300: #8ce9e2; + --color-seafoam-400: #65dad2; + --color-seafoam-500: #3fc9c1; + --color-seafoam-600: #0fb5ae; + --color-seafoam-700: #00a19a; + --color-seafoam-800: #008c87; + --color-seafoam-900: #007772; + --color-seafoam-1000: #00635f; + --color-seafoam-1100: #0c4f4c; + --color-seafoam-1200: #123c3a; + --color-seafoam-1300: #122c2b; + + --color-yellow-100: #fbf198; + --color-yellow-200: #f8e750; + --color-yellow-300: #f8d904; + --color-yellow-400: #e8c600; + --color-yellow-500: #d7b300; + --color-yellow-600: #c49f00; + --color-yellow-700: #b08c00; + --color-yellow-800: #9b7800; + --color-yellow-900: #856600; + --color-yellow-1000: #705300; + --color-yellow-1100: #5b4300; + --color-yellow-1200: #483300; + --color-yellow-1300: #362500; + } +} diff --git a/src/apps/settings/styles/global.css b/src/apps/settings/styles/global.css index 62c1524c..5f4d103c 100644 --- a/src/apps/settings/styles/global.css +++ b/src/apps/settings/styles/global.css @@ -1,127 +1,127 @@ -#root { - display: grid; - grid-template-columns: min-content 1fr; - grid-template-rows: 50px 1fr; - height: 100vh; - width: 100vw; -} - -#splashscreen { - will-change: contents; - position: fixed; - z-index: 1000; - width: 100%; - height: 100%; - top: 0; - left: 0; - background-color: var(--color-gray-50); - transition: opacity 300ms linear; - opacity: 1; - - &::before { - position: absolute; - width: 100%; - height: 100%; - content: " "; - background: linear-gradient(217deg, var(--color-red-100), #0000 70%), - linear-gradient(127deg, var(--color-blue-100), #0000 70%), - linear-gradient(336deg, var(--color-cyan-100), #0000 70%); - } - - &.hidden { - display: none; - } - - &.vanish { - opacity: 0; - } - - .splashscreen-content { - position: absolute; - top: 50%; - left: 50%; - display: flex; - align-items: center; - gap: 20px; - transform: translate(-50%, -50%); - - .splashscreen-logo { - width: 100px; - } - - .splashscreen-text { - font-size: 5rem; - line-height: 5rem; - margin-top: -5px; - text-wrap: nowrap; - } - } -} - -body { - overflow: hidden; - cursor: default; - - :not(input):not(textarea), - :not(input):not(textarea)::after, - :not(input):not(textarea)::before { - -webkit-user-select: none; - user-select: none; - } -} - -hr { - margin: 5px 0; -} - -::-webkit-scrollbar { - width: 8px; - height: 8px; -} - -::-webkit-scrollbar-track { - background-color: transparent; -} - -::-webkit-scrollbar-thumb { - background-color: var(--color-gray-500); - border-radius: 6px; -} - -::-webkit-scrollbar-thumb:hover { - background-color: var(--color-gray-600); -} - -b { - font-weight: 600; -} - -.content { - height: 100%; - background: linear-gradient(217deg, var(--color-red-100), rgba(255, 0, 0, 0) 70%), - linear-gradient(127deg, var(--color-blue-100), rgba(0, 0, 255, 0) 70%), - linear-gradient(336deg, var(--color-cyan-100), rgba(0, 255, 0, 0) 70%); - padding: 10px; - overflow: auto; -} - -.ant-select { - min-width: 100px; -} - -.ant-input { - min-width: 90px; -} - -.ant-color-picker-trigger { - min-width: 90px !important; -} - -.ant-modal-body { - max-height: 65vh !important; - overflow-y: auto !important; -} - -.ant-modal-content { - padding: 12px 24px !important; -} +#root { + display: grid; + grid-template-columns: min-content 1fr; + grid-template-rows: 50px 1fr; + height: 100vh; + width: 100vw; +} + +#splashscreen { + will-change: contents; + position: fixed; + z-index: 1000; + width: 100%; + height: 100%; + top: 0; + left: 0; + background-color: var(--color-gray-50); + transition: opacity 300ms linear; + opacity: 1; + + &::before { + position: absolute; + width: 100%; + height: 100%; + content: " "; + background: linear-gradient(217deg, var(--color-red-100), #0000 70%), + linear-gradient(127deg, var(--color-blue-100), #0000 70%), + linear-gradient(336deg, var(--color-cyan-100), #0000 70%); + } + + &.hidden { + display: none; + } + + &.vanish { + opacity: 0; + } + + .splashscreen-content { + position: absolute; + top: 50%; + left: 50%; + display: flex; + align-items: center; + gap: 20px; + transform: translate(-50%, -50%); + + .splashscreen-logo { + width: 100px; + } + + .splashscreen-text { + font-size: 5rem; + line-height: 5rem; + margin-top: -5px; + text-wrap: nowrap; + } + } +} + +body { + overflow: hidden; + cursor: default; + + :not(input):not(textarea), + :not(input):not(textarea)::after, + :not(input):not(textarea)::before { + -webkit-user-select: none; + user-select: none; + } +} + +hr { + margin: 5px 0; +} + +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background-color: transparent; +} + +::-webkit-scrollbar-thumb { + background-color: var(--color-gray-500); + border-radius: 6px; +} + +::-webkit-scrollbar-thumb:hover { + background-color: var(--color-gray-600); +} + +b { + font-weight: 600; +} + +.content { + height: 100%; + background: linear-gradient(217deg, var(--color-red-100), rgba(255, 0, 0, 0) 70%), + linear-gradient(127deg, var(--color-blue-100), rgba(0, 0, 255, 0) 70%), + linear-gradient(336deg, var(--color-cyan-100), rgba(0, 255, 0, 0) 70%); + padding: 10px; + overflow: auto; +} + +.ant-select { + min-width: 100px; +} + +.ant-input { + min-width: 90px; +} + +.ant-color-picker-trigger { + min-width: 90px !important; +} + +.ant-modal-body { + max-height: 65vh !important; + overflow-y: auto !important; +} + +.ant-modal-content { + padding: 12px 24px !important; +} diff --git a/src/apps/settings/styles/reset.css b/src/apps/settings/styles/reset.css index 00912b16..8bba46cd 100644 --- a/src/apps/settings/styles/reset.css +++ b/src/apps/settings/styles/reset.css @@ -1,84 +1,84 @@ -:root { - font-size: 100%; - --main-typo: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; - --primary-color: var(--color-gray-900); - --secondary-color: var(--color-gray-50); -} - -*, *:after, *:before { - margin: 0; - padding: 0; - border: 0; - outline: none; - box-sizing: border-box; - vertical-align: baseline; -} - -img, image, picture, video, iframe, figure { - max-width: 100%; - width: 100%; - display: block; -} - -a { - display: block; -} - -p a { - display: inline; -} - -li { - list-style-type: none; -} - -html { - scroll-behavior: smooth; -} - -h1, h2, h3, h4, h5, h6, p, span, a, strong, blockquote, i, b, em, pre { - font-size: 1em; - font-weight: inherit; - font-style: inherit; - text-decoration: none; - color: inherit; -} - -form, input, textarea, select, button, label { - font-family: inherit; - font-size: inherit; - hyphens: auto; - background-color: transparent; - display: block; - color: inherit; -} - -table, tr, td { - border-collapse: collapse; - border-spacing: 0; -} - -svg { - width: 100%; - display: block; - fill: currentColor; -} - -body { - font-size: 1em; - line-height: 1.4em; - font-family: var(--main-typo); - color: var(--primary-color); - background-color: var(--secondary-color); - hyphens: auto; - font-smooth: always; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -hr { - border: 1px solid; - margin: 1em 0; - opacity: 0.8; - color: var(--color-gray-200); +:root { + font-size: 100%; + --main-typo: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + --primary-color: var(--color-gray-900); + --secondary-color: var(--color-gray-50); +} + +*, *:after, *:before { + margin: 0; + padding: 0; + border: 0; + outline: none; + box-sizing: border-box; + vertical-align: baseline; +} + +img, image, picture, video, iframe, figure { + max-width: 100%; + width: 100%; + display: block; +} + +a { + display: block; +} + +p a { + display: inline; +} + +li { + list-style-type: none; +} + +html { + scroll-behavior: smooth; +} + +h1, h2, h3, h4, h5, h6, p, span, a, strong, blockquote, i, b, em, pre { + font-size: 1em; + font-weight: inherit; + font-style: inherit; + text-decoration: none; + color: inherit; +} + +form, input, textarea, select, button, label { + font-family: inherit; + font-size: inherit; + hyphens: auto; + background-color: transparent; + display: block; + color: inherit; +} + +table, tr, td { + border-collapse: collapse; + border-spacing: 0; +} + +svg { + width: 100%; + display: block; + fill: currentColor; +} + +body { + font-size: 1em; + line-height: 1.4em; + font-family: var(--main-typo); + color: var(--primary-color); + background-color: var(--secondary-color); + hyphens: auto; + font-smooth: always; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +hr { + border: 1px solid; + margin: 1em 0; + opacity: 0.8; + color: var(--color-gray-200); } \ No newline at end of file diff --git a/src/apps/settings/styles/variables.css b/src/apps/settings/styles/variables.css index 05f5a329..3fcdd5a6 100644 --- a/src/apps/settings/styles/variables.css +++ b/src/apps/settings/styles/variables.css @@ -1,13 +1,13 @@ -:root { - /* font variables */ - --placeholder-font-color: var(--color-gray-400); - --error-font-color: var(--color-red-800); - - /* config variables */ - --config-border-radius: 8px; - - /* z indexs */ - --z-header: 1; - --z-docs-menu: 2; - --z-modal: 3; +:root { + /* font variables */ + --placeholder-font-color: var(--color-gray-400); + --error-font-color: var(--color-red-800); + + /* config variables */ + --config-border-radius: 8px; + + /* z indexs */ + --z-header: 1; + --z-docs-menu: 2; + --z-modal: 3; } \ No newline at end of file diff --git a/src/apps/shared/ConsoleWrapper.ts b/src/apps/shared/ConsoleWrapper.ts index f6ada5b5..608ecb9c 100644 --- a/src/apps/shared/ConsoleWrapper.ts +++ b/src/apps/shared/ConsoleWrapper.ts @@ -1,67 +1,67 @@ -import * as Logger from '@tauri-apps/plugin-log'; - -export function wrapConsole() { - const WebConsole = { - info: console.info, - warn: console.warn, - error: console.error, - debug: console.debug, - trace: console.trace, - }; - - const StringifyParams = (params: any[]): string => { - return params.reduce((a, b) => { - if (typeof b === 'string') { - return a + ' ' + b; - } - return a + ' ' + JSON.stringify(b, null, 2); - }, ''); - }; - - window.addEventListener('unhandledrejection', (event) => { - console.error(`Unhandled Rejection - ${event.reason}`); - }); - - console.error = (...params: any[]) => { - WebConsole.error(...params); - Logger.error(StringifyParams(params)); - }; - - console.warn = (...params: any[]) => { - WebConsole.warn(...params); - Logger.warn(StringifyParams(params)); - }; - - console.info = (...params: any[]) => { - WebConsole.info(...params); - Logger.info(StringifyParams(params)); - }; - - console.debug = (...params: any[]) => { - WebConsole.debug(...params); - Logger.debug(StringifyParams(params)); - }; - - console.trace = (...params: any[]) => { - WebConsole.trace(...params); - Logger.trace(StringifyParams(params)); - }; - - disableRefreshAndContextMenu(); -} - -export function disableRefreshAndContextMenu() { - document.addEventListener('keydown', function (event) { - if ( - event.key === 'F5' || - (event.ctrlKey && event.key === 'r') || - (event.metaKey && event.key === 'r') - ) { - event.preventDefault(); - } - }); - - document.addEventListener('contextmenu', function (event) { - event.preventDefault(); - }); -} +import * as Logger from '@tauri-apps/plugin-log'; + +export function wrapConsole() { + const WebConsole = { + info: console.info, + warn: console.warn, + error: console.error, + debug: console.debug, + trace: console.trace, + }; + + const StringifyParams = (params: any[]): string => { + return params.reduce((a, b) => { + if (typeof b === 'string') { + return a + ' ' + b; + } + return a + ' ' + JSON.stringify(b, null, 2); + }, ''); + }; + + window.addEventListener('unhandledrejection', (event) => { + console.error(`Unhandled Rejection - ${event.reason}`); + }); + + console.error = (...params: any[]) => { + WebConsole.error(...params); + Logger.error(StringifyParams(params)); + }; + + console.warn = (...params: any[]) => { + WebConsole.warn(...params); + Logger.warn(StringifyParams(params)); + }; + + console.info = (...params: any[]) => { + WebConsole.info(...params); + Logger.info(StringifyParams(params)); + }; + + console.debug = (...params: any[]) => { + WebConsole.debug(...params); + Logger.debug(StringifyParams(params)); + }; + + console.trace = (...params: any[]) => { + WebConsole.trace(...params); + Logger.trace(StringifyParams(params)); + }; + + disableRefreshAndContextMenu(); +} + +export function disableRefreshAndContextMenu() { + document.addEventListener('keydown', function (event) { + if ( + event.key === 'F5' || + (event.ctrlKey && event.key === 'r') || + (event.metaKey && event.key === 'r') + ) { + event.preventDefault(); + } + }); + + document.addEventListener('contextmenu', function (event) { + event.preventDefault(); + }); +} diff --git a/src/apps/shared/StateBuilder.ts b/src/apps/shared/StateBuilder.ts index 713327be..8eef7e02 100644 --- a/src/apps/shared/StateBuilder.ts +++ b/src/apps/shared/StateBuilder.ts @@ -1,100 +1,100 @@ -import { Action, ActionReducerMapBuilder, CaseReducer, PayloadAction, Slice } from '@reduxjs/toolkit'; -import { cast, isStrictObject, prettify, TupleReduce } from 'readable-types'; - -export type SelectorsFor = { [K in keyof T]: (state: T) => T[K] }; -export type ReducersFor = { - [K in keyof T as `set${Capitalize>}`]: CaseReducer>; -}; - -export const capitalize = (text: string) => { - return text.slice(0, 1).toUpperCase() + text.slice(1); -}; -export const matcher = (slice: Slice) => (action: Action) => action.type.startsWith(slice.name); - -interface $GetState extends $<[acc: Record, current: Slice]> { - return: this[0] & { [x in this[1]['name']]: ReturnType }; -} - -export type SelectorFor2 = $if, { - then: ((state: State) => Current) & { [K in keyof Current]: SelectorFor2 }; - else: (state: State) => Current; -}>; - -export class StateBuilder { - static selectorsFor(state: T): SelectorsFor { - const selectors = {} as SelectorsFor; - for (const key in state) { - selectors[key] = (state: T) => state[key]; - } - return selectors; - } - - static reducersFor(state: T): ReducersFor { - const reducers: any = {}; - for (const key in state) { - reducers[`set${capitalize(key)}`] = (state: T, action: any) => { - state[key] = action.payload; - }; - } - return reducers; - } - - static addSliceAsExtraReducer(slice: Slice, builder: ActionReducerMapBuilder<{ [x in Slice['name']]: any }>) { - builder.addMatcher(matcher(slice), (state, action) => { - state[slice.name] = slice.reducer(state[slice.name], action); - }); - } - - static compositeInitialState>(...slices: [...T]): prettify>; - static compositeInitialState(...slices: Slice[]) { - return slices.reduce((acc, slice) => { - acc[slice.name] = slice.getInitialState(); - return acc; - }, {} as anyObject); - } - - static compositeSelector(obj: T, selfSelector: any = (self: any) => self): SelectorFor2 { - for (const key in obj) { - selfSelector[key] = (state: any) => selfSelector(state)[key]; - - if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) { - selfSelector[key] = StateBuilder.compositeSelector(obj[key], selfSelector[key]); - } - } - return selfSelector; - } - -/* - children: Slices = [] as any; - - constructor(public name: Name) {}; - - appendChild(child: T): StateBuilder { - this.children.push(child); - return this as any; - } - - static addSlicesAsChildren(builder: ActionReducerMapBuilder, slices: Slice[]) { - slices.forEach((slice) => { - builder.addMatcher(matcher(slice), (state, action) => { - state[slice.name] = slice.reducer(state[slice.name], action); - }); - }); - } - - build() { - const slices = this.children; - - const initialState = {}; - - return createSlice({ - name: this.name, - initialState, - reducers: reducersFor(initialState), - selectors: selectorsFor(initialState), - extraReducers(builder) { - StateBuilder.addSlicesAsChildren(builder, slices); - }, - }); - }; */ -} +import { Action, ActionReducerMapBuilder, CaseReducer, PayloadAction, Slice } from '@reduxjs/toolkit'; +import { cast, isStrictObject, prettify, TupleReduce } from 'readable-types'; + +export type SelectorsFor = { [K in keyof T]: (state: T) => T[K] }; +export type ReducersFor = { + [K in keyof T as `set${Capitalize>}`]: CaseReducer>; +}; + +export const capitalize = (text: string) => { + return text.slice(0, 1).toUpperCase() + text.slice(1); +}; +export const matcher = (slice: Slice) => (action: Action) => action.type.startsWith(slice.name); + +interface $GetState extends $<[acc: Record, current: Slice]> { + return: this[0] & { [x in this[1]['name']]: ReturnType }; +} + +export type SelectorFor2 = $if, { + then: ((state: State) => Current) & { [K in keyof Current]: SelectorFor2 }; + else: (state: State) => Current; +}>; + +export class StateBuilder { + static selectorsFor(state: T): SelectorsFor { + const selectors = {} as SelectorsFor; + for (const key in state) { + selectors[key] = (state: T) => state[key]; + } + return selectors; + } + + static reducersFor(state: T): ReducersFor { + const reducers: any = {}; + for (const key in state) { + reducers[`set${capitalize(key)}`] = (state: T, action: any) => { + state[key] = action.payload; + }; + } + return reducers; + } + + static addSliceAsExtraReducer(slice: Slice, builder: ActionReducerMapBuilder<{ [x in Slice['name']]: any }>) { + builder.addMatcher(matcher(slice), (state, action) => { + state[slice.name] = slice.reducer(state[slice.name], action); + }); + } + + static compositeInitialState>(...slices: [...T]): prettify>; + static compositeInitialState(...slices: Slice[]) { + return slices.reduce((acc, slice) => { + acc[slice.name] = slice.getInitialState(); + return acc; + }, {} as anyObject); + } + + static compositeSelector(obj: T, selfSelector: any = (self: any) => self): SelectorFor2 { + for (const key in obj) { + selfSelector[key] = (state: any) => selfSelector(state)[key]; + + if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) { + selfSelector[key] = StateBuilder.compositeSelector(obj[key], selfSelector[key]); + } + } + return selfSelector; + } + +/* + children: Slices = [] as any; + + constructor(public name: Name) {}; + + appendChild(child: T): StateBuilder { + this.children.push(child); + return this as any; + } + + static addSlicesAsChildren(builder: ActionReducerMapBuilder, slices: Slice[]) { + slices.forEach((slice) => { + builder.addMatcher(matcher(slice), (state, action) => { + state[slice.name] = slice.reducer(state[slice.name], action); + }); + }); + } + + build() { + const slices = this.children; + + const initialState = {}; + + return createSlice({ + name: this.name, + initialState, + reducers: reducersFor(initialState), + selectors: selectorsFor(initialState), + extraReducers(builder) { + StateBuilder.addSlicesAsChildren(builder, slices); + }, + }); + }; */ +} diff --git a/src/apps/shared/Timing.ts b/src/apps/shared/Timing.ts index ae600ea9..a85f8ff0 100644 --- a/src/apps/shared/Timing.ts +++ b/src/apps/shared/Timing.ts @@ -1,44 +1,44 @@ -export function throttle( - func: T, - delay: number, -): T { - let lastInvokeTime = 0; - let timeoutId: ReturnType | null = null; - - return function (this: ThisParameterType, ...args: Parameters) { - const now = Date.now(); - - if (now - lastInvokeTime < delay) { - if (timeoutId) { - clearTimeout(timeoutId); - } - - timeoutId = setTimeout(() => { - lastInvokeTime = now; - func.apply(this, args); - }, delay); - } else { - lastInvokeTime = now; - func.apply(this, args); - } - } as T; -} - -export interface TimeoutIdRef { - current: ReturnType | null; -} - -export function debounce any>( - func: T, - delay: number, - timeoutId: TimeoutIdRef = { current: null }, -): (...args: Parameters) => void { - return function debouncedFunction(this: ThisParameterType, ...args: Parameters) { - const context = this; - - clearTimeout(timeoutId.current!); - timeoutId.current = setTimeout(function () { - func.apply(context, args); - }, delay); - }; -} +export function throttle( + func: T, + delay: number, +): T { + let lastInvokeTime = 0; + let timeoutId: ReturnType | null = null; + + return function (this: ThisParameterType, ...args: Parameters) { + const now = Date.now(); + + if (now - lastInvokeTime < delay) { + if (timeoutId) { + clearTimeout(timeoutId); + } + + timeoutId = setTimeout(() => { + lastInvokeTime = now; + func.apply(this, args); + }, delay); + } else { + lastInvokeTime = now; + func.apply(this, args); + } + } as T; +} + +export interface TimeoutIdRef { + current: ReturnType | null; +} + +export function debounce any>( + func: T, + delay: number, + timeoutId: TimeoutIdRef = { current: null }, +): (...args: Parameters) => void { + return function debouncedFunction(this: ThisParameterType, ...args: Parameters) { + const context = this; + + clearTimeout(timeoutId.current!); + timeoutId.current = setTimeout(function () { + func.apply(context, args); + }, delay); + }; +} diff --git a/src/apps/shared/components/Icon/index.module.css b/src/apps/shared/components/Icon/index.module.css index f0265d44..9ad40ef3 100644 --- a/src/apps/shared/components/Icon/index.module.css +++ b/src/apps/shared/components/Icon/index.module.css @@ -1,6 +1,6 @@ -.icon { - > svg { - font-size: 1rem; - vertical-align: middle; - } -} +.icon { + > svg { + font-size: 1rem; + vertical-align: middle; + } +} diff --git a/src/apps/shared/components/Icon/index.tsx b/src/apps/shared/components/Icon/index.tsx index 61ea59d9..4b914941 100644 --- a/src/apps/shared/components/Icon/index.tsx +++ b/src/apps/shared/components/Icon/index.tsx @@ -1,100 +1,100 @@ -import { IconBaseProps } from 'react-icons'; -import * as ai from 'react-icons/ai'; -import * as bi from 'react-icons/bi'; -import * as bs from 'react-icons/bs'; -import * as cg from 'react-icons/cg'; -import * as ci from 'react-icons/ci'; -import * as di from 'react-icons/di'; -import * as fa from 'react-icons/fa'; -import * as fa6 from 'react-icons/fa6'; -import * as fc from 'react-icons/fc'; -import * as fi from 'react-icons/fi'; -import * as gi from 'react-icons/gi'; -import * as go from 'react-icons/go'; -import * as gr from 'react-icons/gr'; -import * as hi from 'react-icons/hi'; -import * as hi2 from 'react-icons/hi2'; -import * as im from 'react-icons/im'; -import * as io from 'react-icons/io'; -import * as io5 from 'react-icons/io5'; -import * as lia from 'react-icons/lia'; -import * as lu from 'react-icons/lu'; -import * as md from 'react-icons/md'; -import * as pi from 'react-icons/pi'; -import * as ri from 'react-icons/ri'; -import * as rx from 'react-icons/rx'; -import * as si from 'react-icons/si'; -import * as sl from 'react-icons/sl'; -import * as tb from 'react-icons/tb'; -import * as tfi from 'react-icons/tfi'; -import * as ti from 'react-icons/ti'; -import * as vsc from 'react-icons/vsc'; -import * as wi from 'react-icons/wi'; - -import cs from './index.module.css'; - -export type IconName = keyof typeof icons; -const icons = { - ...ai, - ...bi, - ...bs, - ...cg, - ...ci, - ...di, - ...fa, - ...fa6, - ...fc, - ...fi, - ...gi, - ...go, - ...gr, - ...hi, - ...hi2, - ...im, - ...io, - ...io5, - ...lia, - ...lu, - ...md, - ...pi, - ...ri, - ...rx, - ...si, - ...sl, - ...tb, - ...tfi, - ...ti, - ...vsc, - ...wi, -}; - -export const exposedIcons = Object.keys(icons).reduce((acc, icon) => { - acc[icon] = `[ICON:${icon}]`; - return acc; -}, {} as any); - -export function isValidIconName(str: string) { - const [name] = str.split(':'); - return !!icons[name as IconName]; -} - -interface typesPropsIcon { - iconName: IconName; - propsIcon?: IconBaseProps; -} - -export function Icon(props: typesPropsIcon) { - const { iconName, propsIcon } = props; - - const Icon = icons[iconName] || null; - - if (!Icon) { - return null; - } - - return ( - - - - ); -} +import { IconBaseProps } from 'react-icons'; +import * as ai from 'react-icons/ai'; +import * as bi from 'react-icons/bi'; +import * as bs from 'react-icons/bs'; +import * as cg from 'react-icons/cg'; +import * as ci from 'react-icons/ci'; +import * as di from 'react-icons/di'; +import * as fa from 'react-icons/fa'; +import * as fa6 from 'react-icons/fa6'; +import * as fc from 'react-icons/fc'; +import * as fi from 'react-icons/fi'; +import * as gi from 'react-icons/gi'; +import * as go from 'react-icons/go'; +import * as gr from 'react-icons/gr'; +import * as hi from 'react-icons/hi'; +import * as hi2 from 'react-icons/hi2'; +import * as im from 'react-icons/im'; +import * as io from 'react-icons/io'; +import * as io5 from 'react-icons/io5'; +import * as lia from 'react-icons/lia'; +import * as lu from 'react-icons/lu'; +import * as md from 'react-icons/md'; +import * as pi from 'react-icons/pi'; +import * as ri from 'react-icons/ri'; +import * as rx from 'react-icons/rx'; +import * as si from 'react-icons/si'; +import * as sl from 'react-icons/sl'; +import * as tb from 'react-icons/tb'; +import * as tfi from 'react-icons/tfi'; +import * as ti from 'react-icons/ti'; +import * as vsc from 'react-icons/vsc'; +import * as wi from 'react-icons/wi'; + +import cs from './index.module.css'; + +export type IconName = keyof typeof icons; +const icons = { + ...ai, + ...bi, + ...bs, + ...cg, + ...ci, + ...di, + ...fa, + ...fa6, + ...fc, + ...fi, + ...gi, + ...go, + ...gr, + ...hi, + ...hi2, + ...im, + ...io, + ...io5, + ...lia, + ...lu, + ...md, + ...pi, + ...ri, + ...rx, + ...si, + ...sl, + ...tb, + ...tfi, + ...ti, + ...vsc, + ...wi, +}; + +export const exposedIcons = Object.keys(icons).reduce((acc, icon) => { + acc[icon] = `[ICON:${icon}]`; + return acc; +}, {} as any); + +export function isValidIconName(str: string) { + const [name] = str.split(':'); + return !!icons[name as IconName]; +} + +interface typesPropsIcon { + iconName: IconName; + propsIcon?: IconBaseProps; +} + +export function Icon(props: typesPropsIcon) { + const { iconName, propsIcon } = props; + + const Icon = icons[iconName] || null; + + if (!Icon) { + return null; + } + + return ( + + + + ); +} diff --git a/src/apps/shared/components/OverflowTooltip/index.module.css b/src/apps/shared/components/OverflowTooltip/index.module.css index e68b82cd..05475b8e 100644 --- a/src/apps/shared/components/OverflowTooltip/index.module.css +++ b/src/apps/shared/components/OverflowTooltip/index.module.css @@ -1,6 +1,6 @@ - -.text { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis + +.text { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis } \ No newline at end of file diff --git a/src/apps/shared/components/OverflowTooltip/index.tsx b/src/apps/shared/components/OverflowTooltip/index.tsx index 030f4c59..41599f1b 100644 --- a/src/apps/shared/components/OverflowTooltip/index.tsx +++ b/src/apps/shared/components/OverflowTooltip/index.tsx @@ -1,27 +1,27 @@ -import { Tooltip } from 'antd'; -import { useEffect, useRef, useState } from 'react'; - -import cs from './index.module.css'; - -interface Props { - text: string; -} - -export function OverflowTooltip({ text }: Props) { - const textRef = useRef(null); - const [isOverflow, setIsOverflow] = useState(false); - - useEffect(() => { - if (textRef.current) { - setIsOverflow(textRef.current.scrollWidth > textRef.current.clientWidth); - } - }, [text]); - - return ( - - - {text} - - - ); -} +import { Tooltip } from 'antd'; +import { useEffect, useRef, useState } from 'react'; + +import cs from './index.module.css'; + +interface Props { + text: string; +} + +export function OverflowTooltip({ text }: Props) { + const textRef = useRef(null); + const [isOverflow, setIsOverflow] = useState(false); + + useEffect(() => { + if (textRef.current) { + setIsOverflow(textRef.current.scrollWidth > textRef.current.clientWidth); + } + }, [text]); + + return ( + + + {text} + + + ); +} diff --git a/src/apps/shared/events.ts b/src/apps/shared/events.ts index 57d31550..f191c976 100644 --- a/src/apps/shared/events.ts +++ b/src/apps/shared/events.ts @@ -1,7 +1,7 @@ - -export enum FileChange { - Settings = 'settings', - Themes = 'themes', - WegItems = 'weg-items', - Placeholders = 'placeholders', + +export enum FileChange { + Settings = 'settings', + Themes = 'themes', + WegItems = 'weg-items', + Placeholders = 'placeholders', } \ No newline at end of file diff --git a/src/apps/shared/index.ts b/src/apps/shared/index.ts index fa4e0883..94af2d21 100644 --- a/src/apps/shared/index.ts +++ b/src/apps/shared/index.ts @@ -1,82 +1,82 @@ -import { UserSettings } from '../../shared.interfaces'; -import { Theme } from './schemas/Theme'; -import { path } from '@tauri-apps/api'; -import { PhysicalSize } from '@tauri-apps/api/dpi'; -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; - -export function getRootContainer() { - const container = document.getElementById('root'); - if (!container) { - throw new Error('Root container not found'); - } - return container; -} - -export function toPhysicalPixels(size: number): number { - return Math.floor(size * window.devicePixelRatio); -} - -export async function wasInstalledUsingMSIX() { - let installPath = await path.resourceDir(); - return installPath.startsWith('C:\\Program Files\\WindowsApps'); -} - -export const setWindowAsFullSize = () => { - const screenWidth = toPhysicalPixels(window.screen.width); - const screenHeight = toPhysicalPixels(window.screen.height); - getCurrentWebviewWindow().setSize(new PhysicalSize(screenWidth, screenHeight)); -}; - -export function setColorsAsCssVariables(colors: anyObject) { - for (const [key, value] of Object.entries(colors)) { - if (typeof value !== 'string') { - continue; - } - let hex = value.replace('#', '').slice(0, 6); - var color = parseInt(hex, 16); - var r = (color >> 16) & 255; - var g = (color >> 8) & 255; - var b = color & 255; - // replace rust snake case with kebab case - let name = key.replace('_', '-'); - document.documentElement.style.setProperty(`--config-${name}-color`, value.slice(0, 7)); - document.documentElement.style.setProperty(`--config-${name}-color-rgb`, `${r}, ${g}, ${b}`); - } -} - -export function loadThemeCSS(config: Pick) { - let selected = config.jsonSettings.selectedTheme; - let themes: Theme[] = config.themes - .filter((theme) => selected.includes(theme.info.filename)) - .sort((a, b) => { - return selected.indexOf(a.info.filename) - selected.indexOf(b.info.filename); - }); - - if (themes.length === 0) { - let defaultTheme = config.themes.find((theme) => theme.info.filename === 'default'); - themes = defaultTheme ? [defaultTheme] : []; - } - - const label = getCurrentWebviewWindow().label; - let theme_key: keyof Theme['styles'] | null = null; - if (label.startsWith('fancy-toolbar')) { - theme_key = 'toolbar'; - } else if (label.startsWith('seelenweg')) { - theme_key = 'weg'; - } else if (label.startsWith('window-manager')) { - theme_key = 'wm'; - } - - if (!theme_key) { - return; - } - - document.getElementById(theme_key)?.remove(); - let element = document.createElement('style'); - element.id = theme_key.toString(); - element.textContent = ''; - document.head.appendChild(element); - for (const theme of themes) { - element.textContent += theme.styles[theme_key] + '\n'; - } -} +import { UserSettings } from '../../shared.interfaces'; +import { Theme } from './schemas/Theme'; +import { path } from '@tauri-apps/api'; +import { PhysicalSize } from '@tauri-apps/api/dpi'; +import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; + +export function getRootContainer() { + const container = document.getElementById('root'); + if (!container) { + throw new Error('Root container not found'); + } + return container; +} + +export function toPhysicalPixels(size: number): number { + return Math.floor(size * window.devicePixelRatio); +} + +export async function wasInstalledUsingMSIX() { + let installPath = await path.resourceDir(); + return installPath.startsWith('C:\\Program Files\\WindowsApps'); +} + +export const setWindowAsFullSize = () => { + const screenWidth = toPhysicalPixels(window.screen.width); + const screenHeight = toPhysicalPixels(window.screen.height); + getCurrentWebviewWindow().setSize(new PhysicalSize(screenWidth, screenHeight)); +}; + +export function setColorsAsCssVariables(colors: anyObject) { + for (const [key, value] of Object.entries(colors)) { + if (typeof value !== 'string') { + continue; + } + let hex = value.replace('#', '').slice(0, 6); + var color = parseInt(hex, 16); + var r = (color >> 16) & 255; + var g = (color >> 8) & 255; + var b = color & 255; + // replace rust snake case with kebab case + let name = key.replace('_', '-'); + document.documentElement.style.setProperty(`--config-${name}-color`, value.slice(0, 7)); + document.documentElement.style.setProperty(`--config-${name}-color-rgb`, `${r}, ${g}, ${b}`); + } +} + +export function loadThemeCSS(config: Pick) { + let selected = config.jsonSettings.selectedTheme; + let themes: Theme[] = config.themes + .filter((theme) => selected.includes(theme.info.filename)) + .sort((a, b) => { + return selected.indexOf(a.info.filename) - selected.indexOf(b.info.filename); + }); + + if (themes.length === 0) { + let defaultTheme = config.themes.find((theme) => theme.info.filename === 'default'); + themes = defaultTheme ? [defaultTheme] : []; + } + + const label = getCurrentWebviewWindow().label; + let theme_key: keyof Theme['styles'] | null = null; + if (label.startsWith('fancy-toolbar')) { + theme_key = 'toolbar'; + } else if (label.startsWith('seelenweg')) { + theme_key = 'weg'; + } else if (label.startsWith('window-manager')) { + theme_key = 'wm'; + } + + if (!theme_key) { + return; + } + + document.getElementById(theme_key)?.remove(); + let element = document.createElement('style'); + element.id = theme_key.toString(); + element.textContent = ''; + document.head.appendChild(element); + for (const theme of themes) { + element.textContent += theme.styles[theme_key] + '\n'; + } +} diff --git a/src/apps/shared/interfaces/common.ts b/src/apps/shared/interfaces/common.ts index 5573b9bf..f42c09a7 100644 --- a/src/apps/shared/interfaces/common.ts +++ b/src/apps/shared/interfaces/common.ts @@ -1,3 +1,3 @@ -export interface IModule { - enable: boolean; +export interface IModule { + enable: boolean; } \ No newline at end of file diff --git a/src/apps/shared/lang.ts b/src/apps/shared/lang.ts index 79e8d351..7ee1544c 100644 --- a/src/apps/shared/lang.ts +++ b/src/apps/shared/lang.ts @@ -1,76 +1,76 @@ -export type Lang = (typeof LanguageList)[number]['value']; - -export const LanguageList = [ - ...([ - { label: 'Deutsch', value: 'de' }, // German - { label: 'English', value: 'en' }, // English - { label: 'Español', value: 'es' }, // Spanish - { label: '한국어', value: 'ko' }, // Korean - { label: '中文', value: 'zh' }, // Chinese - { label: 'Français', value: 'fr' }, // French - { label: 'العربية', value: 'ar' }, // Arabic - { label: 'Português', value: 'pt' }, // Portuguese - { label: 'Русский', value: 'ru' }, // Russian - { label: 'हिन्दी', value: 'hi' }, // Hindi - { label: '日本語', value: 'ja' }, // Japanese - { label: 'Italiano', value: 'it' }, // Italian - { label: 'Nederlands', value: 'nl' }, // Dutch - { label: 'Türkçe', value: 'tr' }, // Turkish - { label: 'Polski', value: 'pl' }, // Polish - { label: 'Українська', value: 'uk' }, // Ukrainian - { label: 'Ελληνικά', value: 'el' }, // Greek - { label: 'עברית', value: 'he' }, // Hebrew - { label: 'Svenska', value: 'sv' }, // Swedish - { label: 'Norsk', value: 'no' }, // Norwegian - { label: 'Suomi', value: 'fi' }, // Finnish - { label: 'Dansk', value: 'da' }, // Danish - { label: 'Magyar', value: 'hu' }, // Hungarian - { label: 'Română', value: 'ro' }, // Romanian - { label: 'Čeština', value: 'cs' }, // Czech - { label: 'Slovenský', value: 'sk' }, // Slovak - { label: 'Hrvatski', value: 'hr' }, // Croatian - { label: 'Български', value: 'bg' }, // Bulgarian - { label: 'Lietuvių', value: 'lt' }, // Lithuanian - { label: 'Latviešu', value: 'lv' }, // Latvian - { label: 'Eesti', value: 'et' }, // Estonian - { label: 'Filipino', value: 'tl' }, // Filipino - { label: 'Tiếng Việt', value: 'vi' }, // Vietnamese - { label: 'ไทย', value: 'th' }, // Thai - { label: 'Indonesia', value: 'id' }, // Indonesian - { label: 'Malay', value: 'ms' }, // Malay - { label: 'Català', value: 'ca' }, // Catalan - { label: 'Afrikaans', value: 'af' }, // Afrikaans - { label: 'বাংলা', value: 'bn' }, // Bengali - { label: 'فارسی', value: 'fa' }, // Farsi - { label: 'ਪੰਜਾਬੀ', value: 'pa' }, // Punjabi - { label: 'Kiswahili', value: 'sw' }, // Swahili - { label: 'தமிழ்', value: 'ta' }, // Tamil - { label: 'اردو', value: 'ur' }, // Urdu - { label: 'Cymraeg', value: 'cy' }, // Welsh - { label: 'አማርኛ', value: 'am' }, // Amharic - { label: 'Հայերեն', value: 'hy' }, // Armenian - { label: 'Azərbaycan', value: 'az' }, // Azerbaijani - { label: 'Euskara', value: 'eu' }, // Basque - { label: 'Bosanski', value: 'bs' }, // Bosnian - { label: 'ქართული', value: 'ka' }, // Georgian - { label: 'ગુજરાતી', value: 'gu' }, // Gujarati - { label: 'Íslenska', value: 'is' }, // Icelandic - { label: 'ភាសាខ្មែរ', value: 'km' }, // Khmer - { label: 'Kurdî', value: 'ku' }, // Kurdish - { label: 'ລາວ', value: 'lo' }, // Lao - { label: 'Lëtzebuergesch', value: 'lb' }, // Luxembourgish - { label: 'Македонски', value: 'mk' }, // Macedonian - { label: 'Malti', value: 'mt' }, // Maltese - { label: 'Монгол', value: 'mn' }, // Mongolian - { label: 'नेपाली', value: 'ne' }, // Nepali - { label: 'پښتو', value: 'ps' }, // Pashto - { label: 'Српски', value: 'sr' }, // Serbian - { label: 'සිංහල', value: 'si' }, // Sinhala - { label: 'Soomaali', value: 'so' }, // Somali - { label: 'Тоҷикӣ', value: 'tg' }, // Tajik - { label: 'తెలుగు', value: 'te' }, // Telugu - { label: 'Oʻzbek', value: 'uz' }, // Uzbek - { label: 'Yorùbá', value: 'yo' }, // Yoruba - { label: 'isiZulu', value: 'zu' }, // Zulu - ] as const), -].sort((a, b) => a.label.localeCompare(b.label)); +export type Lang = (typeof LanguageList)[number]['value']; + +export const LanguageList = [ + ...([ + { label: 'Deutsch', value: 'de' }, // German + { label: 'English', value: 'en' }, // English + { label: 'Español', value: 'es' }, // Spanish + { label: '한국어', value: 'ko' }, // Korean + { label: '中文', value: 'zh' }, // Chinese + { label: 'Français', value: 'fr' }, // French + { label: 'العربية', value: 'ar' }, // Arabic + { label: 'Português', value: 'pt' }, // Portuguese + { label: 'Русский', value: 'ru' }, // Russian + { label: 'हिन्दी', value: 'hi' }, // Hindi + { label: '日本語', value: 'ja' }, // Japanese + { label: 'Italiano', value: 'it' }, // Italian + { label: 'Nederlands', value: 'nl' }, // Dutch + { label: 'Türkçe', value: 'tr' }, // Turkish + { label: 'Polski', value: 'pl' }, // Polish + { label: 'Українська', value: 'uk' }, // Ukrainian + { label: 'Ελληνικά', value: 'el' }, // Greek + { label: 'עברית', value: 'he' }, // Hebrew + { label: 'Svenska', value: 'sv' }, // Swedish + { label: 'Norsk', value: 'no' }, // Norwegian + { label: 'Suomi', value: 'fi' }, // Finnish + { label: 'Dansk', value: 'da' }, // Danish + { label: 'Magyar', value: 'hu' }, // Hungarian + { label: 'Română', value: 'ro' }, // Romanian + { label: 'Čeština', value: 'cs' }, // Czech + { label: 'Slovenský', value: 'sk' }, // Slovak + { label: 'Hrvatski', value: 'hr' }, // Croatian + { label: 'Български', value: 'bg' }, // Bulgarian + { label: 'Lietuvių', value: 'lt' }, // Lithuanian + { label: 'Latviešu', value: 'lv' }, // Latvian + { label: 'Eesti', value: 'et' }, // Estonian + { label: 'Filipino', value: 'tl' }, // Filipino + { label: 'Tiếng Việt', value: 'vi' }, // Vietnamese + { label: 'ไทย', value: 'th' }, // Thai + { label: 'Indonesia', value: 'id' }, // Indonesian + { label: 'Malay', value: 'ms' }, // Malay + { label: 'Català', value: 'ca' }, // Catalan + { label: 'Afrikaans', value: 'af' }, // Afrikaans + { label: 'বাংলা', value: 'bn' }, // Bengali + { label: 'فارسی', value: 'fa' }, // Farsi + { label: 'ਪੰਜਾਬੀ', value: 'pa' }, // Punjabi + { label: 'Kiswahili', value: 'sw' }, // Swahili + { label: 'தமிழ்', value: 'ta' }, // Tamil + { label: 'اردو', value: 'ur' }, // Urdu + { label: 'Cymraeg', value: 'cy' }, // Welsh + { label: 'አማርኛ', value: 'am' }, // Amharic + { label: 'Հայերեն', value: 'hy' }, // Armenian + { label: 'Azərbaycan', value: 'az' }, // Azerbaijani + { label: 'Euskara', value: 'eu' }, // Basque + { label: 'Bosanski', value: 'bs' }, // Bosnian + { label: 'ქართული', value: 'ka' }, // Georgian + { label: 'ગુજરાતી', value: 'gu' }, // Gujarati + { label: 'Íslenska', value: 'is' }, // Icelandic + { label: 'ភាសាខ្មែរ', value: 'km' }, // Khmer + { label: 'Kurdî', value: 'ku' }, // Kurdish + { label: 'ລາວ', value: 'lo' }, // Lao + { label: 'Lëtzebuergesch', value: 'lb' }, // Luxembourgish + { label: 'Македонски', value: 'mk' }, // Macedonian + { label: 'Malti', value: 'mt' }, // Maltese + { label: 'Монгол', value: 'mn' }, // Mongolian + { label: 'नेपाली', value: 'ne' }, // Nepali + { label: 'پښتو', value: 'ps' }, // Pashto + { label: 'Српски', value: 'sr' }, // Serbian + { label: 'සිංහල', value: 'si' }, // Sinhala + { label: 'Soomaali', value: 'so' }, // Somali + { label: 'Тоҷикӣ', value: 'tg' }, // Tajik + { label: 'తెలుగు', value: 'te' }, // Telugu + { label: 'Oʻzbek', value: 'uz' }, // Uzbek + { label: 'Yorùbá', value: 'yo' }, // Yoruba + { label: 'isiZulu', value: 'zu' }, // Zulu + ] as const), +].sort((a, b) => a.label.localeCompare(b.label)); diff --git a/src/apps/shared/redux.ts b/src/apps/shared/redux.ts index 2bcf7e25..14f7de30 100644 --- a/src/apps/shared/redux.ts +++ b/src/apps/shared/redux.ts @@ -1,21 +1,21 @@ -import { CaseReducerActions, SliceCaseReducers } from '@reduxjs/toolkit'; -import { Event, listen } from '@tauri-apps/api/event'; -import { Store } from 'redux'; - -export class TauriReduxExtension, Name extends string> { - constructor(private store: Store, private actions: CaseReducerActions) {} - - handleAction(action: K, event: Event) { - const actionObj = this.actions[action](event.payload); - this.store.dispatch(actionObj); - } - - /** Actions exposed to Tauri as `redux://{KeyOfActionCreator}` */ - async globalExpose(...x: [K]) { - let action = x[0]; - if (typeof action !== 'string') { - return; - } - await listen(`redux://${action}`, this.handleAction.bind(this, action)); - } -} +import { CaseReducerActions, SliceCaseReducers } from '@reduxjs/toolkit'; +import { Event, listen } from '@tauri-apps/api/event'; +import { Store } from 'redux'; + +export class TauriReduxExtension, Name extends string> { + constructor(private store: Store, private actions: CaseReducerActions) {} + + handleAction(action: K, event: Event) { + const actionObj = this.actions[action](event.payload); + this.store.dispatch(actionObj); + } + + /** Actions exposed to Tauri as `redux://{KeyOfActionCreator}` */ + async globalExpose(...x: [K]) { + let action = x[0]; + if (typeof action !== 'string') { + return; + } + await listen(`redux://${action}`, this.handleAction.bind(this, action)); + } +} diff --git a/src/apps/shared/schemas/AppsConfigurations.ts b/src/apps/shared/schemas/AppsConfigurations.ts index 4b0bf7cc..6a565206 100644 --- a/src/apps/shared/schemas/AppsConfigurations.ts +++ b/src/apps/shared/schemas/AppsConfigurations.ts @@ -1,67 +1,67 @@ -import { z } from 'zod'; - -export enum ApplicationIdentifier { - Exe = 'Exe', - Class = 'Class', - Title = 'Title', - Path = 'Path', -} - -export enum MatchingStrategy { - Legacy = 'Legacy', - Equals = 'Equals', - StartsWith = 'StartsWith', - EndsWith = 'EndsWith', - Contains = 'Contains', - Regex = 'Regex', -} - -function stringInsensitiveToEnum>(value: string, enumObj: Enum) { - return Object.values(enumObj).find((v) => v.toLocaleLowerCase() === value.toLocaleLowerCase()) as Enum[keyof Enum] | undefined; -} - -interface _IdWithIdentifier { - id: string; - kind: ApplicationIdentifier; - matching_strategy: MatchingStrategy; - negation: boolean; - and: _IdWithIdentifier[]; - or: _IdWithIdentifier[]; -} - -export const IdWithIdentifierSchema = z.object({ - id: z.string().default('new-app.exe'), - kind: z - .string() - .transform((arg) => stringInsensitiveToEnum(arg, ApplicationIdentifier)) - .default(ApplicationIdentifier.Exe), - matching_strategy: z - .string() - .transform((arg) => stringInsensitiveToEnum(arg, MatchingStrategy)) - .default(MatchingStrategy.Equals), - negation: z.boolean().default(false), - and: z.array(z.lazy(() => IdWithIdentifierSchema)).default([]), - or: z.array(z.lazy(() => IdWithIdentifierSchema)).default([]), -}) as z.ZodType<_IdWithIdentifier>; - -export interface IdWithIdentifier { - id: _IdWithIdentifier['id']; - kind: _IdWithIdentifier['kind']; - matchingStrategy: _IdWithIdentifier['matching_strategy']; - negation: _IdWithIdentifier['negation']; - and: IdWithIdentifier[]; - or: IdWithIdentifier[]; -} - -export class IdWithIdentifier { - static default(): IdWithIdentifier { - return { - id: 'new-app.exe', - kind: ApplicationIdentifier.Exe, - matchingStrategy: MatchingStrategy.Equals, - negation: false, - and: [], - or: [], - }; - } +import { z } from 'zod'; + +export enum ApplicationIdentifier { + Exe = 'Exe', + Class = 'Class', + Title = 'Title', + Path = 'Path', +} + +export enum MatchingStrategy { + Legacy = 'Legacy', + Equals = 'Equals', + StartsWith = 'StartsWith', + EndsWith = 'EndsWith', + Contains = 'Contains', + Regex = 'Regex', +} + +function stringInsensitiveToEnum>(value: string, enumObj: Enum) { + return Object.values(enumObj).find((v) => v.toLocaleLowerCase() === value.toLocaleLowerCase()) as Enum[keyof Enum] | undefined; +} + +interface _IdWithIdentifier { + id: string; + kind: ApplicationIdentifier; + matching_strategy: MatchingStrategy; + negation: boolean; + and: _IdWithIdentifier[]; + or: _IdWithIdentifier[]; +} + +export const IdWithIdentifierSchema = z.object({ + id: z.string().default('new-app.exe'), + kind: z + .string() + .transform((arg) => stringInsensitiveToEnum(arg, ApplicationIdentifier)) + .default(ApplicationIdentifier.Exe), + matching_strategy: z + .string() + .transform((arg) => stringInsensitiveToEnum(arg, MatchingStrategy)) + .default(MatchingStrategy.Equals), + negation: z.boolean().default(false), + and: z.array(z.lazy(() => IdWithIdentifierSchema)).default([]), + or: z.array(z.lazy(() => IdWithIdentifierSchema)).default([]), +}) as z.ZodType<_IdWithIdentifier>; + +export interface IdWithIdentifier { + id: _IdWithIdentifier['id']; + kind: _IdWithIdentifier['kind']; + matchingStrategy: _IdWithIdentifier['matching_strategy']; + negation: _IdWithIdentifier['negation']; + and: IdWithIdentifier[]; + or: IdWithIdentifier[]; +} + +export class IdWithIdentifier { + static default(): IdWithIdentifier { + return { + id: 'new-app.exe', + kind: ApplicationIdentifier.Exe, + matchingStrategy: MatchingStrategy.Equals, + negation: false, + and: [], + or: [], + }; + } } \ No newline at end of file diff --git a/src/apps/shared/schemas/FancyToolbar.ts b/src/apps/shared/schemas/FancyToolbar.ts index 30f35318..0fa5317b 100644 --- a/src/apps/shared/schemas/FancyToolbar.ts +++ b/src/apps/shared/schemas/FancyToolbar.ts @@ -1,9 +1,9 @@ -import z from 'zod'; - -export const FancyToolbarSchema = z.object({ - enabled: z.boolean().default(true), - height: z.number().positive().default(30), - placeholder: z.string().nullable().default(null), -}); - -export type FancyToolbar = z.infer; +import z from 'zod'; + +export const FancyToolbarSchema = z.object({ + enabled: z.boolean().default(true), + height: z.number().positive().default(30), + placeholder: z.string().nullable().default(null), +}); + +export type FancyToolbar = z.infer; diff --git a/src/apps/shared/schemas/Layout.ts b/src/apps/shared/schemas/Layout.ts index a953a226..f4faf4c3 100644 --- a/src/apps/shared/schemas/Layout.ts +++ b/src/apps/shared/schemas/Layout.ts @@ -1,93 +1,93 @@ -import { CreatorInfoSchema } from '.'; -import { modify } from 'readable-types'; -import z from 'zod'; - -export enum NodeType { - Vertical = 'Vertical', - Horizontal = 'Horizontal', - Leaf = 'Leaf', - Stack = 'Stack', - Fallback = 'Fallback', -} - -export enum NodeSubtype { - Temporal = 'Temporal', - Permanent = 'Permanent', -} - -export enum NoFallbackBehavior { - Float = 'Float', - Unmanaged = 'Unmanaged', -} - -export const hwndSchema = z.number().nonnegative().describe('Window handle'); - -export type BaseNode = z.infer; -const BaseNodeSchema = z.object({ - type: z.nativeEnum(NodeType), - subtype: z.nativeEnum(NodeSubtype).default(NodeSubtype.Permanent), - priority: z - .number() - .positive() - .describe('Order in how the tree will be traversed (1 = first, 2 = second, etc.)') - .default(1), - growFactor: z.number().describe('How much of the remaining space this node will take').default(1), - condition: z.string().optional().nullable().describe('Math Condition for the node to be shown, e.g: n >= 3'), -}); - -export type StackNode = z.infer; -const StackNodeSchema = BaseNodeSchema.extend({ - type: z.literal(NodeType.Stack), - active: hwndSchema.nullable().default(null), - handles: z.array(hwndSchema).default([]), -}); - -export type FallbackNode = z.infer; -const FallbackNodeSchema = BaseNodeSchema.extend({ - type: z.literal(NodeType.Fallback), - subtype: z.literal(NodeSubtype.Permanent).default(NodeSubtype.Permanent), - active: hwndSchema.nullable().default(null), - handles: z.array(hwndSchema).default([]), -}); - -export type LeafNode = z.infer; -const LeafNodeSchema = BaseNodeSchema.extend({ - type: z.literal(NodeType.Leaf), - handle: hwndSchema.nullable().default(null), -}); - -export type HorizontalBranchNode = BaseNode & { type: NodeType.Horizontal; children: Node[] }; -const HorizontalBranchNodeSchema = BaseNodeSchema.extend({ - type: z.literal(NodeType.Horizontal), - children: z.array(z.lazy(() => NodeSchema)).min(1), -}) as z.ZodType; - -export type VerticalBranchNode = BaseNode & { type: NodeType.Vertical; children: Node[] }; -const VerticalBranchNodeSchema = BaseNodeSchema.extend({ - type: z.literal(NodeType.Vertical), - children: z.array(z.lazy(() => NodeSchema)).min(1), -}) as z.ZodType; - -export type Node = z.infer; -export const NodeSchema = z.union([ - StackNodeSchema, - FallbackNodeSchema, - LeafNodeSchema, - HorizontalBranchNodeSchema, - VerticalBranchNodeSchema, -]).describe('The layout tree'); - -type InnerLayout = z.infer; -export const LayoutSchema = z.object({ - info: CreatorInfoSchema.default({}), - structure: NodeSchema.default({ type: NodeType.Fallback }), - no_fallback_behavior: z.nativeEnum(NoFallbackBehavior).optional().nullable(), -}); - -export interface Layout { - info: modify; - structure: InnerLayout['structure']; - noFallbackBehavior: InnerLayout['no_fallback_behavior']; +import { CreatorInfoSchema } from '.'; +import { modify } from 'readable-types'; +import z from 'zod'; + +export enum NodeType { + Vertical = 'Vertical', + Horizontal = 'Horizontal', + Leaf = 'Leaf', + Stack = 'Stack', + Fallback = 'Fallback', +} + +export enum NodeSubtype { + Temporal = 'Temporal', + Permanent = 'Permanent', +} + +export enum NoFallbackBehavior { + Float = 'Float', + Unmanaged = 'Unmanaged', +} + +export const hwndSchema = z.number().nonnegative().describe('Window handle'); + +export type BaseNode = z.infer; +const BaseNodeSchema = z.object({ + type: z.nativeEnum(NodeType), + subtype: z.nativeEnum(NodeSubtype).default(NodeSubtype.Permanent), + priority: z + .number() + .positive() + .describe('Order in how the tree will be traversed (1 = first, 2 = second, etc.)') + .default(1), + growFactor: z.number().describe('How much of the remaining space this node will take').default(1), + condition: z.string().optional().nullable().describe('Math Condition for the node to be shown, e.g: n >= 3'), +}); + +export type StackNode = z.infer; +const StackNodeSchema = BaseNodeSchema.extend({ + type: z.literal(NodeType.Stack), + active: hwndSchema.nullable().default(null), + handles: z.array(hwndSchema).default([]), +}); + +export type FallbackNode = z.infer; +const FallbackNodeSchema = BaseNodeSchema.extend({ + type: z.literal(NodeType.Fallback), + subtype: z.literal(NodeSubtype.Permanent).default(NodeSubtype.Permanent), + active: hwndSchema.nullable().default(null), + handles: z.array(hwndSchema).default([]), +}); + +export type LeafNode = z.infer; +const LeafNodeSchema = BaseNodeSchema.extend({ + type: z.literal(NodeType.Leaf), + handle: hwndSchema.nullable().default(null), +}); + +export type HorizontalBranchNode = BaseNode & { type: NodeType.Horizontal; children: Node[] }; +const HorizontalBranchNodeSchema = BaseNodeSchema.extend({ + type: z.literal(NodeType.Horizontal), + children: z.array(z.lazy(() => NodeSchema)).min(1), +}) as z.ZodType; + +export type VerticalBranchNode = BaseNode & { type: NodeType.Vertical; children: Node[] }; +const VerticalBranchNodeSchema = BaseNodeSchema.extend({ + type: z.literal(NodeType.Vertical), + children: z.array(z.lazy(() => NodeSchema)).min(1), +}) as z.ZodType; + +export type Node = z.infer; +export const NodeSchema = z.union([ + StackNodeSchema, + FallbackNodeSchema, + LeafNodeSchema, + HorizontalBranchNodeSchema, + VerticalBranchNodeSchema, +]).describe('The layout tree'); + +type InnerLayout = z.infer; +export const LayoutSchema = z.object({ + info: CreatorInfoSchema.default({}), + structure: NodeSchema.default({ type: NodeType.Fallback }), + no_fallback_behavior: z.nativeEnum(NoFallbackBehavior).optional().nullable(), +}); + +export interface Layout { + info: modify; + structure: InnerLayout['structure']; + noFallbackBehavior: InnerLayout['no_fallback_behavior']; } \ No newline at end of file diff --git a/src/apps/shared/schemas/Monitors.ts b/src/apps/shared/schemas/Monitors.ts index a62dd2ae..c1817808 100644 --- a/src/apps/shared/schemas/Monitors.ts +++ b/src/apps/shared/schemas/Monitors.ts @@ -1,23 +1,23 @@ -import { RectSchema } from './WindowManager'; -import z from 'zod'; - -export type Workspace = z.infer; -export const WorkspaceSchema = z.object({ - name: z.string().default('New Workspace'), - layout: z.string().default('BSP'), - padding: z.number().nonnegative().optional().nullable(), - gap: z.number().nonnegative().optional().nullable(), -}); - -type InnerMonitor = z.infer; -export const MonitorSchema = z.object({ - workspaces: z.array(WorkspaceSchema).min(1).default([WorkspaceSchema.parse({})]), - work_area_offset: RectSchema.optional().nullable(), - editing_workspace: z.number().nonnegative().default(0), -}); - -export interface Monitor { - workAreaOffset: InnerMonitor['work_area_offset']; - workspaces: InnerMonitor['workspaces']; - edditingWorkspace: InnerMonitor['editing_workspace']; +import { RectSchema } from './WindowManager'; +import z from 'zod'; + +export type Workspace = z.infer; +export const WorkspaceSchema = z.object({ + name: z.string().default('New Workspace'), + layout: z.string().default('BSP'), + padding: z.number().nonnegative().optional().nullable(), + gap: z.number().nonnegative().optional().nullable(), +}); + +type InnerMonitor = z.infer; +export const MonitorSchema = z.object({ + workspaces: z.array(WorkspaceSchema).min(1).default([WorkspaceSchema.parse({})]), + work_area_offset: RectSchema.optional().nullable(), + editing_workspace: z.number().nonnegative().default(0), +}); + +export interface Monitor { + workAreaOffset: InnerMonitor['work_area_offset']; + workspaces: InnerMonitor['workspaces']; + edditingWorkspace: InnerMonitor['editing_workspace']; } \ No newline at end of file diff --git a/src/apps/shared/schemas/Placeholders.ts b/src/apps/shared/schemas/Placeholders.ts index ae37b388..45964412 100644 --- a/src/apps/shared/schemas/Placeholders.ts +++ b/src/apps/shared/schemas/Placeholders.ts @@ -1,168 +1,168 @@ -import { CreatorInfoSchema } from '.'; -import z from 'zod'; - -export enum ToolbarModuleType { - // generic types - Generic = 'generic', - Text = 'text', - // special types - Date = 'date', - Power = 'power', - Settings = 'settings', - Network = 'network', - Workspaces = 'workspaces', - Media = 'media', - Tray = 'tray', - Device = 'device', - Notifications = 'notifications', -} - -export enum WorkspaceTMMode { - Dotted = 'dotted', - Named = 'named', - Numbered = 'numbered', -} - -export enum TimeUnit { - SECOND = 'second', - MINUTE = 'minute', - HOUR = 'hour', - DAY = 'day', -} - -export enum DeviceTMSubType { - Disk = 'disk', - CPU = 'cpu', - Memory = 'memory', -} - -export const BaseTMSchema = z.object({ - id: z.string().default(() => crypto.randomUUID()), - type: z.nativeEnum(ToolbarModuleType), - template: z - .string() - .transform((value) => value.trimEnd()) - .refine((value) => !value.endsWith('\n'), { - message: 'Template must not end with a newline', - }) - .default('"Unset"'), - tooltip: z.string().nullable().default(null), - badge: z.string().nullable().default(null), - onClick: z.string().nullable().default(null).describe('Deprecated, use `onClickV2` instead'), - onClickV2: z.string().nullable().default(null), - style: z.record(z.string(), z.any()).default({}), -}); - -export type GenericToolbarModule = z.infer; -export const GenericToolbarModuleSchema = BaseTMSchema.extend({ - type: z.union([z.literal(ToolbarModuleType.Generic), z.literal(ToolbarModuleType.Text)]), -}); - -export type TrayTM = z.infer; -export const TrayTMSchema = BaseTMSchema.extend({ - type: z.literal(ToolbarModuleType.Tray), -}); - -export type DateToolbarModule = z.infer; -export const DateToolbarModuleSchema = BaseTMSchema.extend({ - type: z.literal(ToolbarModuleType.Date), - each: z - .nativeEnum(TimeUnit) - .describe('Time unit to update the showing date') - .default(TimeUnit.MINUTE), - format: z.string().default('MMM Do, HH:mm'), -}); - -export type PowerToolbarModule = z.infer; -export const PowerToolbarModuleSchema = BaseTMSchema.extend({ - type: z.literal(ToolbarModuleType.Power), -}); - -export type NetworkTM = z.infer; -export const NetworkTMSchema = BaseTMSchema.extend({ - type: z.literal(ToolbarModuleType.Network), - withWlanSelector: z - .boolean() - .describe('Show Wi-fi settings on click (overrides onClick property)') - .default(false), -}); - -export type MediaTM = z.infer; -export const MediaTMSchema = BaseTMSchema.extend({ - type: z.literal(ToolbarModuleType.Media), - withMediaControls: z.boolean().default(false), -}); - -export type NotificationsTM = z.infer; -export const NotificationsTMSchema = BaseTMSchema.extend({ - type: z.literal(ToolbarModuleType.Notifications), -}); - -export type DeviceTM = z.infer; -export const DeviceTMSchema = BaseTMSchema.extend({ - type: z.literal(ToolbarModuleType.Device), -}); - -export type SettingsToolbarModule = z.infer; -export const SettingsToolbarModuleSchema = BaseTMSchema.extend({ - type: z.literal(ToolbarModuleType.Settings), -}); - -export type WorkspacesTM = z.infer; -export const WorkspaceTMSchema = BaseTMSchema.extend({ - type: z.literal(ToolbarModuleType.Workspaces), - mode: z.nativeEnum(WorkspaceTMMode).default(WorkspaceTMMode.Numbered), -}); - -export type ToolbarModule = z.infer; -export const ToolbarModuleSchema = z.union([ - GenericToolbarModuleSchema, - DateToolbarModuleSchema, - PowerToolbarModuleSchema, - SettingsToolbarModuleSchema, - WorkspaceTMSchema, - TrayTMSchema, - NetworkTMSchema, - MediaTMSchema, - DeviceTMSchema, - NotificationsTMSchema, -]); - -type InnerPlaceholder = z.infer; -export const PlaceholderSchema = z.object({ - info: CreatorInfoSchema.default({}), - left: z.array(ToolbarModuleSchema).default([]), - center: z.array(ToolbarModuleSchema).default([]), - right: z.array(ToolbarModuleSchema).default([]), -}); - -export interface Placeholder extends InnerPlaceholder {} - -export function ParsePlaceholder(value: any): Placeholder | null { - let innerSchema = z.object({ - info: CreatorInfoSchema.default({}), - left: z.array(z.any()).default([]), - center: z.array(z.any()).default([]), - right: z.array(z.any()).default([]), - }); - - const result = innerSchema.safeParse(value); - if (!result.success) { - console.error(result.error); - return null; - } - - const cb = (acc: ToolbarModule[], current: any) => { - let result = ToolbarModuleSchema.safeParse(current); - if (result.success) { - acc.push(result.data); - } - return acc; - }; - - result.data.left = result.data.left.reduce(cb, []); - result.data.center = result.data.center.reduce(cb, []); - result.data.right = result.data.right.reduce(cb, []); - - return result.data; -} +import { CreatorInfoSchema } from '.'; +import z from 'zod'; + +export enum ToolbarModuleType { + // generic types + Generic = 'generic', + Text = 'text', + // special types + Date = 'date', + Power = 'power', + Settings = 'settings', + Network = 'network', + Workspaces = 'workspaces', + Media = 'media', + Tray = 'tray', + Device = 'device', + Notifications = 'notifications', +} + +export enum WorkspaceTMMode { + Dotted = 'dotted', + Named = 'named', + Numbered = 'numbered', +} + +export enum TimeUnit { + SECOND = 'second', + MINUTE = 'minute', + HOUR = 'hour', + DAY = 'day', +} + +export enum DeviceTMSubType { + Disk = 'disk', + CPU = 'cpu', + Memory = 'memory', +} + +export const BaseTMSchema = z.object({ + id: z.string().default(() => crypto.randomUUID()), + type: z.nativeEnum(ToolbarModuleType), + template: z + .string() + .transform((value) => value.trimEnd()) + .refine((value) => !value.endsWith('\n'), { + message: 'Template must not end with a newline', + }) + .default('"Unset"'), + tooltip: z.string().nullable().default(null), + badge: z.string().nullable().default(null), + onClick: z.string().nullable().default(null).describe('Deprecated, use `onClickV2` instead'), + onClickV2: z.string().nullable().default(null), + style: z.record(z.string(), z.any()).default({}), +}); + +export type GenericToolbarModule = z.infer; +export const GenericToolbarModuleSchema = BaseTMSchema.extend({ + type: z.union([z.literal(ToolbarModuleType.Generic), z.literal(ToolbarModuleType.Text)]), +}); + +export type TrayTM = z.infer; +export const TrayTMSchema = BaseTMSchema.extend({ + type: z.literal(ToolbarModuleType.Tray), +}); + +export type DateToolbarModule = z.infer; +export const DateToolbarModuleSchema = BaseTMSchema.extend({ + type: z.literal(ToolbarModuleType.Date), + each: z + .nativeEnum(TimeUnit) + .describe('Time unit to update the showing date') + .default(TimeUnit.MINUTE), + format: z.string().default('MMM Do, HH:mm'), +}); + +export type PowerToolbarModule = z.infer; +export const PowerToolbarModuleSchema = BaseTMSchema.extend({ + type: z.literal(ToolbarModuleType.Power), +}); + +export type NetworkTM = z.infer; +export const NetworkTMSchema = BaseTMSchema.extend({ + type: z.literal(ToolbarModuleType.Network), + withWlanSelector: z + .boolean() + .describe('Show Wi-fi settings on click (overrides onClick property)') + .default(false), +}); + +export type MediaTM = z.infer; +export const MediaTMSchema = BaseTMSchema.extend({ + type: z.literal(ToolbarModuleType.Media), + withMediaControls: z.boolean().default(false), +}); + +export type NotificationsTM = z.infer; +export const NotificationsTMSchema = BaseTMSchema.extend({ + type: z.literal(ToolbarModuleType.Notifications), +}); + +export type DeviceTM = z.infer; +export const DeviceTMSchema = BaseTMSchema.extend({ + type: z.literal(ToolbarModuleType.Device), +}); + +export type SettingsToolbarModule = z.infer; +export const SettingsToolbarModuleSchema = BaseTMSchema.extend({ + type: z.literal(ToolbarModuleType.Settings), +}); + +export type WorkspacesTM = z.infer; +export const WorkspaceTMSchema = BaseTMSchema.extend({ + type: z.literal(ToolbarModuleType.Workspaces), + mode: z.nativeEnum(WorkspaceTMMode).default(WorkspaceTMMode.Numbered), +}); + +export type ToolbarModule = z.infer; +export const ToolbarModuleSchema = z.union([ + GenericToolbarModuleSchema, + DateToolbarModuleSchema, + PowerToolbarModuleSchema, + SettingsToolbarModuleSchema, + WorkspaceTMSchema, + TrayTMSchema, + NetworkTMSchema, + MediaTMSchema, + DeviceTMSchema, + NotificationsTMSchema, +]); + +type InnerPlaceholder = z.infer; +export const PlaceholderSchema = z.object({ + info: CreatorInfoSchema.default({}), + left: z.array(ToolbarModuleSchema).default([]), + center: z.array(ToolbarModuleSchema).default([]), + right: z.array(ToolbarModuleSchema).default([]), +}); + +export interface Placeholder extends InnerPlaceholder {} + +export function ParsePlaceholder(value: any): Placeholder | null { + let innerSchema = z.object({ + info: CreatorInfoSchema.default({}), + left: z.array(z.any()).default([]), + center: z.array(z.any()).default([]), + right: z.array(z.any()).default([]), + }); + + const result = innerSchema.safeParse(value); + if (!result.success) { + console.error(result.error); + return null; + } + + const cb = (acc: ToolbarModule[], current: any) => { + let result = ToolbarModuleSchema.safeParse(current); + if (result.success) { + acc.push(result.data); + } + return acc; + }; + + result.data.left = result.data.left.reduce(cb, []); + result.data.center = result.data.center.reduce(cb, []); + result.data.right = result.data.right.reduce(cb, []); + + return result.data; +} diff --git a/src/apps/shared/schemas/SeelenWegItems.ts b/src/apps/shared/schemas/SeelenWegItems.ts index 0e3601b5..1d750eb3 100644 --- a/src/apps/shared/schemas/SeelenWegItems.ts +++ b/src/apps/shared/schemas/SeelenWegItems.ts @@ -1,56 +1,56 @@ -import { z } from 'zod'; - -export enum SwItemType { - PinnedApp = 'PinnedApp', - TemporalApp = 'TemporalPin', - Separator = 'Separator', - Media = 'Media', - Start = 'StartMenu', -} - -export type SavedPinnedApp = z.infer; -const PinnedAppSchema = z.object({ - type: z.literal(SwItemType.PinnedApp), - /** Path to executable */ - exe: z.string(), - /** Path to execute the app using explorer.exe (uwp apps starts with `shell:AppsFolder`) */ - execution_path: z.string(), -}); - -export type SavedSeparatorItem = z.infer; -const SeparatorSchema = z.object({ - type: z.literal(SwItemType.Separator), -}); - -export type SavedMediaItem = z.infer; -const MediaItemSchema = z.object({ - type: z.literal(SwItemType.Media), -}); - -export type StartMenuItem = z.infer; -const StartMenuItemSchema = z.object({ - type: z.literal(SwItemType.Start), -}); - -export type SwSavedItem = z.infer; -export const SwSavedItemSchema = z.union([ - PinnedAppSchema, - SeparatorSchema, - MediaItemSchema, - StartMenuItemSchema, -]); - -export interface SwSaveFile extends z.infer {} -export const SwSaveFileSchema = z.object({ - left: z.array(SwSavedItemSchema).default([ - { - type: SwItemType.Start, - }, - ]), - center: z.array(SwSavedItemSchema).default([]), - right: z.array(SwSavedItemSchema).default([ - { - type: SwItemType.Media, - }, - ]), -}); +import { z } from 'zod'; + +export enum SwItemType { + PinnedApp = 'PinnedApp', + TemporalApp = 'TemporalPin', + Separator = 'Separator', + Media = 'Media', + Start = 'StartMenu', +} + +export type SavedPinnedApp = z.infer; +const PinnedAppSchema = z.object({ + type: z.literal(SwItemType.PinnedApp), + /** Path to executable */ + exe: z.string(), + /** Path to execute the app using explorer.exe (uwp apps starts with `shell:AppsFolder`) */ + execution_path: z.string(), +}); + +export type SavedSeparatorItem = z.infer; +const SeparatorSchema = z.object({ + type: z.literal(SwItemType.Separator), +}); + +export type SavedMediaItem = z.infer; +const MediaItemSchema = z.object({ + type: z.literal(SwItemType.Media), +}); + +export type StartMenuItem = z.infer; +const StartMenuItemSchema = z.object({ + type: z.literal(SwItemType.Start), +}); + +export type SwSavedItem = z.infer; +export const SwSavedItemSchema = z.union([ + PinnedAppSchema, + SeparatorSchema, + MediaItemSchema, + StartMenuItemSchema, +]); + +export interface SwSaveFile extends z.infer {} +export const SwSaveFileSchema = z.object({ + left: z.array(SwSavedItemSchema).default([ + { + type: SwItemType.Start, + }, + ]), + center: z.array(SwSavedItemSchema).default([]), + right: z.array(SwSavedItemSchema).default([ + { + type: SwItemType.Media, + }, + ]), +}); diff --git a/src/apps/shared/schemas/Seelenweg.ts b/src/apps/shared/schemas/Seelenweg.ts index ccedf592..a2133308 100644 --- a/src/apps/shared/schemas/Seelenweg.ts +++ b/src/apps/shared/schemas/Seelenweg.ts @@ -1,46 +1,46 @@ -import z from 'zod'; - -export enum SeelenWegMode { - FULL_WIDTH = 'Full-Width', - MIN_CONTENT = 'Min-Content', -} - -export enum SeelenWegHideMode { - Never = 'Never', - Always = 'Always', - OnOverlap = 'On-Overlap', -} - -export enum SeelenWegSide { - LEFT = 'Left', - RIGHT = 'Right', - TOP = 'Top', - BOTTOM = 'Bottom', -} - -export const SeelenWegSchema = z.object({ - enabled: z.boolean().default(true), - mode: z.nativeEnum(SeelenWegMode).default(SeelenWegMode.MIN_CONTENT), - hide_mode: z.nativeEnum(SeelenWegHideMode).default(SeelenWegHideMode.OnOverlap), - position: z.nativeEnum(SeelenWegSide).default(SeelenWegSide.BOTTOM), - visible_separators: z.boolean().default(true), - size: z.number().positive().default(40).describe('Item size in pixels'), - zoom_size: z.number().positive().default(70).describe('Zoomed item size in pixels'), - margin: z.number().nonnegative().default(8).describe('Dock/Bar margin in pixels'), - padding: z.number().nonnegative().default(8).describe('Dock/Bar padding in pixels'), - space_between_items: z.number().nonnegative().default(8).describe('Space between items (gap) in pixels'), -}); - -type inner = z.infer & {}; -export interface Seelenweg { - enabled: inner['enabled']; - mode: inner['mode']; - hideMode: inner['hide_mode']; - position: inner['position']; - visibleSeparators: inner['visible_separators']; - size: inner['size']; - zoomSize: inner['zoom_size']; - margin: inner['margin']; - padding: inner['padding']; - spaceBetweenItems: inner['space_between_items']; +import z from 'zod'; + +export enum SeelenWegMode { + FULL_WIDTH = 'Full-Width', + MIN_CONTENT = 'Min-Content', +} + +export enum SeelenWegHideMode { + Never = 'Never', + Always = 'Always', + OnOverlap = 'On-Overlap', +} + +export enum SeelenWegSide { + LEFT = 'Left', + RIGHT = 'Right', + TOP = 'Top', + BOTTOM = 'Bottom', +} + +export const SeelenWegSchema = z.object({ + enabled: z.boolean().default(true), + mode: z.nativeEnum(SeelenWegMode).default(SeelenWegMode.MIN_CONTENT), + hide_mode: z.nativeEnum(SeelenWegHideMode).default(SeelenWegHideMode.OnOverlap), + position: z.nativeEnum(SeelenWegSide).default(SeelenWegSide.BOTTOM), + visible_separators: z.boolean().default(true), + size: z.number().positive().default(40).describe('Item size in pixels'), + zoom_size: z.number().positive().default(70).describe('Zoomed item size in pixels'), + margin: z.number().nonnegative().default(8).describe('Dock/Bar margin in pixels'), + padding: z.number().nonnegative().default(8).describe('Dock/Bar padding in pixels'), + space_between_items: z.number().nonnegative().default(8).describe('Space between items (gap) in pixels'), +}); + +type inner = z.infer & {}; +export interface Seelenweg { + enabled: inner['enabled']; + mode: inner['mode']; + hideMode: inner['hide_mode']; + position: inner['position']; + visibleSeparators: inner['visible_separators']; + size: inner['size']; + zoomSize: inner['zoom_size']; + margin: inner['margin']; + padding: inner['padding']; + spaceBetweenItems: inner['space_between_items']; } \ No newline at end of file diff --git a/src/apps/shared/schemas/Settings.ts b/src/apps/shared/schemas/Settings.ts index 9609afc5..ffef77b5 100644 --- a/src/apps/shared/schemas/Settings.ts +++ b/src/apps/shared/schemas/Settings.ts @@ -1,110 +1,110 @@ -import { FancyToolbar, FancyToolbarSchema } from './FancyToolbar'; -import { Monitor, MonitorSchema } from './Monitors'; -import { Seelenweg, SeelenWegSchema } from './Seelenweg'; -import { WindowManager, WindowManagerSchema } from './WindowManager'; -import z from 'zod'; - -export type AhkVariables = Record; -export type AhkVar = z.infer; -export const AhkVarSchema = z.object({ - fancy: z.string(), - ahk: z.string(), -}); - -export const AhkVariablesSchema = z.object({ - // open_settings: AhkVarSchema.default({ fancy: 'Win + K', ahk: '#k' }), - // pause_wm: AhkVarSchema.default({ fancy: 'Win + Control + Alt + P', ahk: '^#!p' }), - // reservations - reserve_top: AhkVarSchema.default({ fancy: 'Win + Shift + I', ahk: '#+i' }), - reserve_bottom: AhkVarSchema.default({ fancy: 'Win + Shift + K', ahk: '#+k' }), - reserve_left: AhkVarSchema.default({ fancy: 'Win + Shift + J', ahk: '#+j' }), - reserve_right: AhkVarSchema.default({ fancy: 'Win + Shift + L', ahk: '#+l' }), - reserve_float: AhkVarSchema.default({ fancy: 'Win + Shift + U', ahk: '#+u' }), - reserve_stack: AhkVarSchema.default({ fancy: 'Win + Shift + O', ahk: '#+o' }), - // focus - focus_top: AhkVarSchema.default({ fancy: 'Win + Shift + W', ahk: '#+w' }), - focus_bottom: AhkVarSchema.default({ fancy: 'Win + Shift + S', ahk: '#+s' }), - focus_left: AhkVarSchema.default({ fancy: 'Win + Shift + A', ahk: '#+a' }), - focus_right: AhkVarSchema.default({ fancy: 'Win + Shift + D', ahk: '#+d' }), - focus_latest: AhkVarSchema.default({ fancy: 'Win + Shift + E', ahk: '#+e' }), - // window size - increase_width: AhkVarSchema.default({ fancy: 'Win + Alt + =', ahk: '#!=' }), - decrease_width: AhkVarSchema.default({ fancy: 'Win + Alt + -', ahk: '#!-' }), - increase_height: AhkVarSchema.default({ fancy: 'Win + Shift + =', ahk: '#+=' }), - decrease_height: AhkVarSchema.default({ fancy: 'Win + Shift + -', ahk: '#+-' }), - restore_sizes: AhkVarSchema.default({ fancy: 'Win + Alt + 0', ahk: '#!0' }), - // switch - switch_workspace_0: AhkVarSchema.default({ fancy: 'Alt + 1', ahk: '!1' }), - switch_workspace_1: AhkVarSchema.default({ fancy: 'Alt + 2', ahk: '!2' }), - switch_workspace_2: AhkVarSchema.default({ fancy: 'Alt + 3', ahk: '!3' }), - switch_workspace_3: AhkVarSchema.default({ fancy: 'Alt + 4', ahk: '!4' }), - switch_workspace_4: AhkVarSchema.default({ fancy: 'Alt + 5', ahk: '!5' }), - switch_workspace_5: AhkVarSchema.default({ fancy: 'Alt + 6', ahk: '!6' }), - switch_workspace_6: AhkVarSchema.default({ fancy: 'Alt + 7', ahk: '!7' }), - switch_workspace_7: AhkVarSchema.default({ fancy: 'Alt + 8', ahk: '!8' }), - switch_workspace_8: AhkVarSchema.default({ fancy: 'Alt + 9', ahk: '!9' }), - switch_workspace_9: AhkVarSchema.default({ fancy: 'Alt + 0', ahk: '!0' }), - // move - move_to_workspace_0: AhkVarSchema.default({ fancy: 'Alt + Shift + 1', ahk: '!+1' }), - move_to_workspace_1: AhkVarSchema.default({ fancy: 'Alt + Shift + 2', ahk: '!+2' }), - move_to_workspace_2: AhkVarSchema.default({ fancy: 'Alt + Shift + 3', ahk: '!+3' }), - move_to_workspace_3: AhkVarSchema.default({ fancy: 'Alt + Shift + 4', ahk: '!+4' }), - move_to_workspace_4: AhkVarSchema.default({ fancy: 'Alt + Shift + 5', ahk: '!+5' }), - move_to_workspace_5: AhkVarSchema.default({ fancy: 'Alt + Shift + 6', ahk: '!+6' }), - move_to_workspace_6: AhkVarSchema.default({ fancy: 'Alt + Shift + 7', ahk: '!+7' }), - move_to_workspace_7: AhkVarSchema.default({ fancy: 'Alt + Shift + 8', ahk: '!+8' }), - move_to_workspace_8: AhkVarSchema.default({ fancy: 'Alt + Shift + 9', ahk: '!+9' }), - move_to_workspace_9: AhkVarSchema.default({ fancy: 'Alt + Shift + 0', ahk: '!+0' }), - // send - send_to_workspace_0: AhkVarSchema.default({ fancy: 'Win + Shift + 1', ahk: '#+1' }), - send_to_workspace_1: AhkVarSchema.default({ fancy: 'Win + Shift + 2', ahk: '#+2' }), - send_to_workspace_2: AhkVarSchema.default({ fancy: 'Win + Shift + 3', ahk: '#+3' }), - send_to_workspace_3: AhkVarSchema.default({ fancy: 'Win + Shift + 4', ahk: '#+4' }), - send_to_workspace_4: AhkVarSchema.default({ fancy: 'Win + Shift + 5', ahk: '#+5' }), - send_to_workspace_5: AhkVarSchema.default({ fancy: 'Win + Shift + 6', ahk: '#+6' }), - send_to_workspace_6: AhkVarSchema.default({ fancy: 'Win + Shift + 7', ahk: '#+7' }), - send_to_workspace_7: AhkVarSchema.default({ fancy: 'Win + Shift + 8', ahk: '#+8' }), - send_to_workspace_8: AhkVarSchema.default({ fancy: 'Win + Shift + 9', ahk: '#+9' }), - send_to_workspace_9: AhkVarSchema.default({ fancy: 'Win + Shift + 0', ahk: '#+0' }), -}); - -export const SettingsSchema = z.object({ - fancy_toolbar: FancyToolbarSchema.default({}), - seelenweg: SeelenWegSchema.default({}), - window_manager: WindowManagerSchema.default({}), - monitors: z - .array(MonitorSchema) - .min(1) - .default([MonitorSchema.parse({})]), - ahk_enabled: z.boolean().default(true), - ahk_variables: AhkVariablesSchema.default({}), - selected_theme: z - .union([z.string(), z.array(z.string())]) - .transform((arg) => { - // backward compatibility with versions before 1.4.0 - if (arg === 'default.json') { - return ['default']; - } - return Array.isArray(arg) ? arg : [arg]; - }) - .default(['default']), - dev_tools: z.boolean().default(false), - language: z.string().nullable().default(() => { - if (globalThis.navigator) { - return globalThis.navigator.language.split('-')[0] || 'en'; - } - return 'en'; - }), -}); - -export interface ISettings { - fancyToolbar: FancyToolbar; - seelenweg: Seelenweg; - windowManager: WindowManager; - monitors: Monitor[]; - ahkEnabled: boolean; - ahkVariables: AhkVariables; - selectedTheme: string[]; - devTools: boolean; - language: string; -} +import { FancyToolbar, FancyToolbarSchema } from './FancyToolbar'; +import { Monitor, MonitorSchema } from './Monitors'; +import { Seelenweg, SeelenWegSchema } from './Seelenweg'; +import { WindowManager, WindowManagerSchema } from './WindowManager'; +import z from 'zod'; + +export type AhkVariables = Record; +export type AhkVar = z.infer; +export const AhkVarSchema = z.object({ + fancy: z.string(), + ahk: z.string(), +}); + +export const AhkVariablesSchema = z.object({ + // open_settings: AhkVarSchema.default({ fancy: 'Win + K', ahk: '#k' }), + // pause_wm: AhkVarSchema.default({ fancy: 'Win + Control + Alt + P', ahk: '^#!p' }), + // reservations + reserve_top: AhkVarSchema.default({ fancy: 'Win + Shift + I', ahk: '#+i' }), + reserve_bottom: AhkVarSchema.default({ fancy: 'Win + Shift + K', ahk: '#+k' }), + reserve_left: AhkVarSchema.default({ fancy: 'Win + Shift + J', ahk: '#+j' }), + reserve_right: AhkVarSchema.default({ fancy: 'Win + Shift + L', ahk: '#+l' }), + reserve_float: AhkVarSchema.default({ fancy: 'Win + Shift + U', ahk: '#+u' }), + reserve_stack: AhkVarSchema.default({ fancy: 'Win + Shift + O', ahk: '#+o' }), + // focus + focus_top: AhkVarSchema.default({ fancy: 'Win + Shift + W', ahk: '#+w' }), + focus_bottom: AhkVarSchema.default({ fancy: 'Win + Shift + S', ahk: '#+s' }), + focus_left: AhkVarSchema.default({ fancy: 'Win + Shift + A', ahk: '#+a' }), + focus_right: AhkVarSchema.default({ fancy: 'Win + Shift + D', ahk: '#+d' }), + focus_latest: AhkVarSchema.default({ fancy: 'Win + Shift + E', ahk: '#+e' }), + // window size + increase_width: AhkVarSchema.default({ fancy: 'Win + Alt + =', ahk: '#!=' }), + decrease_width: AhkVarSchema.default({ fancy: 'Win + Alt + -', ahk: '#!-' }), + increase_height: AhkVarSchema.default({ fancy: 'Win + Shift + =', ahk: '#+=' }), + decrease_height: AhkVarSchema.default({ fancy: 'Win + Shift + -', ahk: '#+-' }), + restore_sizes: AhkVarSchema.default({ fancy: 'Win + Alt + 0', ahk: '#!0' }), + // switch + switch_workspace_0: AhkVarSchema.default({ fancy: 'Alt + 1', ahk: '!1' }), + switch_workspace_1: AhkVarSchema.default({ fancy: 'Alt + 2', ahk: '!2' }), + switch_workspace_2: AhkVarSchema.default({ fancy: 'Alt + 3', ahk: '!3' }), + switch_workspace_3: AhkVarSchema.default({ fancy: 'Alt + 4', ahk: '!4' }), + switch_workspace_4: AhkVarSchema.default({ fancy: 'Alt + 5', ahk: '!5' }), + switch_workspace_5: AhkVarSchema.default({ fancy: 'Alt + 6', ahk: '!6' }), + switch_workspace_6: AhkVarSchema.default({ fancy: 'Alt + 7', ahk: '!7' }), + switch_workspace_7: AhkVarSchema.default({ fancy: 'Alt + 8', ahk: '!8' }), + switch_workspace_8: AhkVarSchema.default({ fancy: 'Alt + 9', ahk: '!9' }), + switch_workspace_9: AhkVarSchema.default({ fancy: 'Alt + 0', ahk: '!0' }), + // move + move_to_workspace_0: AhkVarSchema.default({ fancy: 'Alt + Shift + 1', ahk: '!+1' }), + move_to_workspace_1: AhkVarSchema.default({ fancy: 'Alt + Shift + 2', ahk: '!+2' }), + move_to_workspace_2: AhkVarSchema.default({ fancy: 'Alt + Shift + 3', ahk: '!+3' }), + move_to_workspace_3: AhkVarSchema.default({ fancy: 'Alt + Shift + 4', ahk: '!+4' }), + move_to_workspace_4: AhkVarSchema.default({ fancy: 'Alt + Shift + 5', ahk: '!+5' }), + move_to_workspace_5: AhkVarSchema.default({ fancy: 'Alt + Shift + 6', ahk: '!+6' }), + move_to_workspace_6: AhkVarSchema.default({ fancy: 'Alt + Shift + 7', ahk: '!+7' }), + move_to_workspace_7: AhkVarSchema.default({ fancy: 'Alt + Shift + 8', ahk: '!+8' }), + move_to_workspace_8: AhkVarSchema.default({ fancy: 'Alt + Shift + 9', ahk: '!+9' }), + move_to_workspace_9: AhkVarSchema.default({ fancy: 'Alt + Shift + 0', ahk: '!+0' }), + // send + send_to_workspace_0: AhkVarSchema.default({ fancy: 'Win + Shift + 1', ahk: '#+1' }), + send_to_workspace_1: AhkVarSchema.default({ fancy: 'Win + Shift + 2', ahk: '#+2' }), + send_to_workspace_2: AhkVarSchema.default({ fancy: 'Win + Shift + 3', ahk: '#+3' }), + send_to_workspace_3: AhkVarSchema.default({ fancy: 'Win + Shift + 4', ahk: '#+4' }), + send_to_workspace_4: AhkVarSchema.default({ fancy: 'Win + Shift + 5', ahk: '#+5' }), + send_to_workspace_5: AhkVarSchema.default({ fancy: 'Win + Shift + 6', ahk: '#+6' }), + send_to_workspace_6: AhkVarSchema.default({ fancy: 'Win + Shift + 7', ahk: '#+7' }), + send_to_workspace_7: AhkVarSchema.default({ fancy: 'Win + Shift + 8', ahk: '#+8' }), + send_to_workspace_8: AhkVarSchema.default({ fancy: 'Win + Shift + 9', ahk: '#+9' }), + send_to_workspace_9: AhkVarSchema.default({ fancy: 'Win + Shift + 0', ahk: '#+0' }), +}); + +export const SettingsSchema = z.object({ + fancy_toolbar: FancyToolbarSchema.default({}), + seelenweg: SeelenWegSchema.default({}), + window_manager: WindowManagerSchema.default({}), + monitors: z + .array(MonitorSchema) + .min(1) + .default([MonitorSchema.parse({})]), + ahk_enabled: z.boolean().default(true), + ahk_variables: AhkVariablesSchema.default({}), + selected_theme: z + .union([z.string(), z.array(z.string())]) + .transform((arg) => { + // backward compatibility with versions before 1.4.0 + if (arg === 'default.json') { + return ['default']; + } + return Array.isArray(arg) ? arg : [arg]; + }) + .default(['default']), + dev_tools: z.boolean().default(false), + language: z.string().nullable().default(() => { + if (globalThis.navigator) { + return globalThis.navigator.language.split('-')[0] || 'en'; + } + return 'en'; + }), +}); + +export interface ISettings { + fancyToolbar: FancyToolbar; + seelenweg: Seelenweg; + windowManager: WindowManager; + monitors: Monitor[]; + ahkEnabled: boolean; + ahkVariables: AhkVariables; + selectedTheme: string[]; + devTools: boolean; + language: string; +} diff --git a/src/apps/shared/schemas/Theme.ts b/src/apps/shared/schemas/Theme.ts index 13991f35..7f49bb6c 100644 --- a/src/apps/shared/schemas/Theme.ts +++ b/src/apps/shared/schemas/Theme.ts @@ -1,15 +1,15 @@ -import { CreatorInfoSchema } from '.'; -import { z } from 'zod'; - -export const ThemeSchema = z.object({ - info: CreatorInfoSchema.extend({ - tags: z.array(z.string()), - }), - styles: z.object({ - weg: z.string(), - toolbar: z.string(), - wm: z.string(), - }), -}); - -export interface Theme extends z.infer {} +import { CreatorInfoSchema } from '.'; +import { z } from 'zod'; + +export const ThemeSchema = z.object({ + info: CreatorInfoSchema.extend({ + tags: z.array(z.string()), + }), + styles: z.object({ + weg: z.string(), + toolbar: z.string(), + wm: z.string(), + }), +}); + +export interface Theme extends z.infer {} diff --git a/src/apps/shared/schemas/WindowManager.ts b/src/apps/shared/schemas/WindowManager.ts index 8271eb79..063bc6e7 100644 --- a/src/apps/shared/schemas/WindowManager.ts +++ b/src/apps/shared/schemas/WindowManager.ts @@ -1,47 +1,47 @@ -import z from 'zod'; - -export type Rect = z.infer; -export const RectSchema = z.object({ - top: z.number().default(0), - left: z.number().default(0), - right: z.number().default(0), - bottom: z.number().default(0), -}); - -export type Border = z.infer; -export const BorderSchema = z.object({ - enabled: z.boolean().default(true), - width: z.number().min(0).default(3), - offset: z.number().default(-1), -}); - -export type FloatingWindowSettings = z.infer; -export const FloatingWindowSchema = z.object({ - width: z.number().positive().default(800), - height: z.number().positive().default(500), -}); - -export const WindowManagerSchema = z.object({ - enabled: z.boolean().default(false), - auto_stacking_by_category: z.boolean().default(true), - border: BorderSchema.default({}), - resize_delta: z.number().default(10).describe('% to add or remove on resize of windows using the CLI'), - workspace_gap: z.number().nonnegative().default(10).describe('Space between windows'), - workspace_padding: z.number().nonnegative().default(10), - global_work_area_offset: RectSchema.default({}), - floating: FloatingWindowSchema.default({}), - default_layout: z.string().nullable().default(null), -}); - -type inner = z.infer & {}; -export interface WindowManager { - enabled: inner['enabled']; - autoStackingByCategory: inner['auto_stacking_by_category']; - border: inner['border']; - resizeDelta: inner['resize_delta']; - workspaceGap: inner['workspace_gap']; - workspacePadding: inner['workspace_padding']; - globalWorkAreaOffset: inner['global_work_area_offset']; - floating: inner['floating']; - defaultLayout: inner['default_layout']; +import z from 'zod'; + +export type Rect = z.infer; +export const RectSchema = z.object({ + top: z.number().default(0), + left: z.number().default(0), + right: z.number().default(0), + bottom: z.number().default(0), +}); + +export type Border = z.infer; +export const BorderSchema = z.object({ + enabled: z.boolean().default(true), + width: z.number().min(0).default(3), + offset: z.number().default(-1), +}); + +export type FloatingWindowSettings = z.infer; +export const FloatingWindowSchema = z.object({ + width: z.number().positive().default(800), + height: z.number().positive().default(500), +}); + +export const WindowManagerSchema = z.object({ + enabled: z.boolean().default(false), + auto_stacking_by_category: z.boolean().default(true), + border: BorderSchema.default({}), + resize_delta: z.number().default(10).describe('% to add or remove on resize of windows using the CLI'), + workspace_gap: z.number().nonnegative().default(10).describe('Space between windows'), + workspace_padding: z.number().nonnegative().default(10), + global_work_area_offset: RectSchema.default({}), + floating: FloatingWindowSchema.default({}), + default_layout: z.string().nullable().default(null), +}); + +type inner = z.infer & {}; +export interface WindowManager { + enabled: inner['enabled']; + autoStackingByCategory: inner['auto_stacking_by_category']; + border: inner['border']; + resizeDelta: inner['resize_delta']; + workspaceGap: inner['workspace_gap']; + workspacePadding: inner['workspace_padding']; + globalWorkAreaOffset: inner['global_work_area_offset']; + floating: inner['floating']; + defaultLayout: inner['default_layout']; } \ No newline at end of file diff --git a/src/apps/shared/schemas/index.test.ts b/src/apps/shared/schemas/index.test.ts index 37985f88..141b1b0e 100644 --- a/src/apps/shared/schemas/index.test.ts +++ b/src/apps/shared/schemas/index.test.ts @@ -1,59 +1,59 @@ -import { VariableConvention } from '.'; - -describe('VariableConvention', () => { - test('snakeToCamel', () => { - expect(VariableConvention.snakeToCamel('hello_world')).toBe('helloWorld'); - expect(VariableConvention.snakeToCamel('testing_snake_case_text')).toBe('testingSnakeCaseText'); - expect(VariableConvention.snakeToCamel('hello_world_1_2_3')).toBe('helloWorld123'); - }); - - test('camelToSnake', () => { - expect(VariableConvention.camelToSnake('HelloWorld')).toBe('hello_world'); - expect(VariableConvention.camelToSnake('helloWorld')).toBe('hello_world'); - expect(VariableConvention.camelToSnake('testingSnakeCaseText')).toBe('testing_snake_case_text'); - expect(VariableConvention.camelToSnake('helloWorld123')).toBe('hello_world_1_2_3'); - }); - - test('deepKeyParser', () => { - const camelObject = [ - { - helloWorld: { - myWorld: 123, - }, - testing: { - camelCase: { - deepCamelCase: 'text', - }, - arrayCamelCase: [ - { - deepCamelCase0: 'text', - }, - 'text', - ], - }, - }, - ]; - - const snakeObject = [ - { - hello_world: { - my_world: 123, - }, - testing: { - camel_case: { - deep_camel_case: 'text', - }, - array_camel_case: [ - { - deep_camel_case_0: 'text', - }, - 'text', - ], - }, - }, - ]; - - expect(VariableConvention.deepKeyParser(camelObject, VariableConvention.camelToSnake)).toEqual(snakeObject); - expect(VariableConvention.deepKeyParser(snakeObject, VariableConvention.snakeToCamel)).toEqual(camelObject); - }); -}); +import { VariableConvention } from '.'; + +describe('VariableConvention', () => { + test('snakeToCamel', () => { + expect(VariableConvention.snakeToCamel('hello_world')).toBe('helloWorld'); + expect(VariableConvention.snakeToCamel('testing_snake_case_text')).toBe('testingSnakeCaseText'); + expect(VariableConvention.snakeToCamel('hello_world_1_2_3')).toBe('helloWorld123'); + }); + + test('camelToSnake', () => { + expect(VariableConvention.camelToSnake('HelloWorld')).toBe('hello_world'); + expect(VariableConvention.camelToSnake('helloWorld')).toBe('hello_world'); + expect(VariableConvention.camelToSnake('testingSnakeCaseText')).toBe('testing_snake_case_text'); + expect(VariableConvention.camelToSnake('helloWorld123')).toBe('hello_world_1_2_3'); + }); + + test('deepKeyParser', () => { + const camelObject = [ + { + helloWorld: { + myWorld: 123, + }, + testing: { + camelCase: { + deepCamelCase: 'text', + }, + arrayCamelCase: [ + { + deepCamelCase0: 'text', + }, + 'text', + ], + }, + }, + ]; + + const snakeObject = [ + { + hello_world: { + my_world: 123, + }, + testing: { + camel_case: { + deep_camel_case: 'text', + }, + array_camel_case: [ + { + deep_camel_case_0: 'text', + }, + 'text', + ], + }, + }, + ]; + + expect(VariableConvention.deepKeyParser(camelObject, VariableConvention.camelToSnake)).toEqual(snakeObject); + expect(VariableConvention.deepKeyParser(snakeObject, VariableConvention.snakeToCamel)).toEqual(camelObject); + }); +}); diff --git a/src/apps/shared/schemas/index.ts b/src/apps/shared/schemas/index.ts index d7c3e083..9c54cdfa 100644 --- a/src/apps/shared/schemas/index.ts +++ b/src/apps/shared/schemas/index.ts @@ -1,88 +1,88 @@ -import z from 'zod'; - -export class VariableConvention { - static snakeToCamel(text: string) { - let camel = ''; - let prevCharIsDash = false; - for (const char of text.split('')) { - if (char === '_') { - prevCharIsDash = true; - continue; - } - if (prevCharIsDash) { - camel += char.toUpperCase(); - prevCharIsDash = false; - } else { - camel += char; - } - } - return camel; - } - - static camelToSnake(text: string) { - let snake = ''; - for (let i = 0; i < text.length; i++) { - const char = text[i]!; - if ((char === char.toLowerCase() && !char.match(/[0-9]/)) || i === 0) { - snake += char.toLowerCase(); - } else { - snake += `_${char.toLowerCase()}`; - } - } - return snake; - } - - static camelToUser(text: string) { - return VariableConvention.camelToSnake(text).replace(/_/g, ' '); - } - - static deepKeyParser(obj: anyObject, parser: (text: string) => string): anyObject { - if (Array.isArray(obj)) { - return obj.map((x) => { - if (typeof x === 'object' && x != null) { - return VariableConvention.deepKeyParser(x, parser); - } - return x; - }); - } - - let newObj = {} as anyObject; - for (const key in obj) { - const value = obj[key]; - if (typeof value === 'object' && value != null) { - newObj[parser(key)] = VariableConvention.deepKeyParser(value, parser); - } else { - newObj[parser(key)] = value; - } - } - return newObj; - } - - static fromSnakeToCamel(value: any): any { - return VariableConvention.deepKeyParser(value, VariableConvention.snakeToCamel); - } - - static fromCamelToSnake(value: any): any { - return VariableConvention.deepKeyParser(value, VariableConvention.camelToSnake); - } -} - -export function parseAsCamel(schema: z.Schema, value: any) { - return VariableConvention.fromSnakeToCamel(schema.parse(value)); -} - -export function safeParseAsCamel(schema: z.Schema, value: any) { - let result = schema.safeParse(value); - if (result.error) { - console.error(result.error); - return; - } - return VariableConvention.fromSnakeToCamel(result.data); -} - -export const CreatorInfoSchema = z.object({ - displayName: z.string().default('Unknown'), - author: z.string().default('Unknown'), - description: z.string().default('Empty'), - filename: z.string().default(''), -}); +import z from 'zod'; + +export class VariableConvention { + static snakeToCamel(text: string) { + let camel = ''; + let prevCharIsDash = false; + for (const char of text.split('')) { + if (char === '_') { + prevCharIsDash = true; + continue; + } + if (prevCharIsDash) { + camel += char.toUpperCase(); + prevCharIsDash = false; + } else { + camel += char; + } + } + return camel; + } + + static camelToSnake(text: string) { + let snake = ''; + for (let i = 0; i < text.length; i++) { + const char = text[i]!; + if ((char === char.toLowerCase() && !char.match(/[0-9]/)) || i === 0) { + snake += char.toLowerCase(); + } else { + snake += `_${char.toLowerCase()}`; + } + } + return snake; + } + + static camelToUser(text: string) { + return VariableConvention.camelToSnake(text).replace(/_/g, ' '); + } + + static deepKeyParser(obj: anyObject, parser: (text: string) => string): anyObject { + if (Array.isArray(obj)) { + return obj.map((x) => { + if (typeof x === 'object' && x != null) { + return VariableConvention.deepKeyParser(x, parser); + } + return x; + }); + } + + let newObj = {} as anyObject; + for (const key in obj) { + const value = obj[key]; + if (typeof value === 'object' && value != null) { + newObj[parser(key)] = VariableConvention.deepKeyParser(value, parser); + } else { + newObj[parser(key)] = value; + } + } + return newObj; + } + + static fromSnakeToCamel(value: any): any { + return VariableConvention.deepKeyParser(value, VariableConvention.snakeToCamel); + } + + static fromCamelToSnake(value: any): any { + return VariableConvention.deepKeyParser(value, VariableConvention.camelToSnake); + } +} + +export function parseAsCamel(schema: z.Schema, value: any) { + return VariableConvention.fromSnakeToCamel(schema.parse(value)); +} + +export function safeParseAsCamel(schema: z.Schema, value: any) { + let result = schema.safeParse(value); + if (result.error) { + console.error(result.error); + return; + } + return VariableConvention.fromSnakeToCamel(result.data); +} + +export const CreatorInfoSchema = z.object({ + displayName: z.string().default('Unknown'), + author: z.string().default('Unknown'), + description: z.string().default('Empty'), + filename: z.string().default(''), +}); diff --git a/src/apps/shared/styles.ts b/src/apps/shared/styles.ts index 2d109128..876a0230 100644 --- a/src/apps/shared/styles.ts +++ b/src/apps/shared/styles.ts @@ -1,40 +1,40 @@ -import { useEffect, useState } from 'react'; - -type Args = undefined | string | { [x: string]: any }; -export const cx = (...args: Args[]): string => { - return args - .map((arg) => { - if (!arg) { - return; - } - - if (typeof arg === 'string') { - return arg; - } - - let classnames = ''; - Object.keys(arg).forEach((key) => { - if (arg[key]) { - classnames += ` ${key}`; - } - }); - - return classnames.trimStart(); - }) - .join(' '); -}; - -export function useDarkMode() { - const [isDarkMode, setIsDarkMode] = useState( - window.matchMedia('(prefers-color-scheme: dark)').matches, - ); - - useEffect(() => { - const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); - const listener = () => setIsDarkMode(mediaQuery.matches); - mediaQuery.addEventListener('change', listener); - return () => mediaQuery.removeEventListener('change', listener); - }); - - return isDarkMode; -} +import { useEffect, useState } from 'react'; + +type Args = undefined | string | { [x: string]: any }; +export const cx = (...args: Args[]): string => { + return args + .map((arg) => { + if (!arg) { + return; + } + + if (typeof arg === 'string') { + return arg; + } + + let classnames = ''; + Object.keys(arg).forEach((key) => { + if (arg[key]) { + classnames += ` ${key}`; + } + }); + + return classnames.trimStart(); + }) + .join(' '); +}; + +export function useDarkMode() { + const [isDarkMode, setIsDarkMode] = useState( + window.matchMedia('(prefers-color-scheme: dark)').matches, + ); + + useEffect(() => { + const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); + const listener = () => setIsDarkMode(mediaQuery.matches); + mediaQuery.addEventListener('change', listener); + return () => mediaQuery.removeEventListener('change', listener); + }); + + return isDarkMode; +} diff --git a/src/apps/toolbar-hitbox/index.css b/src/apps/toolbar-hitbox/index.css index 02e5fc25..5e39916e 100644 --- a/src/apps/toolbar-hitbox/index.css +++ b/src/apps/toolbar-hitbox/index.css @@ -1,12 +1,12 @@ -*, *:after, *:before { - margin: 0; - padding: 0; - border: 0; - outline: none; - box-sizing: border-box; - vertical-align: baseline; -} - -/* body { - background: red; +*, *:after, *:before { + margin: 0; + padding: 0; + border: 0; + outline: none; + box-sizing: border-box; + vertical-align: baseline; +} + +/* body { + background: red; } */ \ No newline at end of file diff --git a/src/apps/toolbar-hitbox/index.html b/src/apps/toolbar-hitbox/index.html index aa458273..5a3e45d6 100644 --- a/src/apps/toolbar-hitbox/index.html +++ b/src/apps/toolbar-hitbox/index.html @@ -1,8 +1,8 @@ - - - - - - - - + + + + + + + + diff --git a/src/apps/toolbar-hitbox/index.tsx b/src/apps/toolbar-hitbox/index.tsx index 8585cc6a..10808e47 100644 --- a/src/apps/toolbar-hitbox/index.tsx +++ b/src/apps/toolbar-hitbox/index.tsx @@ -1,44 +1,44 @@ -import { wrapConsole } from '../shared/ConsoleWrapper'; -import { invoke } from '@tauri-apps/api/core'; -import { emitTo } from '@tauri-apps/api/event'; -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; - -import './index.css'; - -async function Main() { - wrapConsole(); - let view = getCurrentWebviewWindow(); - let main = view.label.replace('-hitbox', ''); - - view.listen('init', async () => { - await getCurrentWebviewWindow().show(); - - async function onClick(e: MouseEvent | TouchEvent) { - invoke('ensure_hitboxes_zorder').catch(console.error); - - let x = 0; - let y = 0; - if (e instanceof MouseEvent) { - x = e.clientX; - y = e.clientY; - emitTo(main, 'click', { x, y }); - return; - } - - if (e.touches && e.touches.length > 0) { - x = e.touches[0]?.clientX || 0; - y = e.touches[0]?.clientY || 0; - emitTo(main, 'click', { x, y }); - } - } - - document.body.addEventListener('mouseenter', () => { - emitTo(main, 'mouseenter'); - invoke('ensure_hitboxes_zorder').catch(console.error); - }); - document.body.addEventListener('click', onClick); - document.body.addEventListener('touchend', onClick); - }); -} - -Main(); +import { wrapConsole } from '../shared/ConsoleWrapper'; +import { invoke } from '@tauri-apps/api/core'; +import { emitTo } from '@tauri-apps/api/event'; +import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; + +import './index.css'; + +async function Main() { + wrapConsole(); + let view = getCurrentWebviewWindow(); + let main = view.label.replace('-hitbox', ''); + + view.listen('init', async () => { + await getCurrentWebviewWindow().show(); + + async function onClick(e: MouseEvent | TouchEvent) { + invoke('ensure_hitboxes_zorder').catch(console.error); + + let x = 0; + let y = 0; + if (e instanceof MouseEvent) { + x = e.clientX; + y = e.clientY; + emitTo(main, 'click', { x, y }); + return; + } + + if (e.touches && e.touches.length > 0) { + x = e.touches[0]?.clientX || 0; + y = e.touches[0]?.clientY || 0; + emitTo(main, 'click', { x, y }); + } + } + + document.body.addEventListener('mouseenter', () => { + emitTo(main, 'mouseenter'); + invoke('ensure_hitboxes_zorder').catch(console.error); + }); + document.body.addEventListener('click', onClick); + document.body.addEventListener('touchend', onClick); + }); +} + +Main(); diff --git a/src/apps/toolbar/app.tsx b/src/apps/toolbar/app.tsx index ab4185df..c775ab00 100644 --- a/src/apps/toolbar/app.tsx +++ b/src/apps/toolbar/app.tsx @@ -1,53 +1,53 @@ -import { ErrorBoundary } from '../seelenweg/components/Error'; -import { getRootContainer } from '../shared'; -import { useDarkMode } from '../shared/styles'; -import { ErrorFallback } from './components/Error'; -import { emit, emitTo } from '@tauri-apps/api/event'; -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; -import { ConfigProvider, theme } from 'antd'; -import { useEffect } from 'react'; -import { useSelector } from 'react-redux'; - -import { ToolBar } from './modules/main/infra'; - -import { Selectors } from './modules/shared/store/app'; - -async function onMount() { - let view = getCurrentWebviewWindow(); - await emitTo(view.label.replace('/', '-hitbox/'), 'init'); - await view.show(); - await emit('register-colors-events'); -} - -export function App() { - const version = useSelector(Selectors.version); - - const structure = useSelector(Selectors.placeholder); - const colors = useSelector(Selectors.colors); - - const isDarkMode = useDarkMode(); - - useEffect(() => { - onMount().catch(console.error); - }, []); - - if (!structure) { - return ; - } - - return ( - getRootContainer()} - theme={{ - token: { - colorPrimary: isDarkMode ? colors.accent_light : colors.accent_dark, - }, - algorithm: isDarkMode ? theme.darkAlgorithm : theme.defaultAlgorithm, - }} - > - }> - - - - ); -} +import { ErrorBoundary } from '../seelenweg/components/Error'; +import { getRootContainer } from '../shared'; +import { useDarkMode } from '../shared/styles'; +import { ErrorFallback } from './components/Error'; +import { emit, emitTo } from '@tauri-apps/api/event'; +import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; +import { ConfigProvider, theme } from 'antd'; +import { useEffect } from 'react'; +import { useSelector } from 'react-redux'; + +import { ToolBar } from './modules/main/infra'; + +import { Selectors } from './modules/shared/store/app'; + +async function onMount() { + let view = getCurrentWebviewWindow(); + await emitTo(view.label.replace('/', '-hitbox/'), 'init'); + await view.show(); + await emit('register-colors-events'); +} + +export function App() { + const version = useSelector(Selectors.version); + + const structure = useSelector(Selectors.placeholder); + const colors = useSelector(Selectors.colors); + + const isDarkMode = useDarkMode(); + + useEffect(() => { + onMount().catch(console.error); + }, []); + + if (!structure) { + return ; + } + + return ( + getRootContainer()} + theme={{ + token: { + colorPrimary: isDarkMode ? colors.accent_light : colors.accent_dark, + }, + algorithm: isDarkMode ? theme.darkAlgorithm : theme.defaultAlgorithm, + }} + > + }> + + + + ); +} diff --git a/src/apps/toolbar/components/Error/index.module.css b/src/apps/toolbar/components/Error/index.module.css index a99accb8..c3203a84 100644 --- a/src/apps/toolbar/components/Error/index.module.css +++ b/src/apps/toolbar/components/Error/index.module.css @@ -1,8 +1,8 @@ -.error { - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: var(--config-height); - background-color: var(--color-blue-800); +.error { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: var(--config-height); + background-color: var(--color-blue-800); } \ No newline at end of file diff --git a/src/apps/toolbar/components/Error/index.tsx b/src/apps/toolbar/components/Error/index.tsx index 7bf42f1e..e4f9cbdf 100644 --- a/src/apps/toolbar/components/Error/index.tsx +++ b/src/apps/toolbar/components/Error/index.tsx @@ -1,9 +1,9 @@ -import cs from './index.module.css'; - -interface Props { - msg?: string; -} - -export function ErrorFallback({ msg = 'Something went wrong' }: Props) { - return
{msg}
; -} +import cs from './index.module.css'; + +interface Props { + msg?: string; +} + +export function ErrorFallback({ msg = 'Something went wrong' }: Props) { + return
{msg}
; +} diff --git a/src/apps/toolbar/events.ts b/src/apps/toolbar/events.ts index 573408a0..d5932d0e 100644 --- a/src/apps/toolbar/events.ts +++ b/src/apps/toolbar/events.ts @@ -1,48 +1,48 @@ -import { debounce, TimeoutIdRef } from '../shared/Timing'; -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; - -import { CallbacksManager } from './modules/shared/utils/app'; - -export const ExtraCallbacksOnLeave = new CallbacksManager(); -export const ExtraCallbacksOnActivate = new CallbacksManager(); - -export function registerDocumentEvents(container: HTMLElement) { - const timeoutId: TimeoutIdRef = { current: null }; - const webview = getCurrentWebviewWindow(); - - const onMouseLeave = debounce( - () => { - webview.setIgnoreCursorEvents(true); - ExtraCallbacksOnLeave.execute(); - }, - 200, - timeoutId, - ); - - const onMouseEnter = () => { - if (timeoutId.current) { - clearTimeout(timeoutId.current); - } - webview.setIgnoreCursorEvents(false); - ExtraCallbacksOnActivate.execute(); - }; - - container.addEventListener('mouseleave', onMouseLeave); - // if for some reazon mouseleave is not emitted - // set ignore cursor events when user click on screen - document.body.addEventListener('click', (event) => { - if (event.target === document.body) { - onMouseLeave(); - } - }); - - container.addEventListener('mouseenter', onMouseEnter); - webview.listen('mouseenter', onMouseEnter); // listener for hitbox - - webview.listen<{ x: number; y: number }>('click', (event) => { - let element = document.elementFromPoint(event.payload.x, event.payload.y); - if (element && 'click' in element && typeof element.click === 'function') { - element.click(); - } - }); -} +import { debounce, TimeoutIdRef } from '../shared/Timing'; +import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; + +import { CallbacksManager } from './modules/shared/utils/app'; + +export const ExtraCallbacksOnLeave = new CallbacksManager(); +export const ExtraCallbacksOnActivate = new CallbacksManager(); + +export function registerDocumentEvents(container: HTMLElement) { + const timeoutId: TimeoutIdRef = { current: null }; + const webview = getCurrentWebviewWindow(); + + const onMouseLeave = debounce( + () => { + webview.setIgnoreCursorEvents(true); + ExtraCallbacksOnLeave.execute(); + }, + 200, + timeoutId, + ); + + const onMouseEnter = () => { + if (timeoutId.current) { + clearTimeout(timeoutId.current); + } + webview.setIgnoreCursorEvents(false); + ExtraCallbacksOnActivate.execute(); + }; + + container.addEventListener('mouseleave', onMouseLeave); + // if for some reazon mouseleave is not emitted + // set ignore cursor events when user click on screen + document.body.addEventListener('click', (event) => { + if (event.target === document.body) { + onMouseLeave(); + } + }); + + container.addEventListener('mouseenter', onMouseEnter); + webview.listen('mouseenter', onMouseEnter); // listener for hitbox + + webview.listen<{ x: number; y: number }>('click', (event) => { + let element = document.elementFromPoint(event.payload.x, event.payload.y); + if (element && 'click' in element && typeof element.click === 'function') { + element.click(); + } + }); +} diff --git a/src/apps/toolbar/i18n/index.ts b/src/apps/toolbar/i18n/index.ts index 5779f454..36e91f97 100644 --- a/src/apps/toolbar/i18n/index.ts +++ b/src/apps/toolbar/i18n/index.ts @@ -1,98 +1,98 @@ -import { Lang } from '../../shared/lang'; -import i18n from 'i18next'; -import yaml from 'js-yaml'; -import { initReactI18next } from 'react-i18next'; - -i18n.use(initReactI18next).init( - { - lng: 'en', - fallbackLng: 'en', - interpolation: { - escapeValue: false, - }, - debug: true, - resources: {}, - }, - undefined, -); - -export async function loadTranslations() { - const translations: Record = { - en: await import('./translations/en.yml'), - es: await import('./translations/es.yml'), - de: await import('./translations/de.yml'), - zh: await import('./translations/zh.yml'), - ko: await import('./translations/ko.yml'), - fr: await import('./translations/fr.yml'), - ar: await import('./translations/ar.yml'), - ru: await import('./translations/ru.yml'), - hi: await import('./translations/hi.yml'), - ja: await import('./translations/ja.yml'), - pt: await import('./translations/pt.yml'), - it: await import('./translations/it.yml'), - nl: await import('./translations/nl.yml'), - tr: await import('./translations/tr.yml'), - pl: await import('./translations/pl.yml'), - uk: await import('./translations/uk.yml'), - id: await import('./translations/id.yml'), - cs: await import('./translations/cs.yml'), - th: await import('./translations/th.yml'), - vi: await import('./translations/vi.yml'), - ms: await import('./translations/ms.yml'), - he: await import('./translations/he.yml'), - ro: await import('./translations/ro.yml'), - el: await import('./translations/el.yml'), - sv: await import('./translations/sv.yml'), - no: await import('./translations/no.yml'), - fi: await import('./translations/fi.yml'), - da: await import('./translations/da.yml'), - hu: await import('./translations/hu.yml'), - lt: await import('./translations/lt.yml'), - bg: await import('./translations/bg.yml'), - sk: await import('./translations/sk.yml'), - hr: await import('./translations/hr.yml'), - lv: await import('./translations/lv.yml'), - et: await import('./translations/et.yml'), - tl: await import('./translations/tl.yml'), - ca: await import('./translations/ca.yml'), - af: await import('./translations/af.yml'), - bn: await import('./translations/bn.yml'), - fa: await import('./translations/fa.yml'), - pa: await import('./translations/pa.yml'), - sw: await import('./translations/sw.yml'), - ta: await import('./translations/ta.yml'), - ur: await import('./translations/ur.yml'), - cy: await import('./translations/cy.yml'), - am: await import('./translations/am.yml'), - hy: await import('./translations/hy.yml'), - az: await import('./translations/az.yml'), - eu: await import('./translations/eu.yml'), - bs: await import('./translations/bs.yml'), - ka: await import('./translations/ka.yml'), - gu: await import('./translations/gu.yml'), - is: await import('./translations/is.yml'), - km: await import('./translations/km.yml'), - ku: await import('./translations/ku.yml'), - lo: await import('./translations/lo.yml'), - lb: await import('./translations/lb.yml'), - mk: await import('./translations/mk.yml'), - mt: await import('./translations/mt.yml'), - mn: await import('./translations/mn.yml'), - ne: await import('./translations/ne.yml'), - ps: await import('./translations/ps.yml'), - sr: await import('./translations/sr.yml'), - si: await import('./translations/si.yml'), - so: await import('./translations/so.yml'), - tg: await import('./translations/tg.yml'), - te: await import('./translations/te.yml'), - uz: await import('./translations/uz.yml'), - yo: await import('./translations/yo.yml'), - zu: await import('./translations/zu.yml'), - }; - - for (const [key, value] of Object.entries(translations)) { - i18n.addResourceBundle(key, 'translation', yaml.load(value.default)); - } -} - -export default i18n; +import { Lang } from '../../shared/lang'; +import i18n from 'i18next'; +import yaml from 'js-yaml'; +import { initReactI18next } from 'react-i18next'; + +i18n.use(initReactI18next).init( + { + lng: 'en', + fallbackLng: 'en', + interpolation: { + escapeValue: false, + }, + debug: true, + resources: {}, + }, + undefined, +); + +export async function loadTranslations() { + const translations: Record = { + en: await import('./translations/en.yml'), + es: await import('./translations/es.yml'), + de: await import('./translations/de.yml'), + zh: await import('./translations/zh.yml'), + ko: await import('./translations/ko.yml'), + fr: await import('./translations/fr.yml'), + ar: await import('./translations/ar.yml'), + ru: await import('./translations/ru.yml'), + hi: await import('./translations/hi.yml'), + ja: await import('./translations/ja.yml'), + pt: await import('./translations/pt.yml'), + it: await import('./translations/it.yml'), + nl: await import('./translations/nl.yml'), + tr: await import('./translations/tr.yml'), + pl: await import('./translations/pl.yml'), + uk: await import('./translations/uk.yml'), + id: await import('./translations/id.yml'), + cs: await import('./translations/cs.yml'), + th: await import('./translations/th.yml'), + vi: await import('./translations/vi.yml'), + ms: await import('./translations/ms.yml'), + he: await import('./translations/he.yml'), + ro: await import('./translations/ro.yml'), + el: await import('./translations/el.yml'), + sv: await import('./translations/sv.yml'), + no: await import('./translations/no.yml'), + fi: await import('./translations/fi.yml'), + da: await import('./translations/da.yml'), + hu: await import('./translations/hu.yml'), + lt: await import('./translations/lt.yml'), + bg: await import('./translations/bg.yml'), + sk: await import('./translations/sk.yml'), + hr: await import('./translations/hr.yml'), + lv: await import('./translations/lv.yml'), + et: await import('./translations/et.yml'), + tl: await import('./translations/tl.yml'), + ca: await import('./translations/ca.yml'), + af: await import('./translations/af.yml'), + bn: await import('./translations/bn.yml'), + fa: await import('./translations/fa.yml'), + pa: await import('./translations/pa.yml'), + sw: await import('./translations/sw.yml'), + ta: await import('./translations/ta.yml'), + ur: await import('./translations/ur.yml'), + cy: await import('./translations/cy.yml'), + am: await import('./translations/am.yml'), + hy: await import('./translations/hy.yml'), + az: await import('./translations/az.yml'), + eu: await import('./translations/eu.yml'), + bs: await import('./translations/bs.yml'), + ka: await import('./translations/ka.yml'), + gu: await import('./translations/gu.yml'), + is: await import('./translations/is.yml'), + km: await import('./translations/km.yml'), + ku: await import('./translations/ku.yml'), + lo: await import('./translations/lo.yml'), + lb: await import('./translations/lb.yml'), + mk: await import('./translations/mk.yml'), + mt: await import('./translations/mt.yml'), + mn: await import('./translations/mn.yml'), + ne: await import('./translations/ne.yml'), + ps: await import('./translations/ps.yml'), + sr: await import('./translations/sr.yml'), + si: await import('./translations/si.yml'), + so: await import('./translations/so.yml'), + tg: await import('./translations/tg.yml'), + te: await import('./translations/te.yml'), + uz: await import('./translations/uz.yml'), + yo: await import('./translations/yo.yml'), + zu: await import('./translations/zu.yml'), + }; + + for (const [key, value] of Object.entries(translations)) { + i18n.addResourceBundle(key, 'translation', yaml.load(value.default)); + } +} + +export default i18n; diff --git a/src/apps/toolbar/i18n/translations/af.yml b/src/apps/toolbar/i18n/translations/af.yml index b8c9d648..9faa932c 100644 --- a/src/apps/toolbar/i18n/translations/af.yml +++ b/src/apps/toolbar/i18n/translations/af.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedia - comunications: Kommunikasie - input_device: Insetapparaat - players: Mediaspelers - output_device: Uitsettoestel - master_volume: Meestervolume -network: - placeholder: - password: Wagwoord - not_found: Geen netwerke gevind nie - disconnect: Afsluit ?? - hidden: Verborge netwerk - connect: Konnekteer - more: Meer netwerkinstellings -settings: - restart: Begin oor - log_out: Teken uit - shutdown: Stilstand - title: Instellings - app_settings: Appinstellings - sleep: Slaap -placeholder: - ethernet_connected: toegang tot die internet - battery_remaining: '% oorblywende' - smart_charge: '- Slim lading' - settings: Vinnige instellings - ethernet_disconnected: Geen internettoegang nie - bluetooth_devices: Bluetooth & toestelle - volume: Volume - open_user_folder: Open gebruikersmap - open_system_tray: Oop stelselbak - notifications: Kennisgewings +media: + device: + multimedia: Multimedia + comunications: Kommunikasie + input_device: Insetapparaat + players: Mediaspelers + output_device: Uitsettoestel + master_volume: Meestervolume +network: + placeholder: + password: Wagwoord + not_found: Geen netwerke gevind nie + disconnect: Afsluit ?? + hidden: Verborge netwerk + connect: Konnekteer + more: Meer netwerkinstellings +settings: + restart: Begin oor + log_out: Teken uit + shutdown: Stilstand + title: Instellings + app_settings: Appinstellings + sleep: Slaap +placeholder: + ethernet_connected: toegang tot die internet + battery_remaining: '% oorblywende' + smart_charge: '- Slim lading' + settings: Vinnige instellings + ethernet_disconnected: Geen internettoegang nie + bluetooth_devices: Bluetooth & toestelle + volume: Volume + open_user_folder: Open gebruikersmap + open_system_tray: Oop stelselbak + notifications: Kennisgewings diff --git a/src/apps/toolbar/i18n/translations/am.yml b/src/apps/toolbar/i18n/translations/am.yml index ab17e758..5e92d83b 100644 --- a/src/apps/toolbar/i18n/translations/am.yml +++ b/src/apps/toolbar/i18n/translations/am.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: መልቲሚዲያ - comunications: ግንኙነቶች - output_device: የውጤት መሣሪያ - input_device: የግቤት መሣሪያ - players: የሚዲያ ተጫዋቾች - master_volume: ዋና መጠን -network: - placeholder: - password: የይለፍ ቃል - disconnect: ያላቅቁ - hidden: የተደበቀ አውታረመረብ - more: ተጨማሪ የአውታረ መረብ ቅንብሮች - not_found: ምንም አውታረመረቦች አልተገኙም - connect: አገናኝ -settings: - restart: እንደገና ጀምር - title: ቅንብሮች - shutdown: ዝጋው - log_out: ውጣ - app_settings: የመተግበሪያ ቅንጅቶች - sleep: እንቅልፍ -placeholder: - smart_charge: '- ዘመናዊ ክፍያ' - open_system_tray: ክፍት የስርዓት ትሪ - open_user_folder: የተከፈተ የተጠቃሚ አቃፊ - ethernet_connected: የበይነመረብ መዳረሻ - volume: ድምጽ - bluetooth_devices: ብሉቱዝ እና መሣሪያዎች - ethernet_disconnected: ምንም የበይነመረብ ግንኙነት የለም - settings: ፈጣን ቅንብሮች - battery_remaining: '% ይቀራል' - notifications: ማሳወቂያዎች +media: + device: + multimedia: መልቲሚዲያ + comunications: ግንኙነቶች + output_device: የውጤት መሣሪያ + input_device: የግቤት መሣሪያ + players: የሚዲያ ተጫዋቾች + master_volume: ዋና መጠን +network: + placeholder: + password: የይለፍ ቃል + disconnect: ያላቅቁ + hidden: የተደበቀ አውታረመረብ + more: ተጨማሪ የአውታረ መረብ ቅንብሮች + not_found: ምንም አውታረመረቦች አልተገኙም + connect: አገናኝ +settings: + restart: እንደገና ጀምር + title: ቅንብሮች + shutdown: ዝጋው + log_out: ውጣ + app_settings: የመተግበሪያ ቅንጅቶች + sleep: እንቅልፍ +placeholder: + smart_charge: '- ዘመናዊ ክፍያ' + open_system_tray: ክፍት የስርዓት ትሪ + open_user_folder: የተከፈተ የተጠቃሚ አቃፊ + ethernet_connected: የበይነመረብ መዳረሻ + volume: ድምጽ + bluetooth_devices: ብሉቱዝ እና መሣሪያዎች + ethernet_disconnected: ምንም የበይነመረብ ግንኙነት የለም + settings: ፈጣን ቅንብሮች + battery_remaining: '% ይቀራል' + notifications: ማሳወቂያዎች diff --git a/src/apps/toolbar/i18n/translations/ar.yml b/src/apps/toolbar/i18n/translations/ar.yml index c82ca40d..5123d442 100644 --- a/src/apps/toolbar/i18n/translations/ar.yml +++ b/src/apps/toolbar/i18n/translations/ar.yml @@ -1,34 +1,34 @@ -media: - master_volume: الحجم الرئيسي - output_device: جهاز إخراج - input_device: جهاز الإدخال - players: مشغلات الوسائط - device: - multimedia: الوسائط المتعددة - comunications: مجال الاتصالات -network: - not_found: لم يتم العثور على شبكات - more: المزيد من إعدادات الشبكة - hidden: الشبكة المخفية - placeholder: - password: كلمة المرور - disconnect: قطع الاتصال - connect: يتصل -settings: - title: إعدادات - app_settings: إعدادات التطبيقات - log_out: تسجيل خروج - sleep: ينام - restart: إعادة تشغيل - shutdown: اغلق -placeholder: - open_user_folder: افتح مجلد المستخدم - open_system_tray: افتح علبة النظام - bluetooth_devices: بلوتوث - ethernet_connected: خدمة الإنترنت - ethernet_disconnected: لا يوجد اتصال بالإنترنت - volume: مقدار - battery_remaining: ٪ متبقي - smart_charge: '- الشحن الذكي' - settings: الإعدادات السريعة - notifications: إشعارات +media: + master_volume: الحجم الرئيسي + output_device: جهاز إخراج + input_device: جهاز الإدخال + players: مشغلات الوسائط + device: + multimedia: الوسائط المتعددة + comunications: مجال الاتصالات +network: + not_found: لم يتم العثور على شبكات + more: المزيد من إعدادات الشبكة + hidden: الشبكة المخفية + placeholder: + password: كلمة المرور + disconnect: قطع الاتصال + connect: يتصل +settings: + title: إعدادات + app_settings: إعدادات التطبيقات + log_out: تسجيل خروج + sleep: ينام + restart: إعادة تشغيل + shutdown: اغلق +placeholder: + open_user_folder: افتح مجلد المستخدم + open_system_tray: افتح علبة النظام + bluetooth_devices: بلوتوث + ethernet_connected: خدمة الإنترنت + ethernet_disconnected: لا يوجد اتصال بالإنترنت + volume: مقدار + battery_remaining: ٪ متبقي + smart_charge: '- الشحن الذكي' + settings: الإعدادات السريعة + notifications: إشعارات diff --git a/src/apps/toolbar/i18n/translations/az.yml b/src/apps/toolbar/i18n/translations/az.yml index 505b7573..87798774 100644 --- a/src/apps/toolbar/i18n/translations/az.yml +++ b/src/apps/toolbar/i18n/translations/az.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedia - comunications: Rabitə - master_volume: Magistral həcm - players: Media oyunçuları - input_device: Giriş cihazı - output_device: Çıxış cihazı -network: - placeholder: - password: Parol - more: Daha çox şəbəkə parametrləri - not_found: Heç bir şəbəkə tapılmadı - hidden: Gizli şəbəkə - disconnect: Ayırd etmək - connect: Qoşulmaq -settings: - shutdown: Söndür - restart: Yenidən başlamaq - log_out: Çıxış - app_settings: Tətbiq parametrləri - sleep: Yatmaq - title: Parametrlər -placeholder: - ethernet_connected: İnternetə çıxışı - smart_charge: '- Ağıllı yük' - bluetooth_devices: Bluetooth və Cihazlar - open_system_tray: Açıq Sistem Tepsisi - volume: Həcm - open_user_folder: İstifadəçi qovluğu açın - ethernet_disconnected: İnternetə giriş yoxdur - settings: Tez Parametrlər - battery_remaining: Qalan - notifications: Bildirişlər +media: + device: + multimedia: Multimedia + comunications: Rabitə + master_volume: Magistral həcm + players: Media oyunçuları + input_device: Giriş cihazı + output_device: Çıxış cihazı +network: + placeholder: + password: Parol + more: Daha çox şəbəkə parametrləri + not_found: Heç bir şəbəkə tapılmadı + hidden: Gizli şəbəkə + disconnect: Ayırd etmək + connect: Qoşulmaq +settings: + shutdown: Söndür + restart: Yenidən başlamaq + log_out: Çıxış + app_settings: Tətbiq parametrləri + sleep: Yatmaq + title: Parametrlər +placeholder: + ethernet_connected: İnternetə çıxışı + smart_charge: '- Ağıllı yük' + bluetooth_devices: Bluetooth və Cihazlar + open_system_tray: Açıq Sistem Tepsisi + volume: Həcm + open_user_folder: İstifadəçi qovluğu açın + ethernet_disconnected: İnternetə giriş yoxdur + settings: Tez Parametrlər + battery_remaining: Qalan + notifications: Bildirişlər diff --git a/src/apps/toolbar/i18n/translations/bg.yml b/src/apps/toolbar/i18n/translations/bg.yml index 019a9237..2054a89c 100644 --- a/src/apps/toolbar/i18n/translations/bg.yml +++ b/src/apps/toolbar/i18n/translations/bg.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Мултимедия - comunications: Комуникации - master_volume: Главен обем - input_device: Вход устройство - output_device: Изходно устройство - players: Медийни играчи -network: - placeholder: - password: Парола - not_found: Не са намерени мрежи - connect: Свържете се - hidden: Скрита мрежа - more: Повече мрежови настройки - disconnect: Изключете -settings: - shutdown: Изключвам - log_out: Излез от профила си - title: Настройки - restart: Рестартирам - app_settings: Настройки на приложението - sleep: Сън -placeholder: - battery_remaining: '% остава' - open_system_tray: Отворена система табла - open_user_folder: Отворете потребителската папка - ethernet_disconnected: Няма достъп до интернет - smart_charge: '- Smart Charge' - ethernet_connected: достъп до интернет - volume: Сила на звука - settings: Бързи настройки - bluetooth_devices: Bluetooth & устройства - notifications: Известия +media: + device: + multimedia: Мултимедия + comunications: Комуникации + master_volume: Главен обем + input_device: Вход устройство + output_device: Изходно устройство + players: Медийни играчи +network: + placeholder: + password: Парола + not_found: Не са намерени мрежи + connect: Свържете се + hidden: Скрита мрежа + more: Повече мрежови настройки + disconnect: Изключете +settings: + shutdown: Изключвам + log_out: Излез от профила си + title: Настройки + restart: Рестартирам + app_settings: Настройки на приложението + sleep: Сън +placeholder: + battery_remaining: '% остава' + open_system_tray: Отворена система табла + open_user_folder: Отворете потребителската папка + ethernet_disconnected: Няма достъп до интернет + smart_charge: '- Smart Charge' + ethernet_connected: достъп до интернет + volume: Сила на звука + settings: Бързи настройки + bluetooth_devices: Bluetooth & устройства + notifications: Известия diff --git a/src/apps/toolbar/i18n/translations/bn.yml b/src/apps/toolbar/i18n/translations/bn.yml index 55926170..4a092ac9 100644 --- a/src/apps/toolbar/i18n/translations/bn.yml +++ b/src/apps/toolbar/i18n/translations/bn.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: যোগাযোগ - multimedia: মাল্টিমিডিয়া - master_volume: মাস্টার ভলিউম - input_device: প্রেরণকারী যন্ত্র - output_device: আউটপুট ডিভাইস - players: মিডিয়া প্লেয়ার -network: - placeholder: - password: পাসওয়ার্ড - disconnect: সংযোগ বিচ্ছিন্ন - not_found: কোনও নেটওয়ার্ক পাওয়া যায় নি - connect: সংযুক্ত করুন - more: আরও নেটওয়ার্ক সেটিংস - hidden: লুকানো নেটওয়ার্ক -settings: - app_settings: অ্যাপ সেটিংস - restart: আবার শুরু - sleep: ঘুম - title: সেটিংস - log_out: প্রস্থান - shutdown: শাটডাউন -placeholder: - ethernet_connected: ইন্টারনেট সুবিধা - smart_charge: '- স্মার্ট চার্জ' - open_system_tray: ওপেন সিস্টেম ট্রে - battery_remaining: '% অবশিষ্ট' - settings: দ্রুত সেটিংস - ethernet_disconnected: কোনও ইন্টারনেট অ্যাক্সেস নেই - bluetooth_devices: ব্লুটুথ এবং ডিভাইস - volume: ভলিউম - open_user_folder: ব্যবহারকারী ফোল্ডারটি খুলুন - notifications: বিজ্ঞপ্তি +media: + device: + comunications: যোগাযোগ + multimedia: মাল্টিমিডিয়া + master_volume: মাস্টার ভলিউম + input_device: প্রেরণকারী যন্ত্র + output_device: আউটপুট ডিভাইস + players: মিডিয়া প্লেয়ার +network: + placeholder: + password: পাসওয়ার্ড + disconnect: সংযোগ বিচ্ছিন্ন + not_found: কোনও নেটওয়ার্ক পাওয়া যায় নি + connect: সংযুক্ত করুন + more: আরও নেটওয়ার্ক সেটিংস + hidden: লুকানো নেটওয়ার্ক +settings: + app_settings: অ্যাপ সেটিংস + restart: আবার শুরু + sleep: ঘুম + title: সেটিংস + log_out: প্রস্থান + shutdown: শাটডাউন +placeholder: + ethernet_connected: ইন্টারনেট সুবিধা + smart_charge: '- স্মার্ট চার্জ' + open_system_tray: ওপেন সিস্টেম ট্রে + battery_remaining: '% অবশিষ্ট' + settings: দ্রুত সেটিংস + ethernet_disconnected: কোনও ইন্টারনেট অ্যাক্সেস নেই + bluetooth_devices: ব্লুটুথ এবং ডিভাইস + volume: ভলিউম + open_user_folder: ব্যবহারকারী ফোল্ডারটি খুলুন + notifications: বিজ্ঞপ্তি diff --git a/src/apps/toolbar/i18n/translations/bs.yml b/src/apps/toolbar/i18n/translations/bs.yml index fbb1bbe0..84bdb8f8 100644 --- a/src/apps/toolbar/i18n/translations/bs.yml +++ b/src/apps/toolbar/i18n/translations/bs.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Komunikacije - multimedia: Multimedija - players: Medijski igrači - input_device: Uređaj za unos - master_volume: Glavni volumen - output_device: Izlazni uređaj -network: - placeholder: - password: Lozinka - disconnect: Prekinuti - not_found: Nisu pronađene mreže - more: Više mrežnih postavki - hidden: Skrivena mreža - connect: Povezati -settings: - shutdown: Ugasiti - log_out: Odjaviti se - restart: Ponovo pokrenuti - app_settings: Postavke aplikacija - sleep: Spavati - title: Postavke -placeholder: - ethernet_connected: pristup Internetu - ethernet_disconnected: Nema pristupa internetu - battery_remaining: preostalo% - open_system_tray: Otvorena sistemska ladica - smart_charge: '- pametna optužba' - open_user_folder: Otvorite mapu korisnika - settings: Brze postavke - volume: Zapremina - bluetooth_devices: Bluetooth i uređaji - notifications: Obavijesti +media: + device: + comunications: Komunikacije + multimedia: Multimedija + players: Medijski igrači + input_device: Uređaj za unos + master_volume: Glavni volumen + output_device: Izlazni uređaj +network: + placeholder: + password: Lozinka + disconnect: Prekinuti + not_found: Nisu pronađene mreže + more: Više mrežnih postavki + hidden: Skrivena mreža + connect: Povezati +settings: + shutdown: Ugasiti + log_out: Odjaviti se + restart: Ponovo pokrenuti + app_settings: Postavke aplikacija + sleep: Spavati + title: Postavke +placeholder: + ethernet_connected: pristup Internetu + ethernet_disconnected: Nema pristupa internetu + battery_remaining: preostalo% + open_system_tray: Otvorena sistemska ladica + smart_charge: '- pametna optužba' + open_user_folder: Otvorite mapu korisnika + settings: Brze postavke + volume: Zapremina + bluetooth_devices: Bluetooth i uređaji + notifications: Obavijesti diff --git a/src/apps/toolbar/i18n/translations/ca.yml b/src/apps/toolbar/i18n/translations/ca.yml index 03f0a9a0..57ffe108 100644 --- a/src/apps/toolbar/i18n/translations/ca.yml +++ b/src/apps/toolbar/i18n/translations/ca.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimèdia - comunications: Comunicacions - master_volume: Volum de domini - input_device: Dispositiu d'entrada - output_device: Dispositiu de sortida - players: Reproductors de mitjans de comunicació -network: - placeholder: - password: Contrasenya - not_found: No es van trobar xarxes - more: Més configuració de xarxa - connect: Conectar - disconnect: Desconectar - hidden: Xarxa oculta -settings: - app_settings: Configuració de l'aplicació - title: Configuració - restart: Reinicia - shutdown: Tancar - log_out: Tancar sessió - sleep: Dormir -placeholder: - settings: Configuració ràpida - ethernet_disconnected: Sense accés a Internet - battery_remaining: '% restant' - smart_charge: '- Càrrega intel·ligent' - bluetooth_devices: Bluetooth i dispositius - volume: Volum - open_user_folder: Obriu la carpeta d'usuari - open_system_tray: Safata del sistema obert - ethernet_connected: accés a Internet - notifications: Notificacions +media: + device: + multimedia: Multimèdia + comunications: Comunicacions + master_volume: Volum de domini + input_device: Dispositiu d'entrada + output_device: Dispositiu de sortida + players: Reproductors de mitjans de comunicació +network: + placeholder: + password: Contrasenya + not_found: No es van trobar xarxes + more: Més configuració de xarxa + connect: Conectar + disconnect: Desconectar + hidden: Xarxa oculta +settings: + app_settings: Configuració de l'aplicació + title: Configuració + restart: Reinicia + shutdown: Tancar + log_out: Tancar sessió + sleep: Dormir +placeholder: + settings: Configuració ràpida + ethernet_disconnected: Sense accés a Internet + battery_remaining: '% restant' + smart_charge: '- Càrrega intel·ligent' + bluetooth_devices: Bluetooth i dispositius + volume: Volum + open_user_folder: Obriu la carpeta d'usuari + open_system_tray: Safata del sistema obert + ethernet_connected: accés a Internet + notifications: Notificacions diff --git a/src/apps/toolbar/i18n/translations/cs.yml b/src/apps/toolbar/i18n/translations/cs.yml index e3a3406d..99f5dfce 100644 --- a/src/apps/toolbar/i18n/translations/cs.yml +++ b/src/apps/toolbar/i18n/translations/cs.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimédia - comunications: komunikace - input_device: Vstupní zařízení - players: Přehrávače médií - master_volume: Hlavní hlasitost - output_device: Výstupní zařízení -network: - placeholder: - password: Heslo - not_found: Nalezeny žádné sítě - hidden: Skrytá síť - more: Více nastavení sítě - disconnect: Odpojit - connect: Připojit -settings: - app_settings: Nastavení aplikace - restart: Restart - shutdown: Vypnout - sleep: Spát - log_out: Odhlásit se - title: Nastavení -placeholder: - ethernet_disconnected: Žádný přístup k internetu - volume: Hlasitost - bluetooth_devices: Bluetooth & zařízení - open_system_tray: Otevřený systémový zásobník - ethernet_connected: Přístup na internet - open_user_folder: Otevřená složka uživatele - smart_charge: '- Chytrý poplatek' - battery_remaining: zbývající % - settings: Rychlé nastavení - notifications: Oznámení +media: + device: + multimedia: Multimédia + comunications: komunikace + input_device: Vstupní zařízení + players: Přehrávače médií + master_volume: Hlavní hlasitost + output_device: Výstupní zařízení +network: + placeholder: + password: Heslo + not_found: Nalezeny žádné sítě + hidden: Skrytá síť + more: Více nastavení sítě + disconnect: Odpojit + connect: Připojit +settings: + app_settings: Nastavení aplikace + restart: Restart + shutdown: Vypnout + sleep: Spát + log_out: Odhlásit se + title: Nastavení +placeholder: + ethernet_disconnected: Žádný přístup k internetu + volume: Hlasitost + bluetooth_devices: Bluetooth & zařízení + open_system_tray: Otevřený systémový zásobník + ethernet_connected: Přístup na internet + open_user_folder: Otevřená složka uživatele + smart_charge: '- Chytrý poplatek' + battery_remaining: zbývající % + settings: Rychlé nastavení + notifications: Oznámení diff --git a/src/apps/toolbar/i18n/translations/cy.yml b/src/apps/toolbar/i18n/translations/cy.yml index 100e07f7..c956ecef 100644 --- a/src/apps/toolbar/i18n/translations/cy.yml +++ b/src/apps/toolbar/i18n/translations/cy.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Gyfathrebiadau - multimedia: Amlgyfrwng - players: Chwaraewyr cyfryngau - output_device: Dyfais allbwn - master_volume: Meistr - input_device: Dyfais fewnbwn -network: - placeholder: - password: Gyfrinair - hidden: Rhwydwaith Cudd - not_found: Ni ddarganfuwyd unrhyw rwydweithiau - more: Mwy o osodiadau rhwydwaith - disconnect: Ddatgysylltith - connect: Chysyllta ’ -settings: - restart: Ail-ddechrau - log_out: Allgofnodi - app_settings: Gosodiadau App - shutdown: Chaead - title: Gosodiadau - sleep: Chysger -placeholder: - open_system_tray: Hambwrdd System Agored - smart_charge: '- Tâl craff' - battery_remaining: '% yn weddill' - settings: Gosodiadau Cyflym - ethernet_disconnected: Dim Mynediad i'r Rhyngrwyd - open_user_folder: Agor Ffolder Defnyddiwr - ethernet_connected: Mynediad i'r Rhyngrwyd - bluetooth_devices: Bluetooth a Dyfeisiau - volume: Nghyfrol - notifications: Hysbysiadau +media: + device: + comunications: Gyfathrebiadau + multimedia: Amlgyfrwng + players: Chwaraewyr cyfryngau + output_device: Dyfais allbwn + master_volume: Meistr + input_device: Dyfais fewnbwn +network: + placeholder: + password: Gyfrinair + hidden: Rhwydwaith Cudd + not_found: Ni ddarganfuwyd unrhyw rwydweithiau + more: Mwy o osodiadau rhwydwaith + disconnect: Ddatgysylltith + connect: Chysyllta ’ +settings: + restart: Ail-ddechrau + log_out: Allgofnodi + app_settings: Gosodiadau App + shutdown: Chaead + title: Gosodiadau + sleep: Chysger +placeholder: + open_system_tray: Hambwrdd System Agored + smart_charge: '- Tâl craff' + battery_remaining: '% yn weddill' + settings: Gosodiadau Cyflym + ethernet_disconnected: Dim Mynediad i'r Rhyngrwyd + open_user_folder: Agor Ffolder Defnyddiwr + ethernet_connected: Mynediad i'r Rhyngrwyd + bluetooth_devices: Bluetooth a Dyfeisiau + volume: Nghyfrol + notifications: Hysbysiadau diff --git a/src/apps/toolbar/i18n/translations/da.yml b/src/apps/toolbar/i18n/translations/da.yml index 18fc2e81..60b3b595 100644 --- a/src/apps/toolbar/i18n/translations/da.yml +++ b/src/apps/toolbar/i18n/translations/da.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedia - comunications: Kommunikation - input_device: Inputenhed - players: Medieafspillere - output_device: Outputenhed - master_volume: Mastervolumen -network: - placeholder: - password: Adgangskode - connect: Forbinde - disconnect: Koble fra - not_found: Ingen netværk fundet - more: Flere netværksindstillinger - hidden: Skjult netværk -settings: - sleep: Søvn - shutdown: Lukke ned - log_out: Log ud - restart: Genstart - title: Indstillinger - app_settings: Appindstillinger -placeholder: - ethernet_connected: Internetadgang - volume: Bind - settings: Hurtige indstillinger - battery_remaining: '% resterende' - smart_charge: '- Smart opladning' - open_user_folder: Åben brugermappe - ethernet_disconnected: Ingen internetadgang - bluetooth_devices: Bluetooth & enheder - open_system_tray: Åben systembakke - notifications: Underretninger +media: + device: + multimedia: Multimedia + comunications: Kommunikation + input_device: Inputenhed + players: Medieafspillere + output_device: Outputenhed + master_volume: Mastervolumen +network: + placeholder: + password: Adgangskode + connect: Forbinde + disconnect: Koble fra + not_found: Ingen netværk fundet + more: Flere netværksindstillinger + hidden: Skjult netværk +settings: + sleep: Søvn + shutdown: Lukke ned + log_out: Log ud + restart: Genstart + title: Indstillinger + app_settings: Appindstillinger +placeholder: + ethernet_connected: Internetadgang + volume: Bind + settings: Hurtige indstillinger + battery_remaining: '% resterende' + smart_charge: '- Smart opladning' + open_user_folder: Åben brugermappe + ethernet_disconnected: Ingen internetadgang + bluetooth_devices: Bluetooth & enheder + open_system_tray: Åben systembakke + notifications: Underretninger diff --git a/src/apps/toolbar/i18n/translations/de.yml b/src/apps/toolbar/i18n/translations/de.yml index 545d3274..c4ebe7b0 100644 --- a/src/apps/toolbar/i18n/translations/de.yml +++ b/src/apps/toolbar/i18n/translations/de.yml @@ -1,34 +1,34 @@ -media: - master_volume: Hauptlautstärke - output_device: Ausgabegerät - input_device: Eingabegerät - players: Medienplayer - device: - multimedia: Multimedia - comunications: Kommunikation -network: - not_found: Keine Netzwerke gefunden - more: Weitere Netzwerkeinstellungen - hidden: Verstecktes Netzwerk - placeholder: - password: Passwort - disconnect: Trennen - connect: Verbinden -settings: - title: Einstellungen - app_settings: App-Einstellungen - log_out: Abmelden - sleep: Ruhezustand - restart: Neustarten - shutdown: Herunterfahren -placeholder: - open_user_folder: Benutzerordner öffnen - open_system_tray: Systemleiste öffnen - bluetooth_devices: Bluetooth & Geräte - ethernet_connected: Internetzugang - ethernet_disconnected: Kein Internetzugang - volume: Lautstärke - battery_remaining: '% verbleibend' - smart_charge: ' - Intelligentes Laden' - settings: Schnelleinstellungen - notifications: Benachrichtigungen +media: + master_volume: Hauptlautstärke + output_device: Ausgabegerät + input_device: Eingabegerät + players: Medienplayer + device: + multimedia: Multimedia + comunications: Kommunikation +network: + not_found: Keine Netzwerke gefunden + more: Weitere Netzwerkeinstellungen + hidden: Verstecktes Netzwerk + placeholder: + password: Passwort + disconnect: Trennen + connect: Verbinden +settings: + title: Einstellungen + app_settings: App-Einstellungen + log_out: Abmelden + sleep: Ruhezustand + restart: Neustarten + shutdown: Herunterfahren +placeholder: + open_user_folder: Benutzerordner öffnen + open_system_tray: Systemleiste öffnen + bluetooth_devices: Bluetooth & Geräte + ethernet_connected: Internetzugang + ethernet_disconnected: Kein Internetzugang + volume: Lautstärke + battery_remaining: '% verbleibend' + smart_charge: ' - Intelligentes Laden' + settings: Schnelleinstellungen + notifications: Benachrichtigungen diff --git a/src/apps/toolbar/i18n/translations/el.yml b/src/apps/toolbar/i18n/translations/el.yml index a4ae05dc..3d076be6 100644 --- a/src/apps/toolbar/i18n/translations/el.yml +++ b/src/apps/toolbar/i18n/translations/el.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: ΠΟΛΥΜΕΣΑ - comunications: Διαβιβάσεις - input_device: Συσκευή εισόδου - master_volume: Κύριος όγκος - players: Media players - output_device: Συσκευή εξόδου -network: - placeholder: - password: Κωδικός πρόσβασης - more: Περισσότερες ρυθμίσεις δικτύου - disconnect: Αποσυνδέω - connect: Συνδέω-συωδεομαι - hidden: Κρυμμένο δίκτυο - not_found: Δεν βρέθηκαν δίκτυα -settings: - app_settings: Ρυθμίσεις εφαρμογής - shutdown: ΤΕΡΜΑΤΙΣΜΟΣ ΛΕΙΤΟΥΡΓΙΑΣ - title: Ρυθμίσεις - log_out: Αποσύνδεση - restart: Επανεκκίνηση - sleep: Υπνος -placeholder: - settings: Γρήγορες ρυθμίσεις - smart_charge: '- έξυπνη χρέωση' - volume: Ενταση ΗΧΟΥ - open_system_tray: Ανοίξτε το δίσκο του συστήματος - open_user_folder: Ανοίξτε το φάκελο χρήστη - battery_remaining: '% υπόλοιπο' - bluetooth_devices: Bluetooth & συσκευές - ethernet_connected: πρόσβαση στο διαδίκτυο - ethernet_disconnected: Χωρίς πρόσβαση στο Διαδίκτυο - notifications: Ειδοποιήσεις +media: + device: + multimedia: ΠΟΛΥΜΕΣΑ + comunications: Διαβιβάσεις + input_device: Συσκευή εισόδου + master_volume: Κύριος όγκος + players: Media players + output_device: Συσκευή εξόδου +network: + placeholder: + password: Κωδικός πρόσβασης + more: Περισσότερες ρυθμίσεις δικτύου + disconnect: Αποσυνδέω + connect: Συνδέω-συωδεομαι + hidden: Κρυμμένο δίκτυο + not_found: Δεν βρέθηκαν δίκτυα +settings: + app_settings: Ρυθμίσεις εφαρμογής + shutdown: ΤΕΡΜΑΤΙΣΜΟΣ ΛΕΙΤΟΥΡΓΙΑΣ + title: Ρυθμίσεις + log_out: Αποσύνδεση + restart: Επανεκκίνηση + sleep: Υπνος +placeholder: + settings: Γρήγορες ρυθμίσεις + smart_charge: '- έξυπνη χρέωση' + volume: Ενταση ΗΧΟΥ + open_system_tray: Ανοίξτε το δίσκο του συστήματος + open_user_folder: Ανοίξτε το φάκελο χρήστη + battery_remaining: '% υπόλοιπο' + bluetooth_devices: Bluetooth & συσκευές + ethernet_connected: πρόσβαση στο διαδίκτυο + ethernet_disconnected: Χωρίς πρόσβαση στο Διαδίκτυο + notifications: Ειδοποιήσεις diff --git a/src/apps/toolbar/i18n/translations/en.yml b/src/apps/toolbar/i18n/translations/en.yml index 6486ec1f..46229c9c 100644 --- a/src/apps/toolbar/i18n/translations/en.yml +++ b/src/apps/toolbar/i18n/translations/en.yml @@ -1,35 +1,35 @@ -media: - master_volume: Master Volume - output_device: Output device - input_device: Input device - players: Media Players - device: - multimedia: Multimedia - comunications: Communications -network: - not_found: No networks found - more: More Network Settings - hidden: Hidden Network - placeholder: - password: Password - disconnect: Disconnect - connect: Connect -settings: - title: Settings - app_settings: App Settings - log_out: Log Out - sleep: Sleep - restart: Restart - shutdown: Shutdown - power: Power -placeholder: - open_user_folder: Open User Folder - open_system_tray: Open System Tray - bluetooth_devices: Bluetooth & Devices - ethernet_connected: Internet access - ethernet_disconnected: No internet access - volume: Volume - battery_remaining: "% remaining" - smart_charge: " - Smart Charge" - settings: Quick Settings - notifications: Notifications +media: + master_volume: Master Volume + output_device: Output device + input_device: Input device + players: Media Players + device: + multimedia: Multimedia + comunications: Communications +network: + not_found: No networks found + more: More Network Settings + hidden: Hidden Network + placeholder: + password: Password + disconnect: Disconnect + connect: Connect +settings: + title: Settings + app_settings: App Settings + log_out: Log Out + sleep: Sleep + restart: Restart + shutdown: Shutdown + power: Power +placeholder: + open_user_folder: Open User Folder + open_system_tray: Open System Tray + bluetooth_devices: Bluetooth & Devices + ethernet_connected: Internet access + ethernet_disconnected: No internet access + volume: Volume + battery_remaining: "% remaining" + smart_charge: " - Smart Charge" + settings: Quick Settings + notifications: Notifications diff --git a/src/apps/toolbar/i18n/translations/es.yml b/src/apps/toolbar/i18n/translations/es.yml index 93d5b933..147c1ef2 100644 --- a/src/apps/toolbar/i18n/translations/es.yml +++ b/src/apps/toolbar/i18n/translations/es.yml @@ -1,34 +1,34 @@ -media: - master_volume: Volumen Maestro - output_device: Dispositivo de salida - input_device: Dispositivo de entrada - players: Reproductores de medios - device: - multimedia: Multimedia - comunications: Comunicaciones -network: - not_found: No se encontraron redes - more: Más configuraciones de red - hidden: Red oculta - placeholder: - password: Contraseña - disconnect: Desconectar - connect: Conectar -settings: - title: Configuraciones - app_settings: Configuraciones de la aplicación - log_out: Cerrar sesión - sleep: Suspender - restart: Reiniciar - shutdown: Apagar -placeholder: - open_user_folder: Abrir carpeta de usuario - open_system_tray: Abrir bandeja del sistema - bluetooth_devices: Bluetooth y dispositivos - ethernet_connected: Acceso a internet - ethernet_disconnected: Sin acceso a internet - volume: Volumen - battery_remaining: '% restante' - smart_charge: ' - Carga inteligente' - settings: Configuraciones rápidas - notifications: Notificaciones +media: + master_volume: Volumen Maestro + output_device: Dispositivo de salida + input_device: Dispositivo de entrada + players: Reproductores de medios + device: + multimedia: Multimedia + comunications: Comunicaciones +network: + not_found: No se encontraron redes + more: Más configuraciones de red + hidden: Red oculta + placeholder: + password: Contraseña + disconnect: Desconectar + connect: Conectar +settings: + title: Configuraciones + app_settings: Configuraciones de la aplicación + log_out: Cerrar sesión + sleep: Suspender + restart: Reiniciar + shutdown: Apagar +placeholder: + open_user_folder: Abrir carpeta de usuario + open_system_tray: Abrir bandeja del sistema + bluetooth_devices: Bluetooth y dispositivos + ethernet_connected: Acceso a internet + ethernet_disconnected: Sin acceso a internet + volume: Volumen + battery_remaining: '% restante' + smart_charge: ' - Carga inteligente' + settings: Configuraciones rápidas + notifications: Notificaciones diff --git a/src/apps/toolbar/i18n/translations/et.yml b/src/apps/toolbar/i18n/translations/et.yml index 30df9ddc..2fa213cd 100644 --- a/src/apps/toolbar/i18n/translations/et.yml +++ b/src/apps/toolbar/i18n/translations/et.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimeedia - comunications: Suhtlus - input_device: Sisendseade - players: Meediamängijad - master_volume: Kaptenimaht - output_device: Väljundseade -network: - placeholder: - password: Parool - disconnect: Ühenduse katkestama - more: Rohkem võrguseadeid - not_found: Võrgustikke pole leitud - connect: Ühendama - hidden: Varjatud võrk -settings: - log_out: Logi välja - restart: Taaskäivita - shutdown: Lülita välja - app_settings: Rakenduse sätted - sleep: Magama - title: Sätted -placeholder: - ethernet_disconnected: Interneti -ühendus pole - ethernet_connected: internetiühendus - battery_remaining: '% järelejäänud' - open_system_tray: Avatud süsteemialus - open_user_folder: Avage kasutaja kaust - smart_charge: '- Nutikas tasu' - bluetooth_devices: Bluetooth ja seadmed - settings: Kiired seaded - volume: Maht - notifications: Teatised +media: + device: + multimedia: Multimeedia + comunications: Suhtlus + input_device: Sisendseade + players: Meediamängijad + master_volume: Kaptenimaht + output_device: Väljundseade +network: + placeholder: + password: Parool + disconnect: Ühenduse katkestama + more: Rohkem võrguseadeid + not_found: Võrgustikke pole leitud + connect: Ühendama + hidden: Varjatud võrk +settings: + log_out: Logi välja + restart: Taaskäivita + shutdown: Lülita välja + app_settings: Rakenduse sätted + sleep: Magama + title: Sätted +placeholder: + ethernet_disconnected: Interneti -ühendus pole + ethernet_connected: internetiühendus + battery_remaining: '% järelejäänud' + open_system_tray: Avatud süsteemialus + open_user_folder: Avage kasutaja kaust + smart_charge: '- Nutikas tasu' + bluetooth_devices: Bluetooth ja seadmed + settings: Kiired seaded + volume: Maht + notifications: Teatised diff --git a/src/apps/toolbar/i18n/translations/eu.yml b/src/apps/toolbar/i18n/translations/eu.yml index b38b9124..60a5066c 100644 --- a/src/apps/toolbar/i18n/translations/eu.yml +++ b/src/apps/toolbar/i18n/translations/eu.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedia - comunications: Komunikazioak - output_device: Irteerako gailua - input_device: Sarrera gailua - master_volume: Bolumen maisua - players: Komunikabideetako jokalariak -network: - placeholder: - password: Kontrazeinu - not_found: Ez da sarerik aurkitu - connect: Batu - hidden: Ezkutuko sarea - disconnect: Deskonektatu - more: Sareko ezarpen gehiago -settings: - restart: Berriro hasi - shutdown: Itzali - log_out: Saioa amaitu - sleep: Lo - app_settings: Aplikazioaren ezarpenak - title: Ezarpen -placeholder: - smart_charge: '- Karga adimentsua' - open_user_folder: Erabiltzaile karpeta irekia - ethernet_connected: Interneterako sarbidea - battery_remaining: '% geratzen' - open_system_tray: Sistema irekiko erretilua - bluetooth_devices: Bluetooth eta gailuak - settings: Ezarpen azkarrak - volume: Ozentasun - ethernet_disconnected: Ez da Interneteko sarbiderik - notifications: Jakinarazpenak +media: + device: + multimedia: Multimedia + comunications: Komunikazioak + output_device: Irteerako gailua + input_device: Sarrera gailua + master_volume: Bolumen maisua + players: Komunikabideetako jokalariak +network: + placeholder: + password: Kontrazeinu + not_found: Ez da sarerik aurkitu + connect: Batu + hidden: Ezkutuko sarea + disconnect: Deskonektatu + more: Sareko ezarpen gehiago +settings: + restart: Berriro hasi + shutdown: Itzali + log_out: Saioa amaitu + sleep: Lo + app_settings: Aplikazioaren ezarpenak + title: Ezarpen +placeholder: + smart_charge: '- Karga adimentsua' + open_user_folder: Erabiltzaile karpeta irekia + ethernet_connected: Interneterako sarbidea + battery_remaining: '% geratzen' + open_system_tray: Sistema irekiko erretilua + bluetooth_devices: Bluetooth eta gailuak + settings: Ezarpen azkarrak + volume: Ozentasun + ethernet_disconnected: Ez da Interneteko sarbiderik + notifications: Jakinarazpenak diff --git a/src/apps/toolbar/i18n/translations/fa.yml b/src/apps/toolbar/i18n/translations/fa.yml index 0745d559..62c52947 100644 --- a/src/apps/toolbar/i18n/translations/fa.yml +++ b/src/apps/toolbar/i18n/translations/fa.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: چند رسانه ای - comunications: ارتباطات - output_device: دستگاه خروجی - input_device: دستگاه ورودی - players: بازیکنان رسانه ای - master_volume: جلد استاد -network: - placeholder: - password: کلمه عبور - connect: وصل کردن - disconnect: قطع شدن - hidden: شبکه پنهان - more: تنظیمات بیشتر شبکه - not_found: هیچ شبکه ای پیدا نشده است -settings: - app_settings: تنظیمات برنامه - restart: مجدداً - sleep: خواب - title: تنظیمات - log_out: خروج - shutdown: تعطیل -placeholder: - settings: تنظیمات سریع - ethernet_connected: دسترسی به اینترنت - volume: جلد - open_system_tray: سینی سیستم باز - battery_remaining: ٪ باقی مانده - bluetooth_devices: بلوتوث و دستگاه - ethernet_disconnected: بدون دسترسی به اینترنت - smart_charge: '- شارژ هوشمند' - open_user_folder: پوشه کاربر را باز کنید - notifications: اطلاعیه +media: + device: + multimedia: چند رسانه ای + comunications: ارتباطات + output_device: دستگاه خروجی + input_device: دستگاه ورودی + players: بازیکنان رسانه ای + master_volume: جلد استاد +network: + placeholder: + password: کلمه عبور + connect: وصل کردن + disconnect: قطع شدن + hidden: شبکه پنهان + more: تنظیمات بیشتر شبکه + not_found: هیچ شبکه ای پیدا نشده است +settings: + app_settings: تنظیمات برنامه + restart: مجدداً + sleep: خواب + title: تنظیمات + log_out: خروج + shutdown: تعطیل +placeholder: + settings: تنظیمات سریع + ethernet_connected: دسترسی به اینترنت + volume: جلد + open_system_tray: سینی سیستم باز + battery_remaining: ٪ باقی مانده + bluetooth_devices: بلوتوث و دستگاه + ethernet_disconnected: بدون دسترسی به اینترنت + smart_charge: '- شارژ هوشمند' + open_user_folder: پوشه کاربر را باز کنید + notifications: اطلاعیه diff --git a/src/apps/toolbar/i18n/translations/fi.yml b/src/apps/toolbar/i18n/translations/fi.yml index 0d2753bc..ab14a1e3 100644 --- a/src/apps/toolbar/i18n/translations/fi.yml +++ b/src/apps/toolbar/i18n/translations/fi.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Viitaus - multimedia: Multimedia - input_device: Syöttölaite - master_volume: Pää-äänenvoimakkuus - players: Mediapelaajat - output_device: Lähtölaite -network: - placeholder: - password: Salasana - connect: Kytkeä - not_found: Verkkoja ei löydy - disconnect: Katkaista - more: Lisää verkkoasetuksia - hidden: Piilotettu verkko -settings: - sleep: Nukkua - log_out: Kirjautua ulos - restart: Uudelleenkäynnistää - title: asetukset - shutdown: Sammuttaa - app_settings: Sovellusasetukset -placeholder: - bluetooth_devices: Bluetooth ja laitteet - battery_remaining: '% jäljelle jäänyt' - settings: Pika -asetukset - ethernet_disconnected: Ei Internet-yhteyttä - ethernet_connected: Internet-yhteys - open_system_tray: Avoin järjestelmälokero - open_user_folder: Avaa käyttäjäkansio - smart_charge: '- Älykäs maksu' - volume: Tilavuus - notifications: Ilmoitukset +media: + device: + comunications: Viitaus + multimedia: Multimedia + input_device: Syöttölaite + master_volume: Pää-äänenvoimakkuus + players: Mediapelaajat + output_device: Lähtölaite +network: + placeholder: + password: Salasana + connect: Kytkeä + not_found: Verkkoja ei löydy + disconnect: Katkaista + more: Lisää verkkoasetuksia + hidden: Piilotettu verkko +settings: + sleep: Nukkua + log_out: Kirjautua ulos + restart: Uudelleenkäynnistää + title: asetukset + shutdown: Sammuttaa + app_settings: Sovellusasetukset +placeholder: + bluetooth_devices: Bluetooth ja laitteet + battery_remaining: '% jäljelle jäänyt' + settings: Pika -asetukset + ethernet_disconnected: Ei Internet-yhteyttä + ethernet_connected: Internet-yhteys + open_system_tray: Avoin järjestelmälokero + open_user_folder: Avaa käyttäjäkansio + smart_charge: '- Älykäs maksu' + volume: Tilavuus + notifications: Ilmoitukset diff --git a/src/apps/toolbar/i18n/translations/fr.yml b/src/apps/toolbar/i18n/translations/fr.yml index 686d5c8c..c44976ef 100644 --- a/src/apps/toolbar/i18n/translations/fr.yml +++ b/src/apps/toolbar/i18n/translations/fr.yml @@ -1,34 +1,34 @@ -media: - master_volume: Volume principal - output_device: Dispositif de sortie - input_device: Dispositif d'entrée - players: Lecteurs multimédias - device: - multimedia: Multimédia - comunications: Communications -network: - not_found: Aucun réseau trouvé - more: Plus de paramètres réseau - hidden: Réseau caché - placeholder: - password: Mot de passe - disconnect: Déconnecter - connect: Connecter -settings: - title: Paramètres - app_settings: Paramètres de l'application - log_out: Se déconnecter - sleep: Dormir - restart: Redémarrage - shutdown: Fermer -placeholder: - open_user_folder: Ouvrir le dossier utilisateur - open_system_tray: Ouvrir la barre d'état système - bluetooth_devices: Bluetooth - ethernet_connected: accès Internet - ethernet_disconnected: Pas d'accès Internet - volume: Volume - battery_remaining: '% restant' - smart_charge: '- Chargement intelligent' - settings: Réglages rapides - notifications: Notifications +media: + master_volume: Volume principal + output_device: Dispositif de sortie + input_device: Dispositif d'entrée + players: Lecteurs multimédias + device: + multimedia: Multimédia + comunications: Communications +network: + not_found: Aucun réseau trouvé + more: Plus de paramètres réseau + hidden: Réseau caché + placeholder: + password: Mot de passe + disconnect: Déconnecter + connect: Connecter +settings: + title: Paramètres + app_settings: Paramètres de l'application + log_out: Se déconnecter + sleep: Dormir + restart: Redémarrage + shutdown: Fermer +placeholder: + open_user_folder: Ouvrir le dossier utilisateur + open_system_tray: Ouvrir la barre d'état système + bluetooth_devices: Bluetooth + ethernet_connected: accès Internet + ethernet_disconnected: Pas d'accès Internet + volume: Volume + battery_remaining: '% restant' + smart_charge: '- Chargement intelligent' + settings: Réglages rapides + notifications: Notifications diff --git a/src/apps/toolbar/i18n/translations/gu.yml b/src/apps/toolbar/i18n/translations/gu.yml index 7b3b41e6..e97de5ee 100644 --- a/src/apps/toolbar/i18n/translations/gu.yml +++ b/src/apps/toolbar/i18n/translations/gu.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: સંચાર - multimedia: બહુમાળી - master_volume: મુખ્ય જમતિસ - input_device: ઇનપુટ ઉપકરણ - output_device: આઉટપુટ - players: માધ્યમો ખેલાડીઓ -network: - placeholder: - password: પાસશ - connect: જોડાવા - disconnect: અલગ કરવું - not_found: કોઈ નેટવર્ક મળ્યાં નથી - hidden: છુપાયેલું નેટવર્ક - more: વધુ નેટવર્ક સેટિંગ્સ -settings: - restart: પુનઃપ્રારંભ - sleep: ઊંઘ - shutdown: બંધ કરો - log_out: લૉગ આઉટ - app_settings: એપ્લિકેશન સેટિંગ્સ - title: પતાવટ -placeholder: - ethernet_connected: ઇન્ટરનેટનો ઉપયોગ - open_system_tray: ખુલ્લી સિસ્ટમ ટ્રે - settings: ઝડપી સેટિંગ્સ - ethernet_disconnected: કોઈ ઇન્ટરનેટ એક્સેસ નથી - smart_charge: '- સ્માર્ટ ચાર્જ' - volume: જથ્થો - bluetooth_devices: બ્લૂટૂથ અને ઉપકરણો - battery_remaining: બાકી % - open_user_folder: વપરાશકર્તા ફોલ્ડર ખોલો - notifications: સૂચના +media: + device: + comunications: સંચાર + multimedia: બહુમાળી + master_volume: મુખ્ય જમતિસ + input_device: ઇનપુટ ઉપકરણ + output_device: આઉટપુટ + players: માધ્યમો ખેલાડીઓ +network: + placeholder: + password: પાસશ + connect: જોડાવા + disconnect: અલગ કરવું + not_found: કોઈ નેટવર્ક મળ્યાં નથી + hidden: છુપાયેલું નેટવર્ક + more: વધુ નેટવર્ક સેટિંગ્સ +settings: + restart: પુનઃપ્રારંભ + sleep: ઊંઘ + shutdown: બંધ કરો + log_out: લૉગ આઉટ + app_settings: એપ્લિકેશન સેટિંગ્સ + title: પતાવટ +placeholder: + ethernet_connected: ઇન્ટરનેટનો ઉપયોગ + open_system_tray: ખુલ્લી સિસ્ટમ ટ્રે + settings: ઝડપી સેટિંગ્સ + ethernet_disconnected: કોઈ ઇન્ટરનેટ એક્સેસ નથી + smart_charge: '- સ્માર્ટ ચાર્જ' + volume: જથ્થો + bluetooth_devices: બ્લૂટૂથ અને ઉપકરણો + battery_remaining: બાકી % + open_user_folder: વપરાશકર્તા ફોલ્ડર ખોલો + notifications: સૂચના diff --git a/src/apps/toolbar/i18n/translations/he.yml b/src/apps/toolbar/i18n/translations/he.yml index a9896e64..590e960a 100644 --- a/src/apps/toolbar/i18n/translations/he.yml +++ b/src/apps/toolbar/i18n/translations/he.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: מולטימדיה - comunications: תקשורת - input_device: מכשיר קלט - output_device: מכשיר פלט - master_volume: נפח אמן - players: שחקני מדיה -network: - placeholder: - password: סיסמה - connect: לְחַבֵּר - disconnect: לְנַתֵק - hidden: רשת נסתרת - not_found: לא נמצאו רשתות - more: הגדרות רשת נוספות -settings: - app_settings: הגדרות אפליקציה - restart: איתחול - log_out: להתנתק - shutdown: לכבות - title: הגדרות - sleep: לִישׁוֹן -placeholder: - settings: הגדרות מהירות - battery_remaining: '% נותר' - ethernet_disconnected: אין גישה לאינטרנט - smart_charge: '- חיוב חכם' - ethernet_connected: גישה לאינטרנט - bluetooth_devices: Bluetooth ומכשירים - open_system_tray: מגש מערכת פתוח - volume: כרך - open_user_folder: פתח את תיקיית המשתמש - notifications: התראות +media: + device: + multimedia: מולטימדיה + comunications: תקשורת + input_device: מכשיר קלט + output_device: מכשיר פלט + master_volume: נפח אמן + players: שחקני מדיה +network: + placeholder: + password: סיסמה + connect: לְחַבֵּר + disconnect: לְנַתֵק + hidden: רשת נסתרת + not_found: לא נמצאו רשתות + more: הגדרות רשת נוספות +settings: + app_settings: הגדרות אפליקציה + restart: איתחול + log_out: להתנתק + shutdown: לכבות + title: הגדרות + sleep: לִישׁוֹן +placeholder: + settings: הגדרות מהירות + battery_remaining: '% נותר' + ethernet_disconnected: אין גישה לאינטרנט + smart_charge: '- חיוב חכם' + ethernet_connected: גישה לאינטרנט + bluetooth_devices: Bluetooth ומכשירים + open_system_tray: מגש מערכת פתוח + volume: כרך + open_user_folder: פתח את תיקיית המשתמש + notifications: התראות diff --git a/src/apps/toolbar/i18n/translations/hi.yml b/src/apps/toolbar/i18n/translations/hi.yml index 9561eed3..dcd2d8f7 100644 --- a/src/apps/toolbar/i18n/translations/hi.yml +++ b/src/apps/toolbar/i18n/translations/hi.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: बहुतायत - comunications: संचार - master_volume: मूल संस्करण - output_device: आउटपुट डिवाइस - players: मीडिया -खिलाड़ी - input_device: इनपुट डिवाइस -network: - placeholder: - password: पासवर्ड - not_found: कोई नेटवर्क नहीं मिला - more: अधिक नेटवर्क सेटिंग्स - hidden: छिपा हुआ नेटवर्क - disconnect: डिस्कनेक्ट - connect: जोड़ना -settings: - restart: पुनः आरंभ करें - sleep: नींद - shutdown: शट डाउन - title: समायोजन - log_out: लॉग आउट - app_settings: एप्लिकेशन सेटिंग -placeholder: - smart_charge: '- स्मार्ट चार्ज' - battery_remaining: '% शेष' - open_user_folder: उपयोगकर्ता फ़ोल्डर खोलें - bluetooth_devices: ब्लूटूथ और डिवाइस - ethernet_connected: इंटरनेट का उपयोग - ethernet_disconnected: इंटरनेट की सुविधा नहीं है - settings: त्वरित सेटिंग - volume: आयतन - open_system_tray: खुला तंत्र ट्रे - notifications: अधिसूचना +media: + device: + multimedia: बहुतायत + comunications: संचार + master_volume: मूल संस्करण + output_device: आउटपुट डिवाइस + players: मीडिया -खिलाड़ी + input_device: इनपुट डिवाइस +network: + placeholder: + password: पासवर्ड + not_found: कोई नेटवर्क नहीं मिला + more: अधिक नेटवर्क सेटिंग्स + hidden: छिपा हुआ नेटवर्क + disconnect: डिस्कनेक्ट + connect: जोड़ना +settings: + restart: पुनः आरंभ करें + sleep: नींद + shutdown: शट डाउन + title: समायोजन + log_out: लॉग आउट + app_settings: एप्लिकेशन सेटिंग +placeholder: + smart_charge: '- स्मार्ट चार्ज' + battery_remaining: '% शेष' + open_user_folder: उपयोगकर्ता फ़ोल्डर खोलें + bluetooth_devices: ब्लूटूथ और डिवाइस + ethernet_connected: इंटरनेट का उपयोग + ethernet_disconnected: इंटरनेट की सुविधा नहीं है + settings: त्वरित सेटिंग + volume: आयतन + open_system_tray: खुला तंत्र ट्रे + notifications: अधिसूचना diff --git a/src/apps/toolbar/i18n/translations/hr.yml b/src/apps/toolbar/i18n/translations/hr.yml index 8f5c7e0f..0b0e249e 100644 --- a/src/apps/toolbar/i18n/translations/hr.yml +++ b/src/apps/toolbar/i18n/translations/hr.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedija - comunications: Komunikacija - input_device: Ulazni uređaj - output_device: Izlazni uređaj - players: Medijski igrači - master_volume: Glasnoća -network: - placeholder: - password: Lozinka - connect: Spojiti - not_found: Nisu pronađene mreže - hidden: Skrivena mreža - disconnect: Odspojiti - more: Više mrežnih postavki -settings: - log_out: Odjavite se - sleep: Spavati - shutdown: Ugasiti - app_settings: Postavke aplikacija - restart: Ponovno pokrenuti - title: Postavke -placeholder: - volume: Volumen - ethernet_connected: pristup internetu - ethernet_disconnected: Nema pristupa internetu - settings: Brze postavke - smart_charge: '- pametni naboj' - battery_remaining: '% Ostali' - open_user_folder: Otvorena korisnička mapa - open_system_tray: Otvoreni sustav - bluetooth_devices: Bluetooth i uređaji - notifications: Obavijesti +media: + device: + multimedia: Multimedija + comunications: Komunikacija + input_device: Ulazni uređaj + output_device: Izlazni uređaj + players: Medijski igrači + master_volume: Glasnoća +network: + placeholder: + password: Lozinka + connect: Spojiti + not_found: Nisu pronađene mreže + hidden: Skrivena mreža + disconnect: Odspojiti + more: Više mrežnih postavki +settings: + log_out: Odjavite se + sleep: Spavati + shutdown: Ugasiti + app_settings: Postavke aplikacija + restart: Ponovno pokrenuti + title: Postavke +placeholder: + volume: Volumen + ethernet_connected: pristup internetu + ethernet_disconnected: Nema pristupa internetu + settings: Brze postavke + smart_charge: '- pametni naboj' + battery_remaining: '% Ostali' + open_user_folder: Otvorena korisnička mapa + open_system_tray: Otvoreni sustav + bluetooth_devices: Bluetooth i uređaji + notifications: Obavijesti diff --git a/src/apps/toolbar/i18n/translations/hu.yml b/src/apps/toolbar/i18n/translations/hu.yml index 5c694872..b8fdbeff 100644 --- a/src/apps/toolbar/i18n/translations/hu.yml +++ b/src/apps/toolbar/i18n/translations/hu.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimédia - comunications: Kommunikáció - output_device: Kimeneti eszköz - players: Médialejátszók - input_device: Beviteli eszköz - master_volume: Fő kötet -network: - placeholder: - password: Jelszó - disconnect: Leválaszt - not_found: Nincsenek hálózatok nem találtak - hidden: Rejtett hálózat - connect: Összekapcsol - more: További hálózati beállítások -settings: - app_settings: Alkalmazásbeállítások - restart: Újrakezd - log_out: Kijelentkezés - shutdown: Leállitás - sleep: Alvás - title: Beállítások -placeholder: - bluetooth_devices: Bluetooth & eszközök - ethernet_connected: internet-hozzáférés - smart_charge: '- Intelligens töltés' - ethernet_disconnected: Nincs internet hozzaferes - settings: Gyors beállítások - open_system_tray: Nyitott rendszer tálca - battery_remaining: '% megmaradt' - volume: Hangerő - open_user_folder: Nyissa meg a felhasználói mappát - notifications: Értesítések +media: + device: + multimedia: Multimédia + comunications: Kommunikáció + output_device: Kimeneti eszköz + players: Médialejátszók + input_device: Beviteli eszköz + master_volume: Fő kötet +network: + placeholder: + password: Jelszó + disconnect: Leválaszt + not_found: Nincsenek hálózatok nem találtak + hidden: Rejtett hálózat + connect: Összekapcsol + more: További hálózati beállítások +settings: + app_settings: Alkalmazásbeállítások + restart: Újrakezd + log_out: Kijelentkezés + shutdown: Leállitás + sleep: Alvás + title: Beállítások +placeholder: + bluetooth_devices: Bluetooth & eszközök + ethernet_connected: internet-hozzáférés + smart_charge: '- Intelligens töltés' + ethernet_disconnected: Nincs internet hozzaferes + settings: Gyors beállítások + open_system_tray: Nyitott rendszer tálca + battery_remaining: '% megmaradt' + volume: Hangerő + open_user_folder: Nyissa meg a felhasználói mappát + notifications: Értesítések diff --git a/src/apps/toolbar/i18n/translations/hy.yml b/src/apps/toolbar/i18n/translations/hy.yml index 1da44fbe..be8b8519 100644 --- a/src/apps/toolbar/i18n/translations/hy.yml +++ b/src/apps/toolbar/i18n/translations/hy.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Մուլտիմեդիա - comunications: Կապի - master_volume: Վարպետի ծավալը - players: Մեդիա նվագարկիչներ - output_device: Արդյունքային սարք - input_device: Մուտքային սարք -network: - placeholder: - password: Գաղտնաբառ - hidden: Թաքնված ցանց - disconnect: Անջատել - more: Ավելի շատ ցանցային պարամետրեր - connect: Միացնել - not_found: Networks անցեր չեն գտնվել -settings: - shutdown: Անջատել - title: Կարգավորումներ - restart: Վերսկսել - log_out: Դուրս գալ - app_settings: Ծրագրի կարգավորումներ - sleep: Քնել -placeholder: - ethernet_connected: Ինտերնետ հասանելիության - open_system_tray: Բաց համակարգի սկուտեղ - volume: Ծավալ - open_user_folder: Բաց օգտագործողի թղթապանակ - battery_remaining: Մնացած - ethernet_disconnected: Ոչ մի ինտերնետ մուտք չկա - settings: Արագ պարամետրեր - bluetooth_devices: Bluetooth & սարքեր - smart_charge: '- Խելացի վճար' - notifications: Ծանուցումներ +media: + device: + multimedia: Մուլտիմեդիա + comunications: Կապի + master_volume: Վարպետի ծավալը + players: Մեդիա նվագարկիչներ + output_device: Արդյունքային սարք + input_device: Մուտքային սարք +network: + placeholder: + password: Գաղտնաբառ + hidden: Թաքնված ցանց + disconnect: Անջատել + more: Ավելի շատ ցանցային պարամետրեր + connect: Միացնել + not_found: Networks անցեր չեն գտնվել +settings: + shutdown: Անջատել + title: Կարգավորումներ + restart: Վերսկսել + log_out: Դուրս գալ + app_settings: Ծրագրի կարգավորումներ + sleep: Քնել +placeholder: + ethernet_connected: Ինտերնետ հասանելիության + open_system_tray: Բաց համակարգի սկուտեղ + volume: Ծավալ + open_user_folder: Բաց օգտագործողի թղթապանակ + battery_remaining: Մնացած + ethernet_disconnected: Ոչ մի ինտերնետ մուտք չկա + settings: Արագ պարամետրեր + bluetooth_devices: Bluetooth & սարքեր + smart_charge: '- Խելացի վճար' + notifications: Ծանուցումներ diff --git a/src/apps/toolbar/i18n/translations/id.yml b/src/apps/toolbar/i18n/translations/id.yml index d54c111e..edfa0726 100644 --- a/src/apps/toolbar/i18n/translations/id.yml +++ b/src/apps/toolbar/i18n/translations/id.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Komunikasi - multimedia: Multimedia - input_device: Alat input - master_volume: Volume utama - players: Pemain Media - output_device: Perangkat output -network: - placeholder: - password: Kata sandi - disconnect: Memutuskan - connect: Menghubung - not_found: Tidak ada jaringan yang ditemukan - hidden: Jaringan tersembunyi - more: Lebih banyak pengaturan jaringan -settings: - restart: Mengulang kembali - app_settings: Pengaturan aplikasi - sleep: Tidur - log_out: Keluar - shutdown: Matikan - title: Pengaturan -placeholder: - volume: Volume - battery_remaining: '% tersisa' - ethernet_disconnected: Tidak ada akses internet - ethernet_connected: Akses internet - settings: Pengaturan Cepat - bluetooth_devices: Bluetooth & perangkat - open_user_folder: Buka folder pengguna - open_system_tray: Baki sistem terbuka - smart_charge: '- Biaya Cerdas' - notifications: Pemberitahuan +media: + device: + comunications: Komunikasi + multimedia: Multimedia + input_device: Alat input + master_volume: Volume utama + players: Pemain Media + output_device: Perangkat output +network: + placeholder: + password: Kata sandi + disconnect: Memutuskan + connect: Menghubung + not_found: Tidak ada jaringan yang ditemukan + hidden: Jaringan tersembunyi + more: Lebih banyak pengaturan jaringan +settings: + restart: Mengulang kembali + app_settings: Pengaturan aplikasi + sleep: Tidur + log_out: Keluar + shutdown: Matikan + title: Pengaturan +placeholder: + volume: Volume + battery_remaining: '% tersisa' + ethernet_disconnected: Tidak ada akses internet + ethernet_connected: Akses internet + settings: Pengaturan Cepat + bluetooth_devices: Bluetooth & perangkat + open_user_folder: Buka folder pengguna + open_system_tray: Baki sistem terbuka + smart_charge: '- Biaya Cerdas' + notifications: Pemberitahuan diff --git a/src/apps/toolbar/i18n/translations/is.yml b/src/apps/toolbar/i18n/translations/is.yml index 13004645..fe539cb4 100644 --- a/src/apps/toolbar/i18n/translations/is.yml +++ b/src/apps/toolbar/i18n/translations/is.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Margmiðlun - comunications: Samskipti - master_volume: Master bindi - output_device: Framleiðsla tæki - input_device: Inntakstæki - players: Fjölmiðla leikmenn -network: - placeholder: - password: Lykilorð - disconnect: Aftengdu - more: Fleiri netstillingar - not_found: Engin net fundust - hidden: Falið net - connect: Tengdu -settings: - restart: Endurræsa - log_out: Að skrá þig út - app_settings: Forritastillingar - title: Stillingar - shutdown: Lokun - sleep: Sofðu -placeholder: - ethernet_connected: internet aðgangur - smart_charge: '- Snjall hleðsla' - bluetooth_devices: Bluetooth og tæki - volume: Bindi - ethernet_disconnected: Enginn internetaðgangur - settings: Fljótar stillingar - open_user_folder: Opna notendamöppu - battery_remaining: '% eftir' - open_system_tray: Opinn kerfisbakki - notifications: Tilkynningar +media: + device: + multimedia: Margmiðlun + comunications: Samskipti + master_volume: Master bindi + output_device: Framleiðsla tæki + input_device: Inntakstæki + players: Fjölmiðla leikmenn +network: + placeholder: + password: Lykilorð + disconnect: Aftengdu + more: Fleiri netstillingar + not_found: Engin net fundust + hidden: Falið net + connect: Tengdu +settings: + restart: Endurræsa + log_out: Að skrá þig út + app_settings: Forritastillingar + title: Stillingar + shutdown: Lokun + sleep: Sofðu +placeholder: + ethernet_connected: internet aðgangur + smart_charge: '- Snjall hleðsla' + bluetooth_devices: Bluetooth og tæki + volume: Bindi + ethernet_disconnected: Enginn internetaðgangur + settings: Fljótar stillingar + open_user_folder: Opna notendamöppu + battery_remaining: '% eftir' + open_system_tray: Opinn kerfisbakki + notifications: Tilkynningar diff --git a/src/apps/toolbar/i18n/translations/it.yml b/src/apps/toolbar/i18n/translations/it.yml index 077d5af7..cf11363c 100644 --- a/src/apps/toolbar/i18n/translations/it.yml +++ b/src/apps/toolbar/i18n/translations/it.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedia - comunications: Comunicazioni - input_device: Dispositivo di input - master_volume: Volume principale - output_device: Dispositivo di uscita - players: Giocatori dei media -network: - placeholder: - password: Parola d'ordine - connect: Collegare - disconnect: Disconnessione - not_found: Nessuna reti trovata - more: Più impostazioni di rete - hidden: Rete nascosta -settings: - restart: Ricomincia - app_settings: Impostazioni dell'app - log_out: Disconnettersi - title: Impostazioni - sleep: Sonno - shutdown: Fermare -placeholder: - ethernet_connected: accesso ad Internet - volume: Volume - ethernet_disconnected: Nessun accesso ad internet - battery_remaining: '% residuo' - settings: Impostazioni rapide - bluetooth_devices: Bluetooth e dispositivi - smart_charge: '- Smart Charge' - open_user_folder: Apri la cartella utente - open_system_tray: Vassoio di sistema aperto - notifications: Notifiche +media: + device: + multimedia: Multimedia + comunications: Comunicazioni + input_device: Dispositivo di input + master_volume: Volume principale + output_device: Dispositivo di uscita + players: Giocatori dei media +network: + placeholder: + password: Parola d'ordine + connect: Collegare + disconnect: Disconnessione + not_found: Nessuna reti trovata + more: Più impostazioni di rete + hidden: Rete nascosta +settings: + restart: Ricomincia + app_settings: Impostazioni dell'app + log_out: Disconnettersi + title: Impostazioni + sleep: Sonno + shutdown: Fermare +placeholder: + ethernet_connected: accesso ad Internet + volume: Volume + ethernet_disconnected: Nessun accesso ad internet + battery_remaining: '% residuo' + settings: Impostazioni rapide + bluetooth_devices: Bluetooth e dispositivi + smart_charge: '- Smart Charge' + open_user_folder: Apri la cartella utente + open_system_tray: Vassoio di sistema aperto + notifications: Notifiche diff --git a/src/apps/toolbar/i18n/translations/ja.yml b/src/apps/toolbar/i18n/translations/ja.yml index 90a6b63a..acce8cfc 100644 --- a/src/apps/toolbar/i18n/translations/ja.yml +++ b/src/apps/toolbar/i18n/translations/ja.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: コミュニケーション - multimedia: マルチメディア - output_device: 出力デバイス - master_volume: マスターボリューム - input_device: 入力デバイス - players: メディアプレーヤー -network: - placeholder: - password: パスワード - connect: 接続 - not_found: ネットワークが見つかりません - hidden: 隠れたネットワーク - more: 詳しい設定 - disconnect: 切断 -settings: - restart: 再起動 - log_out: ログアウト - app_settings: SeelenUIの設定 - shutdown: シャットダウン - sleep: スリープ - title: 設定 -placeholder: - battery_remaining: % 残り - settings: 設定 - open_system_tray: システムトレイを開く - volume: 音量 - ethernet_connected: インターネットアクセス - bluetooth_devices: Bluetoothとデバイス - smart_charge: '- スマートチャージ' - open_user_folder: ユーザーフォルダーを開く - ethernet_disconnected: インターネットアクセスはありません - notifications: 通知 +media: + device: + comunications: コミュニケーション + multimedia: マルチメディア + output_device: 出力デバイス + master_volume: マスターボリューム + input_device: 入力デバイス + players: メディアプレーヤー +network: + placeholder: + password: パスワード + connect: 接続 + not_found: ネットワークが見つかりません + hidden: 隠れたネットワーク + more: 詳しい設定 + disconnect: 切断 +settings: + restart: 再起動 + log_out: ログアウト + app_settings: SeelenUIの設定 + shutdown: シャットダウン + sleep: スリープ + title: 設定 +placeholder: + battery_remaining: % 残り + settings: 設定 + open_system_tray: システムトレイを開く + volume: 音量 + ethernet_connected: インターネット・アクセス + bluetooth_devices: Bluetoothとデバイス + smart_charge: '- スマートチャージ' + open_user_folder: ユーザーフォルダーを開く + ethernet_disconnected: インターネットアクセスはありません + notifications: 通知 diff --git a/src/apps/toolbar/i18n/translations/ka.yml b/src/apps/toolbar/i18n/translations/ka.yml index 7bc8e44f..749f8ae7 100644 --- a/src/apps/toolbar/i18n/translations/ka.yml +++ b/src/apps/toolbar/i18n/translations/ka.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: კომუნიკაცია - multimedia: მულტიმედია - input_device: შეყვანის მოწყობილობა - master_volume: სამაგისტრო ტომი - output_device: გამომავალი მოწყობილობა - players: მედიის მოთამაშეები -network: - placeholder: - password: პაროლი - not_found: ქსელები ვერ მოიძებნა - disconnect: გათიშვა - connect: დაკავშირება - more: მეტი ქსელის პარამეტრები - hidden: დამალული ქსელი -settings: - restart: Რესტარტი - shutdown: Გათიშვა - sleep: ძილი - log_out: შესვლა - app_settings: პროგრამის პარამეტრები - title: პარამეტრები -placeholder: - bluetooth_devices: Bluetooth & მოწყობილობები - battery_remaining: დარჩენილი - ethernet_connected: ინტერნეტი - open_user_folder: გახსენით მომხმარებლის საქაღალდე - open_system_tray: ღია სისტემის უჯრა - volume: ტომი - smart_charge: '- ჭკვიანი მუხტი' - settings: სწრაფი პარამეტრები - ethernet_disconnected: ინტერნეტი არ არის - notifications: შეტყობინებები +media: + device: + comunications: კომუნიკაცია + multimedia: მულტიმედია + input_device: შეყვანის მოწყობილობა + master_volume: სამაგისტრო ტომი + output_device: გამომავალი მოწყობილობა + players: მედიის მოთამაშეები +network: + placeholder: + password: პაროლი + not_found: ქსელები ვერ მოიძებნა + disconnect: გათიშვა + connect: დაკავშირება + more: მეტი ქსელის პარამეტრები + hidden: დამალული ქსელი +settings: + restart: Რესტარტი + shutdown: Გათიშვა + sleep: ძილი + log_out: შესვლა + app_settings: პროგრამის პარამეტრები + title: პარამეტრები +placeholder: + bluetooth_devices: Bluetooth & მოწყობილობები + battery_remaining: დარჩენილი + ethernet_connected: ინტერნეტი + open_user_folder: გახსენით მომხმარებლის საქაღალდე + open_system_tray: ღია სისტემის უჯრა + volume: ტომი + smart_charge: '- ჭკვიანი მუხტი' + settings: სწრაფი პარამეტრები + ethernet_disconnected: ინტერნეტი არ არის + notifications: შეტყობინებები diff --git a/src/apps/toolbar/i18n/translations/km.yml b/src/apps/toolbar/i18n/translations/km.yml index 0b6b7db7..edcb096b 100644 --- a/src/apps/toolbar/i18n/translations/km.yml +++ b/src/apps/toolbar/i18n/translations/km.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: ការអាេយអាេយរយការត្យេដ្ឋ - multimedia: ពហុមេឌា - input_device: ឧបករណ៍បញ្ចូល - output_device: ឧបករណ៍ទិន្នផល - players: អ្នកលេងប្រព័ន្ធផ្សព្វផ្សាយ - master_volume: កម្រិតសំឡេងមេ -network: - placeholder: - password: ហក្យសមងាត់ - not_found: រកមិនឃើញបណ្តាញ - hidden: បណ្តាញដែលលាក់ - connect: តផ្ជាប់ - more: ការកំណត់បណ្តាញច្រើនទៀត - disconnect: ផ្ដាច់ -settings: - shutdown: បិទ - log_out: ចាកចេញ - app_settings: ការកំណត់កម្មវិធី - title: ការកំណត់ - restart: រ្យេដិតនោ - sleep: ដមនេក -placeholder: - battery_remaining: នៅសល់% - ethernet_connected: ការចូលប្រើអ៊ីនធឺណិត - bluetooth_devices: ប៊្លូធូសនិងឧបករណ៍ - open_system_tray: បើកថាសប្រព័ន្ធ - ethernet_disconnected: គ្មានការចូលប្រើអ៊ីនធឺណិតទេ - smart_charge: '- គិតថ្លៃឆ្លាត' - open_user_folder: បើកថតអ្នកប្រើ - volume: ចមនយន - settings: ការកំណត់រហ័ស - notifications: ការជូនដំណឹង +media: + device: + comunications: ការអាេយអាេយរយការត្យេដ្ឋ + multimedia: ពហុមេឌា + input_device: ឧបករណ៍បញ្ចូល + output_device: ឧបករណ៍ទិន្នផល + players: អ្នកលេងប្រព័ន្ធផ្សព្វផ្សាយ + master_volume: កម្រិតសំឡេងមេ +network: + placeholder: + password: ហក្យសមងាត់ + not_found: រកមិនឃើញបណ្តាញ + hidden: បណ្តាញដែលលាក់ + connect: តផ្ជាប់ + more: ការកំណត់បណ្តាញច្រើនទៀត + disconnect: ផ្ដាច់ +settings: + shutdown: បិទ + log_out: ចាកចេញ + app_settings: ការកំណត់កម្មវិធី + title: ការកំណត់ + restart: រ្យេដិតនោ + sleep: ដមនេក +placeholder: + battery_remaining: នៅសល់% + ethernet_connected: ការចូលប្រើអ៊ីនធឺណិត + bluetooth_devices: ប៊្លូធូសនិងឧបករណ៍ + open_system_tray: បើកថាសប្រព័ន្ធ + ethernet_disconnected: គ្មានការចូលប្រើអ៊ីនធឺណិតទេ + smart_charge: '- គិតថ្លៃឆ្លាត' + open_user_folder: បើកថតអ្នកប្រើ + volume: ចមនយន + settings: ការកំណត់រហ័ស + notifications: ការជូនដំណឹង diff --git a/src/apps/toolbar/i18n/translations/ko.yml b/src/apps/toolbar/i18n/translations/ko.yml index 6acc776c..fc083d7f 100644 --- a/src/apps/toolbar/i18n/translations/ko.yml +++ b/src/apps/toolbar/i18n/translations/ko.yml @@ -1,34 +1,34 @@ -media: - master_volume: 마스터 볼륨 - output_device: 출력 장치 - input_device: 입력 장치 - players: 미디어 플레이어 - device: - multimedia: 멀티미디어 - comunications: 통신 -network: - not_found: 네트워크를 찾을 수 없음 - more: 추가 네트워크 설정 - hidden: 숨겨진 네트워크 - placeholder: - password: 비밀번호 - disconnect: 연결 끊기 - connect: 연결 -settings: - title: 설정 - app_settings: 앱 설정 - log_out: 로그아웃 - sleep: 절전 - restart: 다시 시작 - shutdown: 종료 -placeholder: - open_user_folder: 사용자 폴더 열기 - open_system_tray: 시스템 트레이 열기 - bluetooth_devices: 블루투스 및 장치 - ethernet_connected: 인터넷 연결됨 - ethernet_disconnected: 인터넷 연결 안 됨 - volume: 볼륨 - battery_remaining: '% 남음' - smart_charge: ' - 스마트 충전' - settings: 빠른 설정 - notifications: 알림 +media: + master_volume: 마스터 볼륨 + output_device: 출력 장치 + input_device: 입력 장치 + players: 미디어 플레이어 + device: + multimedia: 멀티미디어 + comunications: 통신 +network: + not_found: 네트워크를 찾을 수 없음 + more: 추가 네트워크 설정 + hidden: 숨겨진 네트워크 + placeholder: + password: 비밀번호 + disconnect: 연결 끊기 + connect: 연결 +settings: + title: 설정 + app_settings: 앱 설정 + log_out: 로그아웃 + sleep: 절전 + restart: 다시 시작 + shutdown: 종료 +placeholder: + open_user_folder: 사용자 폴더 열기 + open_system_tray: 시스템 트레이 열기 + bluetooth_devices: 블루투스 및 장치 + ethernet_connected: 인터넷 연결됨 + ethernet_disconnected: 인터넷 연결 안 됨 + volume: 볼륨 + battery_remaining: '% 남음' + smart_charge: ' - 스마트 충전' + settings: 빠른 설정 + notifications: 알림 diff --git a/src/apps/toolbar/i18n/translations/ku.yml b/src/apps/toolbar/i18n/translations/ku.yml index 21800d0d..a5a1ae48 100644 --- a/src/apps/toolbar/i18n/translations/ku.yml +++ b/src/apps/toolbar/i18n/translations/ku.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Têkilî - multimedia: Multimedia - master_volume: Qumarê masterê - output_device: Devera deriyê - input_device: Cîhaza têketinê - players: Lîstikên Medyayê -network: - placeholder: - password: Şîfre - disconnect: Hevqetandin - connect: Bihevgirêdan - hidden: Tora Hidden - more: Mîhengên bêtir torê - not_found: Tora torgilok nehat dîtin -settings: - shutdown: Temirandin - sleep: Xew - log_out: Derkeve - app_settings: Mîhengên App - restart: Destpêkirin - title: Mîhengan -placeholder: - volume: Bend - ethernet_connected: Gihîştina înternetê - open_system_tray: Tray pergala vekirî - smart_charge: '- heqê harm' - bluetooth_devices: Bluetooth & Amûrên - ethernet_disconnected: Ne gihîştina înternetê - open_user_folder: Peldanka Bikarhêner vekirî - settings: Mîhengên Bilez - battery_remaining: '% mayî' - notifications: Notifications +media: + device: + comunications: Têkilî + multimedia: Multimedia + master_volume: Qumarê masterê + output_device: Devera deriyê + input_device: Cîhaza têketinê + players: Lîstikên Medyayê +network: + placeholder: + password: Şîfre + disconnect: Hevqetandin + connect: Bihevgirêdan + hidden: Tora Hidden + more: Mîhengên bêtir torê + not_found: Tora torgilok nehat dîtin +settings: + shutdown: Temirandin + sleep: Xew + log_out: Derkeve + app_settings: Mîhengên App + restart: Destpêkirin + title: Mîhengan +placeholder: + volume: Bend + ethernet_connected: Gihîştina înternetê + open_system_tray: Tray pergala vekirî + smart_charge: '- heqê harm' + bluetooth_devices: Bluetooth & Amûrên + ethernet_disconnected: Ne gihîştina înternetê + open_user_folder: Peldanka Bikarhêner vekirî + settings: Mîhengên Bilez + battery_remaining: '% mayî' + notifications: Notifications diff --git a/src/apps/toolbar/i18n/translations/lb.yml b/src/apps/toolbar/i18n/translations/lb.yml index 64984012..b56b2e9d 100644 --- a/src/apps/toolbar/i18n/translations/lb.yml +++ b/src/apps/toolbar/i18n/translations/lb.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Kommunikatiounen - multimedia: Multimedia - players: Media Spiller - master_volume: Master Volumen - output_device: Ausgangsapparat - input_device: Input Apparat -network: - placeholder: - password: Passwuert - not_found: Keng Netzwierker fonnt - disconnect: Trennen - hidden: Verstoppt Netzwierk - more: Méi Netzwierk Astellunge - connect: Connecten -settings: - restart: Neistart - shutdown: Ausmaachen - log_out: Ausloggen - app_settings: App Astellunge - title: Astellunge - sleep: Schlolof -placeholder: - battery_remaining: '% bleiwen' - bluetooth_devices: Bluetooth & Apparater - open_system_tray: Open System Schacht - settings: Quick Astellungen - smart_charge: '- Smart charge' - open_user_folder: Open Benotzer Ordner - ethernet_connected: Internet Zougang - ethernet_disconnected: Keen Internetzougang - volume: Vuesso - notifications: Notifikatiounen +media: + device: + comunications: Kommunikatiounen + multimedia: Multimedia + players: Media Spiller + master_volume: Master Volumen + output_device: Ausgangsapparat + input_device: Input Apparat +network: + placeholder: + password: Passwuert + not_found: Keng Netzwierker fonnt + disconnect: Trennen + hidden: Verstoppt Netzwierk + more: Méi Netzwierk Astellunge + connect: Connecten +settings: + restart: Neistart + shutdown: Ausmaachen + log_out: Ausloggen + app_settings: App Astellunge + title: Astellunge + sleep: Schlolof +placeholder: + battery_remaining: '% bleiwen' + bluetooth_devices: Bluetooth & Apparater + open_system_tray: Open System Schacht + settings: Quick Astellungen + smart_charge: '- Smart charge' + open_user_folder: Open Benotzer Ordner + ethernet_connected: Internet Zougang + ethernet_disconnected: Keen Internetzougang + volume: Vuesso + notifications: Notifikatiounen diff --git a/src/apps/toolbar/i18n/translations/lo.yml b/src/apps/toolbar/i18n/translations/lo.yml index 13e62a46..779040e3 100644 --- a/src/apps/toolbar/i18n/translations/lo.yml +++ b/src/apps/toolbar/i18n/translations/lo.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: ໂມສອນເຄີຍີຫໍ້ - comunications: ການສື່ສານ - master_volume: ປະລິມານຕົ້ນສະບັບ - output_device: ອຸປະກອນຜົນໄດ້ຮັບ - players: ເຄື່ອງຫຼີ້ນສື່ - input_device: ອຸປະກອນປ້ອນຂໍ້ມູນ -network: - placeholder: - password: ລະຫັດຜ່ານ - disconnect: ຕັດຂາດ - hidden: ເຄືອຂ່າຍທີ່ເຊື່ອງໄວ້ - not_found: ບໍ່ພົບເຄືອຂ່າຍທີ່ພົບ - more: ການຕັ້ງຄ່າເຄືອຂ່າຍເພີ່ມເຕີມ - connect: ເຊື່ອມຕໍ່ -settings: - shutdown: ປິດ​ເຄື່ອງ - restart: ເລີ່ມ​ຕົ້ນ​ໃຫມ່ - log_out: ອອກ​ຈາກ​ລະ​ບົບ - title: ການກໍານົດ - app_settings: ການຕັ້ງຄ່າແອັບ app - sleep: ນອນ -placeholder: - ethernet_connected: ການ​ເຂົ້າ​ເຖິງ​ອິນ​ເຕີ​ເນັດ - smart_charge: '- ຮັບຜິດຊອບສະຫຼາດ' - battery_remaining: ສ່ວນທີ່ເຫຼືອ - volume: ປະລິມານ - open_system_tray: ເປີດຖາດລະບົບ - open_user_folder: ເປີດໂຟນເດີຜູ້ໃຊ້ - ethernet_disconnected: ບໍ່ມີການເຂົ້າເຖິງອິນເຕີເນັດ - bluetooth_devices: Bluetooth & ອຸປະກອນ - settings: ການຕັ້ງຄ່າດ່ວນ - notifications: ແຈ້ງການ +media: + device: + multimedia: ໂມສອນເຄີຍີຫໍ້ + comunications: ການສື່ສານ + master_volume: ປະລິມານຕົ້ນສະບັບ + output_device: ອຸປະກອນຜົນໄດ້ຮັບ + players: ເຄື່ອງຫຼີ້ນສື່ + input_device: ອຸປະກອນປ້ອນຂໍ້ມູນ +network: + placeholder: + password: ລະຫັດຜ່ານ + disconnect: ຕັດຂາດ + hidden: ເຄືອຂ່າຍທີ່ເຊື່ອງໄວ້ + not_found: ບໍ່ພົບເຄືອຂ່າຍທີ່ພົບ + more: ການຕັ້ງຄ່າເຄືອຂ່າຍເພີ່ມເຕີມ + connect: ເຊື່ອມຕໍ່ +settings: + shutdown: ປິດ​ເຄື່ອງ + restart: ເລີ່ມ​ຕົ້ນ​ໃຫມ່ + log_out: ອອກ​ຈາກ​ລະ​ບົບ + title: ການກໍານົດ + app_settings: ການຕັ້ງຄ່າແອັບ app + sleep: ນອນ +placeholder: + ethernet_connected: ການ​ເຂົ້າ​ເຖິງ​ອິນ​ເຕີ​ເນັດ + smart_charge: '- ຮັບຜິດຊອບສະຫຼາດ' + battery_remaining: ສ່ວນທີ່ເຫຼືອ + volume: ປະລິມານ + open_system_tray: ເປີດຖາດລະບົບ + open_user_folder: ເປີດໂຟນເດີຜູ້ໃຊ້ + ethernet_disconnected: ບໍ່ມີການເຂົ້າເຖິງອິນເຕີເນັດ + bluetooth_devices: Bluetooth & ອຸປະກອນ + settings: ການຕັ້ງຄ່າດ່ວນ + notifications: ແຈ້ງການ diff --git a/src/apps/toolbar/i18n/translations/lt.yml b/src/apps/toolbar/i18n/translations/lt.yml index 523b3587..1e0a4eaf 100644 --- a/src/apps/toolbar/i18n/translations/lt.yml +++ b/src/apps/toolbar/i18n/translations/lt.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Ryšiai - multimedia: Multimedija - master_volume: Pagrindinis garsas - input_device: Įvesties įrenginys - output_device: Išvesties įrenginys - players: Žiniasklaidos žaidėjai -network: - placeholder: - password: Slaptažodis - disconnect: Atjungti - connect: Prisijungti - not_found: Jokių tinklų nerasta - more: Daugiau tinklo nustatymų - hidden: Paslėptas tinklas -settings: - log_out: Atsijungti - restart: Perkrauti - shutdown: Išjungti - app_settings: Programos nustatymai - sleep: Miegas - title: Nustatymai -placeholder: - settings: Greiti nustatymai - smart_charge: '- Išmanus mokestis' - ethernet_connected: Interneto ryšys - open_system_tray: Atviras sistemos dėklas - battery_remaining: '% liko' - ethernet_disconnected: Jokios interneto prieigos - volume: Apimtis - bluetooth_devices: „Bluetooth“ ir įrenginiai - open_user_folder: Atidaryti vartotojo aplanką - notifications: Pranešimai +media: + device: + comunications: Ryšiai + multimedia: Multimedija + master_volume: Pagrindinis garsas + input_device: Įvesties įrenginys + output_device: Išvesties įrenginys + players: Žiniasklaidos žaidėjai +network: + placeholder: + password: Slaptažodis + disconnect: Atjungti + connect: Prisijungti + not_found: Jokių tinklų nerasta + more: Daugiau tinklo nustatymų + hidden: Paslėptas tinklas +settings: + log_out: Atsijungti + restart: Perkrauti + shutdown: Išjungti + app_settings: Programos nustatymai + sleep: Miegas + title: Nustatymai +placeholder: + settings: Greiti nustatymai + smart_charge: '- Išmanus mokestis' + ethernet_connected: Interneto ryšys + open_system_tray: Atviras sistemos dėklas + battery_remaining: '% liko' + ethernet_disconnected: Jokios interneto prieigos + volume: Apimtis + bluetooth_devices: „Bluetooth“ ir įrenginiai + open_user_folder: Atidaryti vartotojo aplanką + notifications: Pranešimai diff --git a/src/apps/toolbar/i18n/translations/lv.yml b/src/apps/toolbar/i18n/translations/lv.yml index 7d9a92b0..de4ad4c3 100644 --- a/src/apps/toolbar/i18n/translations/lv.yml +++ b/src/apps/toolbar/i18n/translations/lv.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedija - comunications: Sakari - input_device: Ievades ierīce - master_volume: Master tilpums - players: Plašsaziņas līdzekļu spēlētāji - output_device: Izvades ierīce -network: - placeholder: - password: Parole - disconnect: Atvienot - connect: Savienot - hidden: Slēpts tīkls - more: Vairāk tīkla iestatījumu - not_found: Neto atrasti tīkli -settings: - log_out: Izlogoties - sleep: Gulēt - shutdown: Izslēgt - title: Iestatījumi - restart: Restartēt - app_settings: Lietotņu iestatījumi -placeholder: - settings: Ātrie iestatījumi - battery_remaining: '% atliekas' - ethernet_connected: Interneta pieslēgums - smart_charge: '- Viedā maksa' - open_user_folder: Atveriet lietotāja mapi - open_system_tray: Atvērtā sistēmas paplāte - bluetooth_devices: Bluetooth & ierīces - volume: Tilpums - ethernet_disconnected: Nav piekļuves internetam - notifications: Paziņojumi +media: + device: + multimedia: Multimedija + comunications: Sakari + input_device: Ievades ierīce + master_volume: Master tilpums + players: Plašsaziņas līdzekļu spēlētāji + output_device: Izvades ierīce +network: + placeholder: + password: Parole + disconnect: Atvienot + connect: Savienot + hidden: Slēpts tīkls + more: Vairāk tīkla iestatījumu + not_found: Neto atrasti tīkli +settings: + log_out: Izlogoties + sleep: Gulēt + shutdown: Izslēgt + title: Iestatījumi + restart: Restartēt + app_settings: Lietotņu iestatījumi +placeholder: + settings: Ātrie iestatījumi + battery_remaining: '% atliekas' + ethernet_connected: Interneta pieslēgums + smart_charge: '- Viedā maksa' + open_user_folder: Atveriet lietotāja mapi + open_system_tray: Atvērtā sistēmas paplāte + bluetooth_devices: Bluetooth & ierīces + volume: Tilpums + ethernet_disconnected: Nav piekļuves internetam + notifications: Paziņojumi diff --git a/src/apps/toolbar/i18n/translations/mk.yml b/src/apps/toolbar/i18n/translations/mk.yml index 723d072c..d664b63d 100644 --- a/src/apps/toolbar/i18n/translations/mk.yml +++ b/src/apps/toolbar/i18n/translations/mk.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Мултимедија - comunications: Комуникации - input_device: Влезен уред - output_device: Излезен уред - master_volume: Господар волумен - players: Медиа плеери -network: - placeholder: - password: Лозинка - hidden: Скриена мрежа - not_found: Не се пронајдени мрежи - disconnect: Исклучување - connect: Поврзете се - more: Повеќе мрежни поставки -settings: - shutdown: Исклучи - restart: Рестарт - log_out: Одјавете се - app_settings: Поставки за апликации - title: Поставки - sleep: Спиење -placeholder: - ethernet_connected: Интернет пристап - volume: Волумен - settings: Брзи поставки - bluetooth_devices: Bluetooth & уреди - battery_remaining: Останатите % - smart_charge: '- Паметно полнење' - open_system_tray: Отворен фиока за систем - open_user_folder: Отворете ја папката за корисници - ethernet_disconnected: Нема пристап до Интернет - notifications: Известувања +media: + device: + multimedia: Мултимедија + comunications: Комуникации + input_device: Влезен уред + output_device: Излезен уред + master_volume: Господар волумен + players: Медиа плеери +network: + placeholder: + password: Лозинка + hidden: Скриена мрежа + not_found: Не се пронајдени мрежи + disconnect: Исклучување + connect: Поврзете се + more: Повеќе мрежни поставки +settings: + shutdown: Исклучи + restart: Рестарт + log_out: Одјавете се + app_settings: Поставки за апликации + title: Поставки + sleep: Спиење +placeholder: + ethernet_connected: Интернет пристап + volume: Волумен + settings: Брзи поставки + bluetooth_devices: Bluetooth & уреди + battery_remaining: Останатите % + smart_charge: '- Паметно полнење' + open_system_tray: Отворен фиока за систем + open_user_folder: Отворете ја папката за корисници + ethernet_disconnected: Нема пристап до Интернет + notifications: Известувања diff --git a/src/apps/toolbar/i18n/translations/mn.yml b/src/apps/toolbar/i18n/translations/mn.yml index 7a1d38da..5c0171cd 100644 --- a/src/apps/toolbar/i18n/translations/mn.yml +++ b/src/apps/toolbar/i18n/translations/mn.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Харилцаа - multimedia: Multimiedia - input_device: Оролтын төхөөрөмж - master_volume: Мэргэжч - players: Хэвлэл хэвлэл тоглогч - output_device: Гаралтын төхөөрөмж -network: - placeholder: - password: Нууц үг - not_found: Сүлжээ олдсонгүй - hidden: Цэг сонссон сүлж - disconnect: Тусгаарлах - connect: Холбох - more: Сүлжээний илүү олон тохиргоо -settings: - shutdown: Унтраах - restart: Дахин ачааллах - log_out: Гарах - app_settings: Дуулахын тохиргоо - title: Тохиргоо - sleep: Нойр -placeholder: - battery_remaining: '% үлдсэн' - volume: Хэмжээ - open_user_folder: Хэрэглэгчийн чиглэлд - smart_charge: '- ухаалаг цэнэг' - settings: Түлэлцэн тохиргоо - open_system_tray: Нээлттэй системийн тавиур - bluetooth_devices: Блютүүт ба төхөөрөмж - ethernet_disconnected: Интернэтэд нэвтрэх боломжгүй байна - ethernet_connected: Интернэт интернет нэвтрэх - notifications: Мэдэгдэл +media: + device: + comunications: Харилцаа + multimedia: Multimiedia + input_device: Оролтын төхөөрөмж + master_volume: Мэргэжч + players: Хэвлэл хэвлэл тоглогч + output_device: Гаралтын төхөөрөмж +network: + placeholder: + password: Нууц үг + not_found: Сүлжээ олдсонгүй + hidden: Цэг сонссон сүлж + disconnect: Тусгаарлах + connect: Холбох + more: Сүлжээний илүү олон тохиргоо +settings: + shutdown: Унтраах + restart: Дахин ачааллах + log_out: Гарах + app_settings: Дуулахын тохиргоо + title: Тохиргоо + sleep: Нойр +placeholder: + battery_remaining: '% үлдсэн' + volume: Хэмжээ + open_user_folder: Хэрэглэгчийн чиглэлд + smart_charge: '- ухаалаг цэнэг' + settings: Түлэлцэн тохиргоо + open_system_tray: Нээлттэй системийн тавиур + bluetooth_devices: Блютүүт ба төхөөрөмж + ethernet_disconnected: Интернэтэд нэвтрэх боломжгүй байна + ethernet_connected: Интернэт интернет нэвтрэх + notifications: Мэдэгдэл diff --git a/src/apps/toolbar/i18n/translations/ms.yml b/src/apps/toolbar/i18n/translations/ms.yml index 6af879fb..b869c26d 100644 --- a/src/apps/toolbar/i18n/translations/ms.yml +++ b/src/apps/toolbar/i18n/translations/ms.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedia - comunications: Komunikasi - output_device: Peranti output - input_device: Peranti input - master_volume: Volume Master - players: Pemain media -network: - placeholder: - password: Kata laluan - more: Lebih banyak tetapan rangkaian - disconnect: Putuskan sambungan - hidden: Rangkaian Tersembunyi - not_found: Tiada rangkaian dijumpai - connect: Sambung -settings: - shutdown: Menutup - log_out: Log keluar - restart: Mula semula - sleep: Tidur - app_settings: Tetapan aplikasi - title: Tetapan -placeholder: - bluetooth_devices: Bluetooth & peranti - volume: Kelantangan - smart_charge: '- Caj pintar' - open_system_tray: Buka dulang sistem - ethernet_connected: akses internet - open_user_folder: Buka folder pengguna - battery_remaining: '% tinggal' - settings: Tetapan cepat - ethernet_disconnected: Tiada akses Internet - notifications: Pemberitahuan +media: + device: + multimedia: Multimedia + comunications: Komunikasi + output_device: Peranti output + input_device: Peranti input + master_volume: Volume Master + players: Pemain media +network: + placeholder: + password: Kata laluan + more: Lebih banyak tetapan rangkaian + disconnect: Putuskan sambungan + hidden: Rangkaian Tersembunyi + not_found: Tiada rangkaian dijumpai + connect: Sambung +settings: + shutdown: Menutup + log_out: Log keluar + restart: Mula semula + sleep: Tidur + app_settings: Tetapan aplikasi + title: Tetapan +placeholder: + bluetooth_devices: Bluetooth & peranti + volume: Kelantangan + smart_charge: '- Caj pintar' + open_system_tray: Buka dulang sistem + ethernet_connected: akses internet + open_user_folder: Buka folder pengguna + battery_remaining: '% tinggal' + settings: Tetapan cepat + ethernet_disconnected: Tiada akses Internet + notifications: Pemberitahuan diff --git a/src/apps/toolbar/i18n/translations/mt.yml b/src/apps/toolbar/i18n/translations/mt.yml index 53633fd2..c615e24c 100644 --- a/src/apps/toolbar/i18n/translations/mt.yml +++ b/src/apps/toolbar/i18n/translations/mt.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Komunikazzjonijiet - multimedia: Multimedja - master_volume: Volum Master - players: Plejers tal-midja - output_device: Apparat tal-ħruġ - input_device: Apparat ta 'input -network: - placeholder: - password: Password - connect: Qabbad - not_found: Ma nstabu l-ebda netwerks - disconnect: Skonnettja - hidden: Netwerk moħbi - more: Aktar settings tan-netwerk -settings: - restart: Erġa ibda - shutdown: Għalaq - log_out: Oħroġ - title: Settings - sleep: Irqad - app_settings: Settings tal-App -placeholder: - open_user_folder: Folder tal-utent miftuħ - settings: Settings ta 'malajr - ethernet_connected: Aċċess għall-Internet - ethernet_disconnected: L-ebda aċċess għall-internet - smart_charge: '- ħlas intelliġenti' - bluetooth_devices: Bluetooth & Apparat - battery_remaining: '% jibqa ''' - open_system_tray: Tray tas-Sistema Miftuħa - volume: Volum - notifications: Notifiki +media: + device: + comunications: Komunikazzjonijiet + multimedia: Multimedja + master_volume: Volum Master + players: Plejers tal-midja + output_device: Apparat tal-ħruġ + input_device: Apparat ta 'input +network: + placeholder: + password: Password + connect: Qabbad + not_found: Ma nstabu l-ebda netwerks + disconnect: Skonnettja + hidden: Netwerk moħbi + more: Aktar settings tan-netwerk +settings: + restart: Erġa ibda + shutdown: Għalaq + log_out: Oħroġ + title: Settings + sleep: Irqad + app_settings: Settings tal-App +placeholder: + open_user_folder: Folder tal-utent miftuħ + settings: Settings ta 'malajr + ethernet_connected: Aċċess għall-Internet + ethernet_disconnected: L-ebda aċċess għall-internet + smart_charge: '- ħlas intelliġenti' + bluetooth_devices: Bluetooth & Apparat + battery_remaining: '% jibqa ''' + open_system_tray: Tray tas-Sistema Miftuħa + volume: Volum + notifications: Notifiki diff --git a/src/apps/toolbar/i18n/translations/ne.yml b/src/apps/toolbar/i18n/translations/ne.yml index 187edb21..6e958bd0 100644 --- a/src/apps/toolbar/i18n/translations/ne.yml +++ b/src/apps/toolbar/i18n/translations/ne.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: संचार - multimedia: मल्टिमेडिया - input_device: इनपुट उपकरण - output_device: आउटपुट उपकरण - master_volume: मास्टर भोल्युम - players: मिडिया खेलाडीहरु -network: - placeholder: - password: संकेत शब्द - disconnect: अलग गनु - not_found: कुनै नेटवर्क फेला परेन - hidden: लुकेको नेटवर्क - more: अधिक नेटवर्क सेटिंग्स - connect: जोड्नु -settings: - shutdown: बन्द गर - restart: फेरि शुरु गर्नु - log_out: बाहिर निस्कनु - app_settings: अनुप्रयोग सेटिंग्स - title: बतंग - sleep: निदाउनु -placeholder: - ethernet_connected: इन्टरनेट पहुँच - smart_charge: '- स्मार्ट शुल्क' - bluetooth_devices: ब्लुटुथ र उपकरणहरू - ethernet_disconnected: कुनै इन्टर्नेट पहुँच छैन - open_user_folder: प्रयोगकर्ता फोल्डर खोल्नुहोस् - volume: आवाज - open_system_tray: खुला प्रणाली ट्रे - battery_remaining: '% बाँकी' - settings: द्रुत सेटिंग्स - notifications: सूचना +media: + device: + comunications: संचार + multimedia: मल्टिमेडिया + input_device: इनपुट उपकरण + output_device: आउटपुट उपकरण + master_volume: मास्टर भोल्युम + players: मिडिया खेलाडीहरु +network: + placeholder: + password: संकेत शब्द + disconnect: अलग गनु + not_found: कुनै नेटवर्क फेला परेन + hidden: लुकेको नेटवर्क + more: अधिक नेटवर्क सेटिंग्स + connect: जोड्नु +settings: + shutdown: बन्द गर + restart: फेरि शुरु गर्नु + log_out: बाहिर निस्कनु + app_settings: अनुप्रयोग सेटिंग्स + title: बतंग + sleep: निदाउनु +placeholder: + ethernet_connected: इन्टरनेट पहुँच + smart_charge: '- स्मार्ट शुल्क' + bluetooth_devices: ब्लुटुथ र उपकरणहरू + ethernet_disconnected: कुनै इन्टर्नेट पहुँच छैन + open_user_folder: प्रयोगकर्ता फोल्डर खोल्नुहोस् + volume: आवाज + open_system_tray: खुला प्रणाली ट्रे + battery_remaining: '% बाँकी' + settings: द्रुत सेटिंग्स + notifications: सूचना diff --git a/src/apps/toolbar/i18n/translations/nl.yml b/src/apps/toolbar/i18n/translations/nl.yml index f269c2c6..684593a8 100644 --- a/src/apps/toolbar/i18n/translations/nl.yml +++ b/src/apps/toolbar/i18n/translations/nl.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedia - comunications: Communicatie - output_device: Uitvoerapparaat - input_device: Invoerapparaat - master_volume: Meester volume - players: Media -spelers -network: - placeholder: - password: Wachtwoord - not_found: Geen netwerken gevonden - connect: Aansluiten - more: Meer netwerkinstellingen - hidden: Verborgen netwerk - disconnect: Loskoppelen -settings: - app_settings: App instellingen - shutdown: Afsluiten - title: Instellingen - log_out: Uitloggen - restart: Herstarten - sleep: Slaap -placeholder: - settings: Snelle instellingen - ethernet_disconnected: Geen toegang tot het internet - battery_remaining: '% overig' - volume: Volume - ethernet_connected: internet toegang - open_user_folder: Open de gebruikersmap - bluetooth_devices: Bluetooth & apparaten - open_system_tray: Open systeemlade - smart_charge: '- Slimme lading' - notifications: Meldingen +media: + device: + multimedia: Multimedia + comunications: Communicatie + output_device: Uitvoerapparaat + input_device: Invoerapparaat + master_volume: Meester volume + players: Media -spelers +network: + placeholder: + password: Wachtwoord + not_found: Geen netwerken gevonden + connect: Aansluiten + more: Meer netwerkinstellingen + hidden: Verborgen netwerk + disconnect: Loskoppelen +settings: + app_settings: App instellingen + shutdown: Afsluiten + title: Instellingen + log_out: Uitloggen + restart: Herstarten + sleep: Slaap +placeholder: + settings: Snelle instellingen + ethernet_disconnected: Geen toegang tot het internet + battery_remaining: '% overig' + volume: Volume + ethernet_connected: internet toegang + open_user_folder: Open de gebruikersmap + bluetooth_devices: Bluetooth & apparaten + open_system_tray: Open systeemlade + smart_charge: '- Slimme lading' + notifications: Meldingen diff --git a/src/apps/toolbar/i18n/translations/no.yml b/src/apps/toolbar/i18n/translations/no.yml index 6fe1df5d..6b0e61b2 100644 --- a/src/apps/toolbar/i18n/translations/no.yml +++ b/src/apps/toolbar/i18n/translations/no.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedia - comunications: Kommunikasjon - master_volume: Hovedvolum - output_device: Utgangsenhet - input_device: Inngangsenhet - players: Mediespillere -network: - placeholder: - password: Passord - connect: Koble - disconnect: Koble fra - more: Flere nettverksinnstillinger - hidden: Skjult nettverk - not_found: Ingen nettverk funnet -settings: - restart: Omstart - shutdown: Skru av - log_out: Logg ut - sleep: Sove - app_settings: Appinnstillinger - title: Innstillinger -placeholder: - battery_remaining: '% gjenstående' - volume: Volum - ethernet_connected: Internettilgang - bluetooth_devices: Bluetooth & Devices - settings: Raske innstillinger - smart_charge: '- Smart kostnad' - open_system_tray: Åpent systembrett - ethernet_disconnected: Ingen internettilgang - open_user_folder: Åpne brukermappe - notifications: Varsler +media: + device: + multimedia: Multimedia + comunications: Kommunikasjon + master_volume: Hovedvolum + output_device: Utgangsenhet + input_device: Inngangsenhet + players: Mediespillere +network: + placeholder: + password: Passord + connect: Koble + disconnect: Koble fra + more: Flere nettverksinnstillinger + hidden: Skjult nettverk + not_found: Ingen nettverk funnet +settings: + restart: Omstart + shutdown: Skru av + log_out: Logg ut + sleep: Sove + app_settings: Appinnstillinger + title: Innstillinger +placeholder: + battery_remaining: '% gjenstående' + volume: Volum + ethernet_connected: Internettilgang + bluetooth_devices: Bluetooth & Devices + settings: Raske innstillinger + smart_charge: '- Smart kostnad' + open_system_tray: Åpent systembrett + ethernet_disconnected: Ingen internettilgang + open_user_folder: Åpne brukermappe + notifications: Varsler diff --git a/src/apps/toolbar/i18n/translations/pa.yml b/src/apps/toolbar/i18n/translations/pa.yml index 5c950cb1..4b7459d5 100644 --- a/src/apps/toolbar/i18n/translations/pa.yml +++ b/src/apps/toolbar/i18n/translations/pa.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: ਸੰਚਾਰ - multimedia: ਮਲਟੀਮੀਡੀਆ - input_device: ਇਨਪੁਟ ਡਿਵਾਈਸ - players: ਮੀਡੀਆ ਪਲੇਅਰ - output_device: ਆਉਟਪੁੱਟ ਜੰਤਰ - master_volume: ਮਾਸਟਰ ਵਾਲੀਅਮ -network: - placeholder: - password: ਪਾਸਵਰਡ - hidden: ਲੁਕਿਆ ਹੋਇਆ ਨੈਟਵਰਕ - not_found: ਕੋਈ ਨੈੱਟਵਰਕ ਨਹੀਂ ਮਿਲਿਆ - disconnect: ਡਿਸਕਨੈਕਟ - connect: ਕਨੈਕਟ ਕਰੋ - more: ਹੋਰ ਨੈੱਟਵਰਕ ਸੈਟਿੰਗਾਂ -settings: - shutdown: ਸ਼ਟ ਡਾਉਨ - title: ਸੈਟਿੰਗਜ਼ - log_out: ਲਾੱਗ ਆਊਟ, ਬਾਹਰ ਆਉਣਾ - app_settings: ਐਪ ਸੈਟਿੰਗਾਂ - sleep: ਨੀਂਦ - restart: ਰੀਸਟਾਰਟ -placeholder: - ethernet_connected: ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ - smart_charge: '- ਸਮਾਰਟ ਚਾਰਜ' - open_user_folder: ਓਪਨ ਯੂਜ਼ਰ ਫੋਲਡਰ - volume: ਵਾਲੀਅਮ - battery_remaining: '% ਬਾਕੀ' - ethernet_disconnected: ਕੋਈ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ - bluetooth_devices: ਬਲਿ Bluetooth ਟੁੱਥ ਅਤੇ ਉਪਕਰਣ - settings: ਤੇਜ਼ ਸੈਟਿੰਗ - open_system_tray: ਸਿਸਟਮ ਟਰੇ ਖੋਲ੍ਹੋ - notifications: ਸੂਚਨਾਵਾਂ +media: + device: + comunications: ਸੰਚਾਰ + multimedia: ਮਲਟੀਮੀਡੀਆ + input_device: ਇਨਪੁਟ ਡਿਵਾਈਸ + players: ਮੀਡੀਆ ਪਲੇਅਰ + output_device: ਆਉਟਪੁੱਟ ਜੰਤਰ + master_volume: ਮਾਸਟਰ ਵਾਲੀਅਮ +network: + placeholder: + password: ਪਾਸਵਰਡ + hidden: ਲੁਕਿਆ ਹੋਇਆ ਨੈਟਵਰਕ + not_found: ਕੋਈ ਨੈੱਟਵਰਕ ਨਹੀਂ ਮਿਲਿਆ + disconnect: ਡਿਸਕਨੈਕਟ + connect: ਕਨੈਕਟ ਕਰੋ + more: ਹੋਰ ਨੈੱਟਵਰਕ ਸੈਟਿੰਗਾਂ +settings: + shutdown: ਸ਼ਟ ਡਾਉਨ + title: ਸੈਟਿੰਗਜ਼ + log_out: ਲਾੱਗ ਆਊਟ, ਬਾਹਰ ਆਉਣਾ + app_settings: ਐਪ ਸੈਟਿੰਗਾਂ + sleep: ਨੀਂਦ + restart: ਰੀਸਟਾਰਟ +placeholder: + ethernet_connected: ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ + smart_charge: '- ਸਮਾਰਟ ਚਾਰਜ' + open_user_folder: ਓਪਨ ਯੂਜ਼ਰ ਫੋਲਡਰ + volume: ਵਾਲੀਅਮ + battery_remaining: '% ਬਾਕੀ' + ethernet_disconnected: ਕੋਈ ਇੰਟਰਨੈੱਟ ਪਹੁੰਚ ਨਹੀਂ + bluetooth_devices: ਬਲਿ Bluetooth ਟੁੱਥ ਅਤੇ ਉਪਕਰਣ + settings: ਤੇਜ਼ ਸੈਟਿੰਗ + open_system_tray: ਸਿਸਟਮ ਟਰੇ ਖੋਲ੍ਹੋ + notifications: ਸੂਚਨਾਵਾਂ diff --git a/src/apps/toolbar/i18n/translations/pl.yml b/src/apps/toolbar/i18n/translations/pl.yml index 4e2db9f8..5812325f 100644 --- a/src/apps/toolbar/i18n/translations/pl.yml +++ b/src/apps/toolbar/i18n/translations/pl.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedia - comunications: Komunikacja - master_volume: Głośność - input_device: Urządzenie wejściowe - output_device: Urządzenie wyjściowe - players: Gracze multimedialni -network: - placeholder: - password: Hasło - disconnect: Rozłączyć się - connect: Łączyć - not_found: Nie znaleziono sieci - more: Więcej ustawień sieciowych - hidden: Ukryta sieć -settings: - app_settings: Ustawienia aplikacji - log_out: Wyloguj - title: Ustawienia - sleep: Spać - shutdown: Zamknięcie - restart: Uruchom ponownie -placeholder: - ethernet_connected: dostęp do Internetu - battery_remaining: '% pozostały' - volume: Tom - bluetooth_devices: Bluetooth i urządzenia - settings: Szybkie ustawienia - ethernet_disconnected: Brak dostępu do internetu - smart_charge: '- Inteligentny ładunek' - open_user_folder: Otwórz folder użytkownika - open_system_tray: Otwórz tacę systemową - notifications: Powiadomienia +media: + device: + multimedia: Multimedia + comunications: Komunikacja + master_volume: Głośność + input_device: Urządzenie wejściowe + output_device: Urządzenie wyjściowe + players: Gracze multimedialni +network: + placeholder: + password: Hasło + disconnect: Rozłączyć się + connect: Łączyć + not_found: Nie znaleziono sieci + more: Więcej ustawień sieciowych + hidden: Ukryta sieć +settings: + app_settings: Ustawienia aplikacji + log_out: Wyloguj + title: Ustawienia + sleep: Spać + shutdown: Zamknięcie + restart: Uruchom ponownie +placeholder: + ethernet_connected: dostęp do Internetu + battery_remaining: '% pozostały' + volume: Tom + bluetooth_devices: Bluetooth i urządzenia + settings: Szybkie ustawienia + ethernet_disconnected: Brak dostępu do internetu + smart_charge: '- Inteligentny ładunek' + open_user_folder: Otwórz folder użytkownika + open_system_tray: Otwórz tacę systemową + notifications: Powiadomienia diff --git a/src/apps/toolbar/i18n/translations/ps.yml b/src/apps/toolbar/i18n/translations/ps.yml index f004dc47..655f033f 100644 --- a/src/apps/toolbar/i18n/translations/ps.yml +++ b/src/apps/toolbar/i18n/translations/ps.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: مخابرات - multimedia: ملټي میډیا - input_device: ننوتنی وسیله - players: د میډیا لوبغاړي - master_volume: ماسټر برابره - output_device: د محصول وسیله -network: - placeholder: - password: رمز - connect: نښلول - not_found: هیڅ جال ونه موندل شو - hidden: پټه شبکه - more: نور د شبکې تنظیمات - disconnect: منحل -settings: - restart: بیا روښانه کول - shutdown: ‍‍‍بندول - log_out: وتل - title: امستنې - sleep: ویده شه - app_settings: د ایپ امستنې -placeholder: - smart_charge: '- سمارټ چارج' - ethernet_disconnected: هیڅ انټرنیټ لاسرسی - battery_remaining: ٪ پاتې - ethernet_connected: انټرنیټ لاسرسی - open_system_tray: د خلاص سیسټم ټری - bluetooth_devices: بلوتوث او وسایل - volume: حجم - open_user_folder: د کارونکي فولډر خلاص کړئ - settings: ګړندي امستنې - notifications: خبرتیاوې +media: + device: + comunications: مخابرات + multimedia: ملټي میډیا + input_device: ننوتنی وسیله + players: د میډیا لوبغاړي + master_volume: ماسټر برابره + output_device: د محصول وسیله +network: + placeholder: + password: رمز + connect: نښلول + not_found: هیڅ جال ونه موندل شو + hidden: پټه شبکه + more: نور د شبکې تنظیمات + disconnect: منحل +settings: + restart: بیا روښانه کول + shutdown: ‍‍‍بندول + log_out: وتل + title: امستنې + sleep: ویده شه + app_settings: د ایپ امستنې +placeholder: + smart_charge: '- سمارټ چارج' + ethernet_disconnected: هیڅ انټرنیټ لاسرسی + battery_remaining: ٪ پاتې + ethernet_connected: انټرنیټ لاسرسی + open_system_tray: د خلاص سیسټم ټری + bluetooth_devices: بلوتوث او وسایل + volume: حجم + open_user_folder: د کارونکي فولډر خلاص کړئ + settings: ګړندي امستنې + notifications: خبرتیاوې diff --git a/src/apps/toolbar/i18n/translations/pt.yml b/src/apps/toolbar/i18n/translations/pt.yml index e6415acd..6186eb51 100644 --- a/src/apps/toolbar/i18n/translations/pt.yml +++ b/src/apps/toolbar/i18n/translations/pt.yml @@ -1,34 +1,34 @@ -media: - master_volume: Volume principal - output_device: Dispositivo de saída - input_device: Dispositivo de entrada - players: Reprodutores de mídia - device: - multimedia: Multimídia - comunications: Comunicações -network: - not_found: Nenhuma rede encontrada - more: Mais configurações de rede - hidden: Rede Oculta - placeholder: - password: Senha - disconnect: desconectar - connect: Conectar -settings: - title: Configurações - app_settings: Configurações do aplicativo - log_out: Sair - sleep: Dormir - restart: Reiniciar - shutdown: Desligar -placeholder: - open_user_folder: Abra a pasta do usuário - open_system_tray: Abra a bandeja do sistema - bluetooth_devices: Bluetooth - ethernet_connected: Acesso à internet - ethernet_disconnected: Sem acesso à internet - volume: Volume - battery_remaining: '% restante' - smart_charge: '- Carga Inteligente' - settings: Configurações rápidas - notifications: Notificações +media: + master_volume: Volume principal + output_device: Dispositivo de saída + input_device: Dispositivo de entrada + players: Reprodutores de mídia + device: + multimedia: Multimídia + comunications: Comunicações +network: + not_found: Nenhuma rede encontrada + more: Mais configurações de rede + hidden: Rede Oculta + placeholder: + password: Senha + disconnect: desconectar + connect: Conectar +settings: + title: Configurações + app_settings: Configurações do aplicativo + log_out: Sair + sleep: Dormir + restart: Reiniciar + shutdown: Desligar +placeholder: + open_user_folder: Abra a pasta do usuário + open_system_tray: Abra a bandeja do sistema + bluetooth_devices: Bluetooth + ethernet_connected: Acesso à internet + ethernet_disconnected: Sem acesso à internet + volume: Volume + battery_remaining: '% restante' + smart_charge: '- Carga Inteligente' + settings: Configurações rápidas + notifications: Notificações diff --git a/src/apps/toolbar/i18n/translations/ro.yml b/src/apps/toolbar/i18n/translations/ro.yml index f0548e19..26d1afb4 100644 --- a/src/apps/toolbar/i18n/translations/ro.yml +++ b/src/apps/toolbar/i18n/translations/ro.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedia - comunications: Comunicări - input_device: Dispozitiv de intrare - players: Playere media - master_volume: Volumul principal - output_device: Dispozitiv de ieșire -network: - placeholder: - password: Parola - connect: Conectați - not_found: Nu au fost găsite rețele - disconnect: Deconectat - more: Mai multe setări de rețea - hidden: Rețea ascunsă -settings: - shutdown: Închide - sleep: Dormi - restart: Repornire - app_settings: Setări aplicație - log_out: Deconectați -vă - title: Setări -placeholder: - ethernet_connected: acces la internet - ethernet_disconnected: Fara acces la internet - volume: Volum - battery_remaining: '% rămas' - bluetooth_devices: Bluetooth & Devices - open_user_folder: Deschideți folderul utilizator - settings: Setări rapide - open_system_tray: Tava de sistem deschisă - smart_charge: '- Încărcare inteligentă' - notifications: Notificări +media: + device: + multimedia: Multimedia + comunications: Comunicări + input_device: Dispozitiv de intrare + players: Playere media + master_volume: Volumul principal + output_device: Dispozitiv de ieșire +network: + placeholder: + password: Parola + connect: Conectați + not_found: Nu au fost găsite rețele + disconnect: Deconectat + more: Mai multe setări de rețea + hidden: Rețea ascunsă +settings: + shutdown: Închide + sleep: Dormi + restart: Repornire + app_settings: Setări aplicație + log_out: Deconectați -vă + title: Setări +placeholder: + ethernet_connected: acces la internet + ethernet_disconnected: Fara acces la internet + volume: Volum + battery_remaining: '% rămas' + bluetooth_devices: Bluetooth & Devices + open_user_folder: Deschideți folderul utilizator + settings: Setări rapide + open_system_tray: Tava de sistem deschisă + smart_charge: '- Încărcare inteligentă' + notifications: Notificări diff --git a/src/apps/toolbar/i18n/translations/ru.yml b/src/apps/toolbar/i18n/translations/ru.yml index 1ea29d81..511600d0 100644 --- a/src/apps/toolbar/i18n/translations/ru.yml +++ b/src/apps/toolbar/i18n/translations/ru.yml @@ -1,34 +1,34 @@ -media: - master_volume: Основной объем - output_device: Устройство вывода - input_device: Устройство ввода - players: Медиаплееры - device: - multimedia: Мультимедиа - comunications: Коммуникации -network: - not_found: Сети не найдены - more: Дополнительные настройки сети - hidden: Скрытая сеть - placeholder: - password: Пароль - disconnect: Отключить - connect: Соединять -settings: - title: Настройки - app_settings: Настройки приложения - log_out: Выйти - sleep: Спать - restart: Перезапуск - shutdown: Неисправность -placeholder: - open_user_folder: Открыть папку пользователя - open_system_tray: Открыть системный трей - bluetooth_devices: Bluetooth и устройства - ethernet_connected: доступ в Интернет - ethernet_disconnected: Нет доступа в Интернет - volume: Объем - battery_remaining: '% оставшийся' - smart_charge: '- Умная зарядка' - settings: Быстрые настройки - notifications: Уведомления +media: + master_volume: Основной объем + output_device: Устройство вывода + input_device: Устройство ввода + players: Медиаплееры + device: + multimedia: Мультимедиа + comunications: Коммуникации +network: + not_found: Сети не найдены + more: Дополнительные настройки сети + hidden: Скрытая сеть + placeholder: + password: Пароль + disconnect: Отключить + connect: Соединять +settings: + title: Настройки + app_settings: Настройки приложения + log_out: Выйти + sleep: Спать + restart: Перезапуск + shutdown: Неисправность +placeholder: + open_user_folder: Открыть папку пользователя + open_system_tray: Открыть системный трей + bluetooth_devices: Bluetooth и устройства + ethernet_connected: доступ в Интернет + ethernet_disconnected: Нет доступа в Интернет + volume: Объем + battery_remaining: '% оставшийся' + smart_charge: '- Умная зарядка' + settings: Быстрые настройки + notifications: Уведомления diff --git a/src/apps/toolbar/i18n/translations/si.yml b/src/apps/toolbar/i18n/translations/si.yml index 50aefc49..bf1d3e53 100644 --- a/src/apps/toolbar/i18n/translations/si.yml +++ b/src/apps/toolbar/i18n/translations/si.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: සන්නිවේදනය - multimedia: බහුමාධ්ය - output_device: ප්රතිදාන උපාංගය - master_volume: මාස්ටර් පරිමාව - input_device: ආදාන උපාංගය - players: මාධ්ය වාදකයන් -network: - placeholder: - password: මුරපදය - not_found: ජාලක් හමු නොවීය - more: තවත් ජාල සැකසුම් - disconnect: විසන්ධි කරන්න - connect: සම්බන්ධ කරන්න - hidden: සැඟවුණු ජාලය -settings: - restart: යළි අරඹන්න - shutdown: වසා දමන්න - title: සැකසුම් - app_settings: යෙදුම් සැකසුම් - log_out: ඉවත් වන්න - sleep: නිදාගන්න -placeholder: - ethernet_connected: අන්තර්ජාල පිවිසුම - battery_remaining: ඉතිරි% ඉතිරිව ඇත - open_system_tray: විවෘත පද්ධති තැටි - ethernet_disconnected: අන්තර්ජාල ප්රවේශයක් නොමැත - bluetooth_devices: බ්ලූටූත් සහ උපාංග - smart_charge: '- ස්මාර්ට් ගාස්තුව' - open_user_folder: පරිශීලක ෆෝල්ඩරය විවෘත කරන්න - settings: ඉක්මන් සැකසුම් - volume: පරිමාව - notifications: දැනුම්දීම් +media: + device: + comunications: සන්නිවේදනය + multimedia: බහුමාධ්ය + output_device: ප්රතිදාන උපාංගය + master_volume: මාස්ටර් පරිමාව + input_device: ආදාන උපාංගය + players: මාධ්ය වාදකයන් +network: + placeholder: + password: මුරපදය + not_found: ජාලක් හමු නොවීය + more: තවත් ජාල සැකසුම් + disconnect: විසන්ධි කරන්න + connect: සම්බන්ධ කරන්න + hidden: සැඟවුණු ජාලය +settings: + restart: යළි අරඹන්න + shutdown: වසා දමන්න + title: සැකසුම් + app_settings: යෙදුම් සැකසුම් + log_out: ඉවත් වන්න + sleep: නිදාගන්න +placeholder: + ethernet_connected: අන්තර්ජාල පිවිසුම + battery_remaining: ඉතිරි% ඉතිරිව ඇත + open_system_tray: විවෘත පද්ධති තැටි + ethernet_disconnected: අන්තර්ජාල ප්රවේශයක් නොමැත + bluetooth_devices: බ්ලූටූත් සහ උපාංග + smart_charge: '- ස්මාර්ට් ගාස්තුව' + open_user_folder: පරිශීලක ෆෝල්ඩරය විවෘත කරන්න + settings: ඉක්මන් සැකසුම් + volume: පරිමාව + notifications: දැනුම්දීම් diff --git a/src/apps/toolbar/i18n/translations/sk.yml b/src/apps/toolbar/i18n/translations/sk.yml index f261a6a6..d94f5fa2 100644 --- a/src/apps/toolbar/i18n/translations/sk.yml +++ b/src/apps/toolbar/i18n/translations/sk.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimédiá - comunications: Komunikácia - input_device: Vstupné zariadenie - output_device: Výstupné zariadenie - master_volume: Zväzok - players: Médiá -network: - placeholder: - password: Heslo - hidden: Skrytá sieť - disconnect: Odpojiť - connect: Pripojiť - more: Viac nastavení siete - not_found: Nenašli sa žiadne siete -settings: - log_out: Odhlásiť sa - restart: Reštart - shutdown: Vypnúť - title: nastavenie - sleep: Spať - app_settings: Nastavenia aplikácií -placeholder: - ethernet_connected: Prístup na internet - ethernet_disconnected: Žiadny prístup na internet - open_user_folder: Otvorte priečinok používateľa - smart_charge: '- Inteligentný poplatok' - settings: Rýchle nastavenia - battery_remaining: zostávajúci % % - bluetooth_devices: Bluetooth a zariadenia - open_system_tray: Podnos otvorených systémov - volume: Zväzok - notifications: Oznámenia +media: + device: + multimedia: Multimédiá + comunications: Komunikácia + input_device: Vstupné zariadenie + output_device: Výstupné zariadenie + master_volume: Zväzok + players: Médiá +network: + placeholder: + password: Heslo + hidden: Skrytá sieť + disconnect: Odpojiť + connect: Pripojiť + more: Viac nastavení siete + not_found: Nenašli sa žiadne siete +settings: + log_out: Odhlásiť sa + restart: Reštart + shutdown: Vypnúť + title: nastavenie + sleep: Spať + app_settings: Nastavenia aplikácií +placeholder: + ethernet_connected: Prístup na internet + ethernet_disconnected: Žiadny prístup na internet + open_user_folder: Otvorte priečinok používateľa + smart_charge: '- Inteligentný poplatok' + settings: Rýchle nastavenia + battery_remaining: zostávajúci % % + bluetooth_devices: Bluetooth a zariadenia + open_system_tray: Podnos otvorených systémov + volume: Zväzok + notifications: Oznámenia diff --git a/src/apps/toolbar/i18n/translations/so.yml b/src/apps/toolbar/i18n/translations/so.yml index 309082fd..6cb2e2ef 100644 --- a/src/apps/toolbar/i18n/translations/so.yml +++ b/src/apps/toolbar/i18n/translations/so.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Isgaar isgaar - multimedia: Urur badan - input_device: Qalabka gelinta - output_device: Aaladda wax soo saarka - players: Ciyaartoyda warbaahinta - master_volume: Mugga Master -network: - placeholder: - password: Eray sir - not_found: Shabakad lama helin - hidden: Shabakada Qarsoon - more: Meelo badan oo shabakad ah - disconnect: Ka furid - connect: Ku xirid -settings: - shutdown: Bakhtii - log_out: Ka bax - sleep: Seexo - app_settings: App Goobaha - restart: Dib u bilow - title: Dejinta -placeholder: - smart_charge: '- SMART SAXIIXA' - ethernet_connected: Helitaanka Internetka - volume: Mug - settings: Meel deg deg ah - open_user_folder: Fur Feejignaanta USE - open_system_tray: Nidaamka Nidaamka Furan - battery_remaining: '% haray' - bluetooth_devices: Bluetooth & aaladda - ethernet_disconnected: Marin internet ah - notifications: Ogeysiisyada +media: + device: + comunications: Isgaar isgaar + multimedia: Urur badan + input_device: Qalabka gelinta + output_device: Aaladda wax soo saarka + players: Ciyaartoyda warbaahinta + master_volume: Mugga Master +network: + placeholder: + password: Eray sir + not_found: Shabakad lama helin + hidden: Shabakada Qarsoon + more: Meelo badan oo shabakad ah + disconnect: Ka furid + connect: Ku xirid +settings: + shutdown: Bakhtii + log_out: Ka bax + sleep: Seexo + app_settings: App Goobaha + restart: Dib u bilow + title: Dejinta +placeholder: + smart_charge: '- SMART SAXIIXA' + ethernet_connected: Helitaanka Internetka + volume: Mug + settings: Meel deg deg ah + open_user_folder: Fur Feejignaanta USE + open_system_tray: Nidaamka Nidaamka Furan + battery_remaining: '% haray' + bluetooth_devices: Bluetooth & aaladda + ethernet_disconnected: Marin internet ah + notifications: Ogeysiisyada diff --git a/src/apps/toolbar/i18n/translations/sr.yml b/src/apps/toolbar/i18n/translations/sr.yml index 94b40580..0c194a44 100644 --- a/src/apps/toolbar/i18n/translations/sr.yml +++ b/src/apps/toolbar/i18n/translations/sr.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Комуникација - multimedia: Мултимедијални - input_device: Улазни уређај - output_device: Излазни уређај - players: Медиа Играчи - master_volume: Главна јачина -network: - placeholder: - password: Лозинка - hidden: Скривена мрежа - not_found: Није пронађена ниједна мрежа - more: Више мрежних поставки - connect: Повезати - disconnect: Прекинути везу -settings: - restart: Поново покренути - shutdown: Искључити - log_out: Одјавити се - app_settings: Подешавања апликација - title: Подешавања - sleep: Спавати -placeholder: - ethernet_disconnected: Нема приступа интернету - ethernet_connected: Приступ интернету - smart_charge: '- паметно набој' - volume: Запремина - settings: Брза подешавања - battery_remaining: преостали% - open_user_folder: Отворите фасциклу корисника - bluetooth_devices: Блуетоотх и уређаји - open_system_tray: Отворите лежиште за систем - notifications: Обавештења +media: + device: + comunications: Комуникација + multimedia: Мултимедијални + input_device: Улазни уређај + output_device: Излазни уређај + players: Медиа Играчи + master_volume: Главна јачина +network: + placeholder: + password: Лозинка + hidden: Скривена мрежа + not_found: Није пронађена ниједна мрежа + more: Више мрежних поставки + connect: Повезати + disconnect: Прекинути везу +settings: + restart: Поново покренути + shutdown: Искључити + log_out: Одјавити се + app_settings: Подешавања апликација + title: Подешавања + sleep: Спавати +placeholder: + ethernet_disconnected: Нема приступа интернету + ethernet_connected: Приступ интернету + smart_charge: '- паметно набој' + volume: Запремина + settings: Брза подешавања + battery_remaining: преостали% + open_user_folder: Отворите фасциклу корисника + bluetooth_devices: Блуетоотх и уређаји + open_system_tray: Отворите лежиште за систем + notifications: Обавештења diff --git a/src/apps/toolbar/i18n/translations/sv.yml b/src/apps/toolbar/i18n/translations/sv.yml index fb511fd5..dd03f8a7 100644 --- a/src/apps/toolbar/i18n/translations/sv.yml +++ b/src/apps/toolbar/i18n/translations/sv.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedia - comunications: Kommunikation - input_device: Inmatningsapparat - output_device: Utmatningsanordning - players: Mediaspelare - master_volume: Mastervolym -network: - placeholder: - password: Lösenord - more: Fler nätverksinställningar - not_found: Inga nätverk hittades - disconnect: Koppla ifrån - connect: Ansluta - hidden: Doldnätverk -settings: - shutdown: Stänga av - restart: Omstart - app_settings: App inställningar - title: inställningar - sleep: Sova - log_out: Logga ut -placeholder: - ethernet_disconnected: Ingen internetuppkoppling - battery_remaining: '% återstående' - open_system_tray: Öppet system - ethernet_connected: internetåtkomst - volume: Volym - open_user_folder: Öppen användarmapp - bluetooth_devices: Bluetooth & enheter - settings: Snabbinställningar - smart_charge: '- Smart laddning' - notifications: Meddelanden +media: + device: + multimedia: Multimedia + comunications: Kommunikation + input_device: Inmatningsapparat + output_device: Utmatningsanordning + players: Mediaspelare + master_volume: Mastervolym +network: + placeholder: + password: Lösenord + more: Fler nätverksinställningar + not_found: Inga nätverk hittades + disconnect: Koppla ifrån + connect: Ansluta + hidden: Doldnätverk +settings: + shutdown: Stänga av + restart: Omstart + app_settings: App inställningar + title: inställningar + sleep: Sova + log_out: Logga ut +placeholder: + ethernet_disconnected: Ingen internetuppkoppling + battery_remaining: '% återstående' + open_system_tray: Öppet system + ethernet_connected: internetåtkomst + volume: Volym + open_user_folder: Öppen användarmapp + bluetooth_devices: Bluetooth & enheter + settings: Snabbinställningar + smart_charge: '- Smart laddning' + notifications: Meddelanden diff --git a/src/apps/toolbar/i18n/translations/sw.yml b/src/apps/toolbar/i18n/translations/sw.yml index 8c3eb226..a0ff38c9 100644 --- a/src/apps/toolbar/i18n/translations/sw.yml +++ b/src/apps/toolbar/i18n/translations/sw.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedia - comunications: Mawasiliano - master_volume: Kiasi cha Mwalimu - input_device: Kifaa cha Kuingiza - players: Wachezaji wa media - output_device: Kifaa cha pato -network: - placeholder: - password: Nenosiri - more: Mipangilio zaidi ya mtandao - not_found: Hakuna mitandao iliyopatikana - disconnect: Kukatwa - connect: Unganisha - hidden: Mtandao uliofichwa -settings: - restart: Anzisha tena - title: Mipangilio - shutdown: Kuzimisha - app_settings: Mipangilio ya programu - log_out: Ingia nje - sleep: Kulala -placeholder: - ethernet_connected: Ufikiaji wa mtandao - settings: Mipangilio ya haraka - smart_charge: '- Smart Charge' - bluetooth_devices: Bluetooth & vifaa - open_system_tray: Tray ya mfumo wazi - open_user_folder: Fungua folda ya Mtumiaji - ethernet_disconnected: Hakuna ufikiaji wa mtandao - volume: Kiasi - battery_remaining: Imebaki - notifications: Arifa +media: + device: + multimedia: Multimedia + comunications: Mawasiliano + master_volume: Kiasi cha Mwalimu + input_device: Kifaa cha Kuingiza + players: Wachezaji wa media + output_device: Kifaa cha pato +network: + placeholder: + password: Nenosiri + more: Mipangilio zaidi ya mtandao + not_found: Hakuna mitandao iliyopatikana + disconnect: Kukatwa + connect: Unganisha + hidden: Mtandao uliofichwa +settings: + restart: Anzisha tena + title: Mipangilio + shutdown: Kuzimisha + app_settings: Mipangilio ya programu + log_out: Ingia nje + sleep: Kulala +placeholder: + ethernet_connected: Ufikiaji wa mtandao + settings: Mipangilio ya haraka + smart_charge: '- Smart Charge' + bluetooth_devices: Bluetooth & vifaa + open_system_tray: Tray ya mfumo wazi + open_user_folder: Fungua folda ya Mtumiaji + ethernet_disconnected: Hakuna ufikiaji wa mtandao + volume: Kiasi + battery_remaining: Imebaki + notifications: Arifa diff --git a/src/apps/toolbar/i18n/translations/ta.yml b/src/apps/toolbar/i18n/translations/ta.yml index 39a84cb8..37e1421d 100644 --- a/src/apps/toolbar/i18n/translations/ta.yml +++ b/src/apps/toolbar/i18n/translations/ta.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: மல்டிமீடியா - comunications: தகவல்தொடர்புகள் - output_device: வெளியீடு சாதனம் - master_volume: முதன்மை தொகுதி - input_device: உள்ளீட்டு சாதனம் - players: மீடியா பிளேயர்கள் -network: - placeholder: - password: கடவுச்சொல் - connect: இணைக்கவும் - more: மேலும் பிணைய அமைப்புகள் - not_found: நெட்வொர்க்குகள் எதுவும் கிடைக்கவில்லை - hidden: மறைக்கப்பட்ட பிணையம் - disconnect: துண்டிக்கவும் -settings: - title: அமைப்புகள் - sleep: தூங்கு - log_out: வெளியேறு - app_settings: பயன்பாட்டு அமைப்புகள் - restart: மறுதொடக்கம் - shutdown: பணிநிறுத்தம் -placeholder: - smart_charge: '- ஸ்மார்ட் கட்டணம்' - settings: விரைவான அமைப்புகள் - open_system_tray: திறந்த கணினி தட்டு - battery_remaining: '% மீதமுள்ள' - open_user_folder: பயனர் கோப்புறையைத் திறக்கவும் - ethernet_connected: இணைய அணுகல் - volume: தொகுதி - ethernet_disconnected: இணைய அணுகல் இல்லை - bluetooth_devices: புளூடூத் & சாதனங்கள் - notifications: அறிவிப்புகள் +media: + device: + multimedia: மல்டிமீடியா + comunications: தகவல்தொடர்புகள் + output_device: வெளியீடு சாதனம் + master_volume: முதன்மை தொகுதி + input_device: உள்ளீட்டு சாதனம் + players: மீடியா பிளேயர்கள் +network: + placeholder: + password: கடவுச்சொல் + connect: இணைக்கவும் + more: மேலும் பிணைய அமைப்புகள் + not_found: நெட்வொர்க்குகள் எதுவும் கிடைக்கவில்லை + hidden: மறைக்கப்பட்ட பிணையம் + disconnect: துண்டிக்கவும் +settings: + title: அமைப்புகள் + sleep: தூங்கு + log_out: வெளியேறு + app_settings: பயன்பாட்டு அமைப்புகள் + restart: மறுதொடக்கம் + shutdown: பணிநிறுத்தம் +placeholder: + smart_charge: '- ஸ்மார்ட் கட்டணம்' + settings: விரைவான அமைப்புகள் + open_system_tray: திறந்த கணினி தட்டு + battery_remaining: '% மீதமுள்ள' + open_user_folder: பயனர் கோப்புறையைத் திறக்கவும் + ethernet_connected: இணைய அணுகல் + volume: தொகுதி + ethernet_disconnected: இணைய அணுகல் இல்லை + bluetooth_devices: புளூடூத் & சாதனங்கள் + notifications: அறிவிப்புகள் diff --git a/src/apps/toolbar/i18n/translations/te.yml b/src/apps/toolbar/i18n/translations/te.yml index e2c2b2de..4e8b6736 100644 --- a/src/apps/toolbar/i18n/translations/te.yml +++ b/src/apps/toolbar/i18n/translations/te.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: కమ్యూనికేషన్స్ - multimedia: మల్టీమీడియా - input_device: ఇన్పుట్ పరికరం - players: మీడియా ప్లేయర్స్ - master_volume: మాస్టర్ వాల్యూమ్ - output_device: అవుట్పుట్ పరికరం -network: - placeholder: - password: పాస్వర్డ్ - disconnect: డిస్‌కనెక్ట్ చేయండి - not_found: నెట్‌వర్క్‌లు ఏవీ కనుగొనబడలేదు - connect: కనెక్ట్ - hidden: దాచిన నెట్‌వర్క్ - more: మరిన్ని నెట్‌వర్క్ సెట్టింగులు -settings: - log_out: లాగ్ అవుట్ - app_settings: అనువర్తన సెట్టింగులు - shutdown: షట్డౌన్ - title: సెట్టింగులు - restart: పున art ప్రారంభం - sleep: నిద్ర -placeholder: - ethernet_connected: ఇంటర్నెట్ సదుపాయం - ethernet_disconnected: ఇంటర్నెట్ సదుపాయం లేదు - bluetooth_devices: బ్లూటూత్ & పరికరాలు - open_system_tray: ఓపెన్ సిస్టమ్ ట్రే - smart_charge: '- స్మార్ట్ ఛార్జ్' - battery_remaining: '% మిగిలి ఉంది' - volume: వాల్యూమ్ - open_user_folder: ఓపెన్ యూజర్ ఫోల్డర్ - settings: శీఘ్ర సెట్టింగులు - notifications: నోటిఫికేషన్‌లు +media: + device: + comunications: కమ్యూనికేషన్స్ + multimedia: మల్టీమీడియా + input_device: ఇన్పుట్ పరికరం + players: మీడియా ప్లేయర్స్ + master_volume: మాస్టర్ వాల్యూమ్ + output_device: అవుట్పుట్ పరికరం +network: + placeholder: + password: పాస్వర్డ్ + disconnect: డిస్‌కనెక్ట్ చేయండి + not_found: నెట్‌వర్క్‌లు ఏవీ కనుగొనబడలేదు + connect: కనెక్ట్ + hidden: దాచిన నెట్‌వర్క్ + more: మరిన్ని నెట్‌వర్క్ సెట్టింగులు +settings: + log_out: లాగ్ అవుట్ + app_settings: అనువర్తన సెట్టింగులు + shutdown: షట్డౌన్ + title: సెట్టింగులు + restart: పున art ప్రారంభం + sleep: నిద్ర +placeholder: + ethernet_connected: ఇంటర్నెట్ సదుపాయం + ethernet_disconnected: ఇంటర్నెట్ సదుపాయం లేదు + bluetooth_devices: బ్లూటూత్ & పరికరాలు + open_system_tray: ఓపెన్ సిస్టమ్ ట్రే + smart_charge: '- స్మార్ట్ ఛార్జ్' + battery_remaining: '% మిగిలి ఉంది' + volume: వాల్యూమ్ + open_user_folder: ఓపెన్ యూజర్ ఫోల్డర్ + settings: శీఘ్ర సెట్టింగులు + notifications: నోటిఫికేషన్‌లు diff --git a/src/apps/toolbar/i18n/translations/tg.yml b/src/apps/toolbar/i18n/translations/tg.yml index cd2e6f85..2725ea3e 100644 --- a/src/apps/toolbar/i18n/translations/tg.yml +++ b/src/apps/toolbar/i18n/translations/tg.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Иртибот - multimedia: Мултимедиявӣ - input_device: Дастгоҳи воридшавӣ - master_volume: Ҳаҷми усто - players: Бозингарони ВАО - output_device: Дастгоҳи баромад -network: - placeholder: - password: Номи махфӣ - hidden: Шабакаи пинҳонӣ - not_found: Ягон шабакаҳо ёфт нашуд - more: Танзимоти шабака - disconnect: Ьудо кардан - connect: Пайваст кардан -settings: - restart: Оғози дубора - shutdown: Пӯшида шудан - log_out: Баромадан - app_settings: Танзимоти барнома - sleep: Хоб - title: Танзимот -placeholder: - smart_charge: '- СПАЛ' - ethernet_connected: Дастрасии Интернет - bluetooth_devices: Bluetooth & Дастгоҳҳо - volume: Баланд - battery_remaining: '% боқимонда' - open_system_tray: Пойгоҳи системаро кушоед - settings: Танзимоти фаврӣ - open_user_folder: Папкаи корбарро кушоед - ethernet_disconnected: Дастрасии Интернет надорад - notifications: Огоҳиҳо +media: + device: + comunications: Иртибот + multimedia: Мултимедиявӣ + input_device: Дастгоҳи воридшавӣ + master_volume: Ҳаҷми усто + players: Бозингарони ВАО + output_device: Дастгоҳи баромад +network: + placeholder: + password: Номи махфӣ + hidden: Шабакаи пинҳонӣ + not_found: Ягон шабакаҳо ёфт нашуд + more: Танзимоти шабака + disconnect: Ьудо кардан + connect: Пайваст кардан +settings: + restart: Оғози дубора + shutdown: Пӯшида шудан + log_out: Баромадан + app_settings: Танзимоти барнома + sleep: Хоб + title: Танзимот +placeholder: + smart_charge: '- СПАЛ' + ethernet_connected: Дастрасии Интернет + bluetooth_devices: Bluetooth & Дастгоҳҳо + volume: Баланд + battery_remaining: '% боқимонда' + open_system_tray: Пойгоҳи системаро кушоед + settings: Танзимоти фаврӣ + open_user_folder: Папкаи корбарро кушоед + ethernet_disconnected: Дастрасии Интернет надорад + notifications: Огоҳиҳо diff --git a/src/apps/toolbar/i18n/translations/th.yml b/src/apps/toolbar/i18n/translations/th.yml index 07c76582..f04d5fe0 100644 --- a/src/apps/toolbar/i18n/translations/th.yml +++ b/src/apps/toolbar/i18n/translations/th.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: การสื่อสาร - multimedia: มัลติมีเดีย - output_device: อุปกรณ์ส่งออก - input_device: อุปกรณ์อินพุต - master_volume: ระดับปริญญาโท - players: เครื่องเล่นสื่อ -network: - placeholder: - password: รหัสผ่าน - connect: เชื่อมต่อ - more: การตั้งค่าเครือข่ายเพิ่มเติม - not_found: ไม่พบเครือข่าย - disconnect: ตัดการเชื่อมต่อ - hidden: เครือข่ายที่ซ่อน -settings: - restart: เริ่มต้นใหม่ - app_settings: การตั้งค่าแอป - sleep: นอน - title: การตั้งค่า - shutdown: ปิดตัวลง - log_out: ออกจากระบบ -placeholder: - settings: การตั้งค่าอย่างรวดเร็ว - open_system_tray: ถาดระบบเปิด - ethernet_disconnected: ไม่มีการเข้าถึงอินเทอร์เน็ต - volume: ปริมาณ - smart_charge: '- ชาร์จอัจฉริยะ' - battery_remaining: '% ที่เหลืออยู่' - open_user_folder: เปิดโฟลเดอร์ผู้ใช้ - ethernet_connected: การเข้าถึงอินเทอร์เน็ต - bluetooth_devices: บลูทู ธ และอุปกรณ์ - notifications: การแจ้งเตือน +media: + device: + comunications: การสื่อสาร + multimedia: มัลติมีเดีย + output_device: อุปกรณ์ส่งออก + input_device: อุปกรณ์อินพุต + master_volume: ระดับปริญญาโท + players: เครื่องเล่นสื่อ +network: + placeholder: + password: รหัสผ่าน + connect: เชื่อมต่อ + more: การตั้งค่าเครือข่ายเพิ่มเติม + not_found: ไม่พบเครือข่าย + disconnect: ตัดการเชื่อมต่อ + hidden: เครือข่ายที่ซ่อน +settings: + restart: เริ่มต้นใหม่ + app_settings: การตั้งค่าแอป + sleep: นอน + title: การตั้งค่า + shutdown: ปิดตัวลง + log_out: ออกจากระบบ +placeholder: + settings: การตั้งค่าอย่างรวดเร็ว + open_system_tray: ถาดระบบเปิด + ethernet_disconnected: ไม่มีการเข้าถึงอินเทอร์เน็ต + volume: ปริมาณ + smart_charge: '- ชาร์จอัจฉริยะ' + battery_remaining: '% ที่เหลืออยู่' + open_user_folder: เปิดโฟลเดอร์ผู้ใช้ + ethernet_connected: การเข้าถึงอินเทอร์เน็ต + bluetooth_devices: บลูทู ธ และอุปกรณ์ + notifications: การแจ้งเตือน diff --git a/src/apps/toolbar/i18n/translations/tl.yml b/src/apps/toolbar/i18n/translations/tl.yml index 14a2a3bc..6c376930 100644 --- a/src/apps/toolbar/i18n/translations/tl.yml +++ b/src/apps/toolbar/i18n/translations/tl.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Komunikasyon - multimedia: Multimedia - master_volume: Dami ng master - input_device: Aparato ng pag -input - players: Mga manlalaro ng media - output_device: Aparato ng output -network: - placeholder: - password: Password - not_found: Walang nahanap na mga network - hidden: Nakatagong network - disconnect: Idiskonekta - more: Higit pang mga setting ng network - connect: Kumonekta -settings: - app_settings: Mga Setting ng App - shutdown: Shutdown - sleep: Matulog ka na - restart: I -restart - log_out: Mag -log out - title: Mga setting -placeholder: - ethernet_connected: Internet access - ethernet_disconnected: Walang internet access - settings: Mabilis na mga setting - battery_remaining: Nananatili - open_system_tray: Bukas na tray ng system - open_user_folder: Buksan ang folder ng gumagamit - volume: Dami - bluetooth_devices: Bluetooth at mga aparato - smart_charge: '- Smart Charge' - notifications: Mga abiso +media: + device: + comunications: Komunikasyon + multimedia: Multimedia + master_volume: Dami ng master + input_device: Aparato ng pag -input + players: Mga manlalaro ng media + output_device: Aparato ng output +network: + placeholder: + password: Password + not_found: Walang nahanap na mga network + hidden: Nakatagong network + disconnect: Idiskonekta + more: Higit pang mga setting ng network + connect: Kumonekta +settings: + app_settings: Mga Setting ng App + shutdown: Shutdown + sleep: Matulog ka na + restart: I -restart + log_out: Mag -log out + title: Mga setting +placeholder: + ethernet_connected: Internet access + ethernet_disconnected: Walang internet access + settings: Mabilis na mga setting + battery_remaining: Nananatili + open_system_tray: Bukas na tray ng system + open_user_folder: Buksan ang folder ng gumagamit + volume: Dami + bluetooth_devices: Bluetooth at mga aparato + smart_charge: '- Smart Charge' + notifications: Mga abiso diff --git a/src/apps/toolbar/i18n/translations/tr.yml b/src/apps/toolbar/i18n/translations/tr.yml index 5aebe15c..a86bda82 100644 --- a/src/apps/toolbar/i18n/translations/tr.yml +++ b/src/apps/toolbar/i18n/translations/tr.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedya - comunications: İletişim - input_device: Giriş aygıtı - output_device: Çıkış aygıtı - players: Medya Oyuncuları - master_volume: Ana ses -network: - placeholder: - password: Şifre - connect: Bağlamak - more: Daha Fazla Ağ Ayarları - hidden: Gizli ağ - not_found: Ağ bulunamadı - disconnect: Koparmak -settings: - shutdown: Kapat - app_settings: Uygulama ayarları - log_out: Çıkış Yap - title: Ayarlar - restart: Tekrar başlat - sleep: Uyumak -placeholder: - battery_remaining: '% geriye kalan' - settings: Hızlı Ayarlar - ethernet_connected: internet girişi - smart_charge: '- Akıllı şarj' - bluetooth_devices: Bluetooth ve Cihazlar - volume: Hacim - ethernet_disconnected: İnternet erişimi yok - open_user_folder: Kullanıcı klasörünü açın - open_system_tray: Sistem Tepsisi - notifications: Bildirimler +media: + device: + multimedia: Multimedya + comunications: İletişim + input_device: Giriş aygıtı + output_device: Çıkış aygıtı + players: Medya Oyuncuları + master_volume: Ana ses +network: + placeholder: + password: Şifre + connect: Bağlamak + more: Daha Fazla Ağ Ayarları + hidden: Gizli ağ + not_found: Ağ bulunamadı + disconnect: Koparmak +settings: + shutdown: Kapat + app_settings: Uygulama ayarları + log_out: Çıkış Yap + title: Ayarlar + restart: Tekrar başlat + sleep: Uyumak +placeholder: + battery_remaining: '% geriye kalan' + settings: Hızlı Ayarlar + ethernet_connected: internet girişi + smart_charge: '- Akıllı şarj' + bluetooth_devices: Bluetooth ve Cihazlar + volume: Hacim + ethernet_disconnected: İnternet erişimi yok + open_user_folder: Kullanıcı klasörünü açın + open_system_tray: Sistem Tepsisi + notifications: Bildirimler diff --git a/src/apps/toolbar/i18n/translations/uk.yml b/src/apps/toolbar/i18n/translations/uk.yml index 1206b14d..786bf50f 100644 --- a/src/apps/toolbar/i18n/translations/uk.yml +++ b/src/apps/toolbar/i18n/translations/uk.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Комунікація - multimedia: Мультимедіа - players: Медіаплеєри - output_device: Пристрій виводу - master_volume: Головний об'єм - input_device: Пристрій введення -network: - placeholder: - password: Пароль - hidden: Прихована мережа - disconnect: Відключити - more: Більше налаштувань мережі - connect: З'єднувати - not_found: Жодних мереж не знайдено -settings: - log_out: Вийти - shutdown: Закрити - app_settings: Налаштування додатків - restart: Перезапустити - sleep: Сплячий - title: Налаштування -placeholder: - ethernet_disconnected: Немає доступу до Інтернету - ethernet_connected: Доступ в інтернет - settings: Швидкі налаштування - volume: Обсяг - battery_remaining: '% залишається' - open_system_tray: Лоток відкритого систем - bluetooth_devices: Bluetooth та пристрої - smart_charge: '- розумний заряд' - open_user_folder: Відкрийте папку користувача - notifications: Сповіщення +media: + device: + comunications: Комунікація + multimedia: Мультимедіа + players: Медіаплеєри + output_device: Пристрій виводу + master_volume: Головний об'єм + input_device: Пристрій введення +network: + placeholder: + password: Пароль + hidden: Прихована мережа + disconnect: Відключити + more: Більше налаштувань мережі + connect: З'єднувати + not_found: Жодних мереж не знайдено +settings: + log_out: Вийти + shutdown: Закрити + app_settings: Налаштування додатків + restart: Перезапустити + sleep: Сплячий + title: Налаштування +placeholder: + ethernet_disconnected: Немає доступу до Інтернету + ethernet_connected: Доступ в інтернет + settings: Швидкі налаштування + volume: Обсяг + battery_remaining: '% залишається' + open_system_tray: Лоток відкритого систем + bluetooth_devices: Bluetooth та пристрої + smart_charge: '- розумний заряд' + open_user_folder: Відкрийте папку користувача + notifications: Сповіщення diff --git a/src/apps/toolbar/i18n/translations/ur.yml b/src/apps/toolbar/i18n/translations/ur.yml index 66e25fe8..e8c6c945 100644 --- a/src/apps/toolbar/i18n/translations/ur.yml +++ b/src/apps/toolbar/i18n/translations/ur.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: مواصلات - multimedia: ملٹی میڈیا - input_device: ان پٹ ڈیوائس - output_device: آؤٹ پٹ ڈیوائس - master_volume: ماسٹر جلد - players: میڈیا پلیئرز -network: - placeholder: - password: پاس ورڈ - disconnect: منقطع - hidden: پوشیدہ نیٹ ورک - not_found: کوئی نیٹ ورک نہیں ملا - connect: جڑیں - more: نیٹ ورک کی مزید ترتیبات -settings: - restart: دوبارہ شروع کریں - log_out: لاگ آوٹ - title: ترتیبات - app_settings: ایپ کی ترتیبات - sleep: نیند - shutdown: شٹ ڈاؤن -placeholder: - ethernet_connected: انٹرنیٹ تک رسائی - smart_charge: '- سمارٹ چارج' - open_system_tray: اوپن سسٹم ٹرے - battery_remaining: ٪ باقی - ethernet_disconnected: انٹرنیٹ تک رسائی نہیں ہے - open_user_folder: صارف فولڈر کھولیں - settings: فوری ترتیبات - bluetooth_devices: بلوٹوتھ اور ڈیوائسز - volume: حجم - notifications: اطلاعات +media: + device: + comunications: مواصلات + multimedia: ملٹی میڈیا + input_device: ان پٹ ڈیوائس + output_device: آؤٹ پٹ ڈیوائس + master_volume: ماسٹر جلد + players: میڈیا پلیئرز +network: + placeholder: + password: پاس ورڈ + disconnect: منقطع + hidden: پوشیدہ نیٹ ورک + not_found: کوئی نیٹ ورک نہیں ملا + connect: جڑیں + more: نیٹ ورک کی مزید ترتیبات +settings: + restart: دوبارہ شروع کریں + log_out: لاگ آوٹ + title: ترتیبات + app_settings: ایپ کی ترتیبات + sleep: نیند + shutdown: شٹ ڈاؤن +placeholder: + ethernet_connected: انٹرنیٹ تک رسائی + smart_charge: '- سمارٹ چارج' + open_system_tray: اوپن سسٹم ٹرے + battery_remaining: ٪ باقی + ethernet_disconnected: انٹرنیٹ تک رسائی نہیں ہے + open_user_folder: صارف فولڈر کھولیں + settings: فوری ترتیبات + bluetooth_devices: بلوٹوتھ اور ڈیوائسز + volume: حجم + notifications: اطلاعات diff --git a/src/apps/toolbar/i18n/translations/uz.yml b/src/apps/toolbar/i18n/translations/uz.yml index 90ad54fc..8b3cfc15 100644 --- a/src/apps/toolbar/i18n/translations/uz.yml +++ b/src/apps/toolbar/i18n/translations/uz.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Aloqa - multimedia: Multimedia - output_device: Chiqish moslamasi - players: Media pleerlari - input_device: Kirish moslamasi - master_volume: Master hajmi -network: - placeholder: - password: Parol - connect: Ulanmoq - hidden: Yashirin tarmoq - disconnect: Ajratmoq - more: Ko'proq tarmoq sozlamalari - not_found: Tarmoq topilmadi -settings: - restart: Qayta ishga tushirish - shutdown: O'chirish; yopish - log_out: Chiqish - app_settings: Ilova sozlamalari - sleep: Uyqu - title: Sozlash -placeholder: - ethernet_connected: Internetga ulanish - battery_remaining: '% Qolgan' - ethernet_disconnected: Internetga kirish yo'q - open_system_tray: Ochiq tizimning patnisi - bluetooth_devices: Bluetooth va qurilmalar - volume: Hajmi - open_user_folder: Foydalanuvchi papkasini oching - settings: Tez sozlamalar - smart_charge: '- aqlli zaryad' - notifications: Bildirishnoma +media: + device: + comunications: Aloqa + multimedia: Multimedia + output_device: Chiqish moslamasi + players: Media pleerlari + input_device: Kirish moslamasi + master_volume: Master hajmi +network: + placeholder: + password: Parol + connect: Ulanmoq + hidden: Yashirin tarmoq + disconnect: Ajratmoq + more: Ko'proq tarmoq sozlamalari + not_found: Tarmoq topilmadi +settings: + restart: Qayta ishga tushirish + shutdown: O'chirish; yopish + log_out: Chiqish + app_settings: Ilova sozlamalari + sleep: Uyqu + title: Sozlash +placeholder: + ethernet_connected: Internetga ulanish + battery_remaining: '% Qolgan' + ethernet_disconnected: Internetga kirish yo'q + open_system_tray: Ochiq tizimning patnisi + bluetooth_devices: Bluetooth va qurilmalar + volume: Hajmi + open_user_folder: Foydalanuvchi papkasini oching + settings: Tez sozlamalar + smart_charge: '- aqlli zaryad' + notifications: Bildirishnoma diff --git a/src/apps/toolbar/i18n/translations/vi.yml b/src/apps/toolbar/i18n/translations/vi.yml index ae0dc2cd..b00b8309 100644 --- a/src/apps/toolbar/i18n/translations/vi.yml +++ b/src/apps/toolbar/i18n/translations/vi.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Đa phương tiện - comunications: Truyền thông - master_volume: Khối lượng tổng thể - input_device: Thiết bị đầu vào - output_device: Thiết bị đầu ra - players: Người chơi truyền thông -network: - placeholder: - password: Mật khẩu - not_found: Không tìm thấy kết nối mạng - hidden: Mạng ẩn - disconnect: Ngắt kết nối - connect: Kết nối - more: Nhiều cài đặt mạng hơn -settings: - sleep: Ngủ - log_out: Đăng xuất - restart: Khởi động lại - title: Cài đặt - app_settings: Cài đặt ứng dụng - shutdown: Tắt -placeholder: - ethernet_connected: truy cập Internet - settings: Cài đặt nhanh - ethernet_disconnected: Không có kết nối mạng - open_system_tray: Khay mở hệ thống - open_user_folder: Mở thư mục người dùng - volume: Âm lượng - bluetooth_devices: Bluetooth & thiết bị - smart_charge: '- Phí thông minh' - battery_remaining: '% còn lại' - notifications: Thông báo +media: + device: + multimedia: Đa phương tiện + comunications: Truyền thông + master_volume: Khối lượng tổng thể + input_device: Thiết bị đầu vào + output_device: Thiết bị đầu ra + players: Người chơi truyền thông +network: + placeholder: + password: Mật khẩu + not_found: Không tìm thấy kết nối mạng + hidden: Mạng ẩn + disconnect: Ngắt kết nối + connect: Kết nối + more: Nhiều cài đặt mạng hơn +settings: + sleep: Ngủ + log_out: Đăng xuất + restart: Khởi động lại + title: Cài đặt + app_settings: Cài đặt ứng dụng + shutdown: Tắt +placeholder: + ethernet_connected: truy cập Internet + settings: Cài đặt nhanh + ethernet_disconnected: Không có kết nối mạng + open_system_tray: Khay mở hệ thống + open_user_folder: Mở thư mục người dùng + volume: Âm lượng + bluetooth_devices: Bluetooth & thiết bị + smart_charge: '- Phí thông minh' + battery_remaining: '% còn lại' + notifications: Thông báo diff --git a/src/apps/toolbar/i18n/translations/yo.yml b/src/apps/toolbar/i18n/translations/yo.yml index e3238203..ec150d2e 100644 --- a/src/apps/toolbar/i18n/translations/yo.yml +++ b/src/apps/toolbar/i18n/translations/yo.yml @@ -1,34 +1,34 @@ -media: - device: - comunications: Awọn ibaraẹnisọrọ - multimedia: Multimedia - master_volume: Ohun elo - input_device: Ẹrọ titẹ - players: Awọn oṣere Media - output_device: Ẹrọ iṣelọpọ -network: - placeholder: - password: Ọrọ igbaniwọle - disconnect: Ge kuro - not_found: Ko si awọn nẹtiwọki ti a rii - hidden: Nẹtiwọki ti o farapamọ - connect: Sopọ - more: Awọn eto nẹtiwọọki diẹ sii -settings: - shutdown: Paade - title: Ètò - app_settings: Eto App - log_out: Wọle - restart: Tun bẹrẹ - sleep: Sun -placeholder: - ethernet_connected: Wiwọle Intanẹẹti - volume: Iwọn didun - battery_remaining: '% ti o ku' - smart_charge: '- Awọn iṣakoso Smart' - open_user_folder: Ṣiṣi folda olumulo - ethernet_disconnected: Ko si wiwọle intanẹẹti ko si - bluetooth_devices: Bluetooth & awọn ẹrọ - settings: Eto Awọn ọna - open_system_tray: Ṣii Tẹ Tẹ - notifications: Awọn iwifunni +media: + device: + comunications: Awọn ibaraẹnisọrọ + multimedia: Multimedia + master_volume: Ohun elo + input_device: Ẹrọ titẹ + players: Awọn oṣere Media + output_device: Ẹrọ iṣelọpọ +network: + placeholder: + password: Ọrọ igbaniwọle + disconnect: Ge kuro + not_found: Ko si awọn nẹtiwọki ti a rii + hidden: Nẹtiwọki ti o farapamọ + connect: Sopọ + more: Awọn eto nẹtiwọọki diẹ sii +settings: + shutdown: Paade + title: Ètò + app_settings: Eto App + log_out: Wọle + restart: Tun bẹrẹ + sleep: Sun +placeholder: + ethernet_connected: Wiwọle Intanẹẹti + volume: Iwọn didun + battery_remaining: '% ti o ku' + smart_charge: '- Awọn iṣakoso Smart' + open_user_folder: Ṣiṣi folda olumulo + ethernet_disconnected: Ko si wiwọle intanẹẹti ko si + bluetooth_devices: Bluetooth & awọn ẹrọ + settings: Eto Awọn ọna + open_system_tray: Ṣii Tẹ Tẹ + notifications: Awọn iwifunni diff --git a/src/apps/toolbar/i18n/translations/zh.yml b/src/apps/toolbar/i18n/translations/zh.yml index 6c733769..1ae039c4 100644 --- a/src/apps/toolbar/i18n/translations/zh.yml +++ b/src/apps/toolbar/i18n/translations/zh.yml @@ -1,34 +1,34 @@ -media: - master_volume: 主音量 - output_device: 输出设备 - input_device: 输入设备 - players: 媒体播放器 - device: - multimedia: 多媒体 - comunications: 通讯 -network: - not_found: 未找到网络 - more: 更多网络设置 - hidden: 隐藏网络 - placeholder: - password: 密码 - disconnect: 断开连接 - connect: 连接 -settings: - title: 设置 - app_settings: 应用设置 - log_out: 注销 - sleep: 睡眠 - restart: 重启 - shutdown: 关机 -placeholder: - open_user_folder: 打开用户文件夹 - open_system_tray: 打开系统托盘 - bluetooth_devices: 蓝牙和设备 - ethernet_connected: 网络已连接 - ethernet_disconnected: 无网络连接 - volume: 音量 - battery_remaining: '% 剩余' - smart_charge: ' - 智能充电' - settings: 快速设置 - notifications: 通知 +media: + master_volume: 主音量 + output_device: 输出设备 + input_device: 输入设备 + players: 媒体播放器 + device: + multimedia: 多媒体 + comunications: 通讯 +network: + not_found: 未找到网络 + more: 更多网络设置 + hidden: 隐藏网络 + placeholder: + password: 密码 + disconnect: 断开连接 + connect: 连接 +settings: + title: 设置 + app_settings: 应用设置 + log_out: 注销 + sleep: 睡眠 + restart: 重启 + shutdown: 关机 +placeholder: + open_user_folder: 打开用户文件夹 + open_system_tray: 打开系统托盘 + bluetooth_devices: 蓝牙和设备 + ethernet_connected: 网络已连接 + ethernet_disconnected: 无网络连接 + volume: 音量 + battery_remaining: '% 剩余' + smart_charge: ' - 智能充电' + settings: 快速设置 + notifications: 通知 diff --git a/src/apps/toolbar/i18n/translations/zu.yml b/src/apps/toolbar/i18n/translations/zu.yml index 9851e70a..c14393c7 100644 --- a/src/apps/toolbar/i18n/translations/zu.yml +++ b/src/apps/toolbar/i18n/translations/zu.yml @@ -1,34 +1,34 @@ -media: - device: - multimedia: Multimedia - comunications: Ukuxoxisana - output_device: I-Output deturment - players: Abadlali beMedia - master_volume: '-Nqubenzi' - input_device: Idivayisi yokufaka -network: - placeholder: - password: Igama lokuvunyelwa ukungena endaweni ethile - hidden: Inethiwekhi efihliwe - connect: Hlangana - more: Izilungiselelo eziningi zenethiwekhi - not_found: Awekho amanethiwekhi atholakele - disconnect: Thukulula -settings: - shutdown: Vala shaqa - log_out: Phuma - restart: Qalanisa - title: Amasethingi - app_settings: Izilungiselelo zohlelo lokusebenza - sleep: Ukulala -placeholder: - settings: Izilungiselelo ezisheshayo - open_system_tray: I-Open System Tray - ethernet_connected: Ukufinyelela i-Inthanethi - battery_remaining: '% okusele' - bluetooth_devices: I-Bluetooth & Amadivayisi - volume: Ukuvimbanisa - smart_charge: '- Ukushaja okuhle' - open_user_folder: Vula ifolda yomsebenzisi - ethernet_disconnected: Akukho ukufinyelela kwe-inthanethi - notifications: Izaziso +media: + device: + multimedia: Multimedia + comunications: Ukuxoxisana + output_device: I-Output deturment + players: Abadlali beMedia + master_volume: '-Nqubenzi' + input_device: Idivayisi yokufaka +network: + placeholder: + password: Igama lokuvunyelwa ukungena endaweni ethile + hidden: Inethiwekhi efihliwe + connect: Hlangana + more: Izilungiselelo eziningi zenethiwekhi + not_found: Awekho amanethiwekhi atholakele + disconnect: Thukulula +settings: + shutdown: Vala shaqa + log_out: Phuma + restart: Qalanisa + title: Amasethingi + app_settings: Izilungiselelo zohlelo lokusebenza + sleep: Ukulala +placeholder: + settings: Izilungiselelo ezisheshayo + open_system_tray: I-Open System Tray + ethernet_connected: Ukufinyelela i-Inthanethi + battery_remaining: '% okusele' + bluetooth_devices: I-Bluetooth & Amadivayisi + volume: Ukuvimbanisa + smart_charge: '- Ukushaja okuhle' + open_user_folder: Vula ifolda yomsebenzisi + ethernet_disconnected: Akukho ukufinyelela kwe-inthanethi + notifications: Izaziso diff --git a/src/apps/toolbar/index.html b/src/apps/toolbar/index.html index 8c587313..e6e676d6 100644 --- a/src/apps/toolbar/index.html +++ b/src/apps/toolbar/index.html @@ -1,10 +1,10 @@ - - - - - - - -
- - + + + + + + + +
+ + diff --git a/src/apps/toolbar/index.tsx b/src/apps/toolbar/index.tsx index efd3fa2b..de00ee78 100644 --- a/src/apps/toolbar/index.tsx +++ b/src/apps/toolbar/index.tsx @@ -1,39 +1,39 @@ -import { getRootContainer } from '../shared'; -import { wrapConsole } from '../shared/ConsoleWrapper'; -import { registerDocumentEvents } from './events'; -import i18n, { loadTranslations } from './i18n'; -import { createRoot } from 'react-dom/client'; -import { I18nextProvider } from 'react-i18next'; -import { Provider } from 'react-redux'; - -import { loadStore, registerStoreEvents, store } from './modules/shared/store/infra'; -import { loadConstants } from './modules/shared/utils/infra'; - -import { App } from './app'; - -import './styles/colors.css'; -import './styles/variables.css'; -import './styles/reset.css'; -import './styles/global.css'; - -async function Main() { - wrapConsole(); - const container = getRootContainer(); - - registerDocumentEvents(container); - - await loadConstants(); - await registerStoreEvents(); - await loadStore(); - await loadTranslations(); - - createRoot(container).render( - - - - - , - ); -} - -Main(); +import { getRootContainer } from '../shared'; +import { wrapConsole } from '../shared/ConsoleWrapper'; +import { registerDocumentEvents } from './events'; +import i18n, { loadTranslations } from './i18n'; +import { createRoot } from 'react-dom/client'; +import { I18nextProvider } from 'react-i18next'; +import { Provider } from 'react-redux'; + +import { loadStore, registerStoreEvents, store } from './modules/shared/store/infra'; +import { loadConstants } from './modules/shared/utils/infra'; + +import { App } from './app'; + +import './styles/colors.css'; +import './styles/variables.css'; +import './styles/reset.css'; +import './styles/global.css'; + +async function Main() { + wrapConsole(); + const container = getRootContainer(); + + registerDocumentEvents(container); + + await loadConstants(); + await registerStoreEvents(); + await loadStore(); + await loadTranslations(); + + createRoot(container).render( + + + + + , + ); +} + +Main(); diff --git a/src/apps/toolbar/modules/Date/infra.tsx b/src/apps/toolbar/modules/Date/infra.tsx index 853d16b1..e1db3e3b 100644 --- a/src/apps/toolbar/modules/Date/infra.tsx +++ b/src/apps/toolbar/modules/Date/infra.tsx @@ -1,29 +1,29 @@ -import { DateToolbarModule, TimeUnit } from '../../../shared/schemas/Placeholders'; -import moment from 'moment'; -import { useEffect, useState } from 'react'; - -import { Item } from '../item/infra'; - -interface Props { - module: DateToolbarModule; -} - -const timeByUnit = { - [TimeUnit.SECOND]: 1000, - [TimeUnit.MINUTE]: 1000 * 60, - [TimeUnit.HOUR]: 1000 * 60 * 60, - [TimeUnit.DAY]: 1000 * 60 * 60 * 24, -}; - -export function DateModule({ module }: Props) { - const [date, setDate] = useState(moment().format(module.format)); - - useEffect(() => { - const id = setInterval(() => { - setDate(moment().format(module.format)); - }, timeByUnit[module.each]); - return () => clearInterval(id); - }, [module]); - - return ; +import { DateToolbarModule, TimeUnit } from '../../../shared/schemas/Placeholders'; +import moment from 'moment'; +import { useEffect, useState } from 'react'; + +import { Item } from '../item/infra'; + +interface Props { + module: DateToolbarModule; +} + +const timeByUnit = { + [TimeUnit.SECOND]: 1000, + [TimeUnit.MINUTE]: 1000 * 60, + [TimeUnit.HOUR]: 1000 * 60 * 60, + [TimeUnit.DAY]: 1000 * 60 * 60 * 24, +}; + +export function DateModule({ module }: Props) { + const [date, setDate] = useState(moment().format(module.format)); + + useEffect(() => { + const id = setInterval(() => { + setDate(moment().format(module.format)); + }, timeByUnit[module.each]); + return () => clearInterval(id); + }, [module]); + + return ; } \ No newline at end of file diff --git a/src/apps/toolbar/modules/Device/infra.tsx b/src/apps/toolbar/modules/Device/infra.tsx index 86cdf7a6..87219f95 100644 --- a/src/apps/toolbar/modules/Device/infra.tsx +++ b/src/apps/toolbar/modules/Device/infra.tsx @@ -1,11 +1,11 @@ -import { DeviceTM } from '../../../shared/schemas/Placeholders'; - -import { Item } from '../item/infra'; - -interface Props { - module: DeviceTM; -} - -export function DeviceModule({ module }: Props) { - return ; -} +import { DeviceTM } from '../../../shared/schemas/Placeholders'; + +import { Item } from '../item/infra'; + +interface Props { + module: DeviceTM; +} + +export function DeviceModule({ module }: Props) { + return ; +} diff --git a/src/apps/toolbar/modules/Notifications/infra/Module.tsx b/src/apps/toolbar/modules/Notifications/infra/Module.tsx index b2047ba5..3cab461c 100644 --- a/src/apps/toolbar/modules/Notifications/infra/Module.tsx +++ b/src/apps/toolbar/modules/Notifications/infra/Module.tsx @@ -1,42 +1,42 @@ -import { NotificationsTM } from '../../../../shared/schemas/Placeholders'; -import { Notifications } from './Notifications'; -import { emit } from '@tauri-apps/api/event'; -import { Popover } from 'antd'; -import { useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; - -import { Item } from '../../item/infra'; -import { useAppBlur } from '../../shared/hooks/infra'; - -import { Selectors } from '../../shared/store/app'; - -import { RootState } from '../../shared/store/domain'; - -interface Props { - module: NotificationsTM; -} - -export function NotificationsModule({ module }: Props) { - const [openPreview, setOpenPreview] = useState(false); - const count = useSelector((state: RootState) => Selectors.notifications(state).length); - - useAppBlur(() => { - setOpenPreview(false); - }); - - useEffect(() => { - emit('register-notifications-events'); - }, []); - - return ( - } - > - - - ); -} +import { NotificationsTM } from '../../../../shared/schemas/Placeholders'; +import { Notifications } from './Notifications'; +import { emit } from '@tauri-apps/api/event'; +import { Popover } from 'antd'; +import { useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; + +import { Item } from '../../item/infra'; +import { useAppBlur } from '../../shared/hooks/infra'; + +import { Selectors } from '../../shared/store/app'; + +import { RootState } from '../../shared/store/domain'; + +interface Props { + module: NotificationsTM; +} + +export function NotificationsModule({ module }: Props) { + const [openPreview, setOpenPreview] = useState(false); + const count = useSelector((state: RootState) => Selectors.notifications(state).length); + + useAppBlur(() => { + setOpenPreview(false); + }); + + useEffect(() => { + emit('register-notifications-events'); + }, []); + + return ( + } + > + + + ); +} diff --git a/src/apps/toolbar/modules/Notifications/infra/Notifications.tsx b/src/apps/toolbar/modules/Notifications/infra/Notifications.tsx index 811c125f..8a98f543 100644 --- a/src/apps/toolbar/modules/Notifications/infra/Notifications.tsx +++ b/src/apps/toolbar/modules/Notifications/infra/Notifications.tsx @@ -1,99 +1,99 @@ -import { Icon } from '../../../../shared/components/Icon'; -import { invoke } from '@tauri-apps/api/core'; -import { Button } from 'antd'; -import { AnimatePresence, motion } from 'framer-motion'; -import moment from 'moment'; -import { useSelector } from 'react-redux'; - -import { BackgroundByLayersV2 } from '../../../../seelenweg/components/BackgroundByLayers/infra'; - -import { Selectors } from '../../shared/store/app'; - -// Difference between Windows epoch (1601) and Unix epoch (1970) in milliseconds -const EPOCH_DIFF_MILLISECONDS = 11644473600000n; - -function WindowsDateFileTimeToDate(fileTime: bigint) { - return new Date(Number(fileTime / 10000n - EPOCH_DIFF_MILLISECONDS)); -} - -export function Notifications() { - const notifications = useSelector(Selectors.notifications); - - return ( - -
- Notifications - -
- -
- - {notifications.map((notification) => ( - -
-
- -
{notification.app_name}
- - -
- {moment(WindowsDateFileTimeToDate(BigInt(notification.date))).fromNow()} -
-
- -
-
-

{notification.body[0]}

- {notification.body.slice(1).map((body, idx) => ( -

{body}

- ))} -
-
- ))} -
- - {!notifications.length && ( - -

No notifications

-
- )} -
-
- -
-
- ); -} +import { Icon } from '../../../../shared/components/Icon'; +import { invoke } from '@tauri-apps/api/core'; +import { Button } from 'antd'; +import { AnimatePresence, motion } from 'framer-motion'; +import moment from 'moment'; +import { useSelector } from 'react-redux'; + +import { BackgroundByLayersV2 } from '../../../../seelenweg/components/BackgroundByLayers/infra'; + +import { Selectors } from '../../shared/store/app'; + +// Difference between Windows epoch (1601) and Unix epoch (1970) in milliseconds +const EPOCH_DIFF_MILLISECONDS = 11644473600000n; + +function WindowsDateFileTimeToDate(fileTime: bigint) { + return new Date(Number(fileTime / 10000n - EPOCH_DIFF_MILLISECONDS)); +} + +export function Notifications() { + const notifications = useSelector(Selectors.notifications); + + return ( + +
+ Notifications + +
+ +
+ + {notifications.map((notification) => ( + +
+
+ +
{notification.app_name}
+ - +
+ {moment(WindowsDateFileTimeToDate(BigInt(notification.date))).fromNow()} +
+
+ +
+
+

{notification.body[0]}

+ {notification.body.slice(1).map((body, idx) => ( +

{body}

+ ))} +
+
+ ))} +
+ + {!notifications.length && ( + +

No notifications

+
+ )} +
+
+ +
+
+ ); +} diff --git a/src/apps/toolbar/modules/Power/infra.tsx b/src/apps/toolbar/modules/Power/infra.tsx index 157c7b9e..cdf35687 100644 --- a/src/apps/toolbar/modules/Power/infra.tsx +++ b/src/apps/toolbar/modules/Power/infra.tsx @@ -1,36 +1,36 @@ -import { PowerToolbarModule } from '../../../shared/schemas/Placeholders'; -import { emit } from '@tauri-apps/api/event'; -import { useEffect } from 'react'; -import { useSelector } from 'react-redux'; - -import { Item } from '../item/infra'; - -import { Selectors } from '../shared/store/app'; - -interface Props { - module: PowerToolbarModule; -} - -export function PowerModule({ module }: Props) { - const power = useSelector(Selectors.powerStatus); - const batteries = useSelector(Selectors.batteries); - - useEffect(() => { - emit('register-power-events'); - }, []); - - if (!batteries.length) { - return null; - } - - return ( - - ); -} +import { PowerToolbarModule } from '../../../shared/schemas/Placeholders'; +import { emit } from '@tauri-apps/api/event'; +import { useEffect } from 'react'; +import { useSelector } from 'react-redux'; + +import { Item } from '../item/infra'; + +import { Selectors } from '../shared/store/app'; + +interface Props { + module: PowerToolbarModule; +} + +export function PowerModule({ module }: Props) { + const power = useSelector(Selectors.powerStatus); + const batteries = useSelector(Selectors.batteries); + + useEffect(() => { + emit('register-power-events'); + }, []); + + if (!batteries.length) { + return null; + } + + return ( + + ); +} diff --git a/src/apps/toolbar/modules/Settings/infra.tsx b/src/apps/toolbar/modules/Settings/infra.tsx index d39f7720..8bd6d263 100644 --- a/src/apps/toolbar/modules/Settings/infra.tsx +++ b/src/apps/toolbar/modules/Settings/infra.tsx @@ -1,158 +1,158 @@ -import { Icon } from '../../../shared/components/Icon'; -import { SettingsToolbarModule } from '../../../shared/schemas/Placeholders'; -import { invoke } from '@tauri-apps/api/core'; -import { emit } from '@tauri-apps/api/event'; -import { Popover, Slider, Tooltip } from 'antd'; -import React, { useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; - -import { BackgroundByLayersV2 } from '../../../seelenweg/components/BackgroundByLayers/infra'; -import { Item } from '../item/infra'; -import { VolumeControl } from '../media/infra/MediaControls'; -import { useAppBlur } from '../shared/hooks/infra'; - -import { Selectors } from '../shared/store/app'; - -import { RootState } from '../shared/store/domain'; - -interface Props { - module: SettingsToolbarModule; -} - -interface Brightness { - min: number; - max: number; - current: number; -} - -export function SettingsModule({ module }: Props) { - const [openPreview, setOpenPreview] = useState(false); - const [brightness, setBrightness] = useState({ - min: 0, - max: 0, - current: 0, - }); - - const defaultInput = useSelector((state: RootState) => - Selectors.mediaInputs(state).find((d) => d.is_default_multimedia), - ); - const defaultOutput = useSelector((state: RootState) => - Selectors.mediaOutputs(state).find((d) => d.is_default_multimedia), - ); - - const { t } = useTranslation(); - - useEffect(() => { - emit('register-media-events'); - }, []); - - useEffect(() => { - invoke('get_main_monitor_brightness') - .then(setBrightness) - .catch(() => { - // TODO brightness is always failing - // console.error(e); - }); - }, [openPreview]); - - useAppBlur(() => { - setOpenPreview(false); - }); - - return ( - - -
- {t('settings.title')} - - - -
- - {!!(defaultInput || defaultOutput) && ( - {t('media.master_volume')} - )} - - {!!defaultOutput && ( -
- - } - /> -
- )} - - {!!defaultInput && ( -
- } - /> -
- )} - - {brightness.max > 0 && ( -
- - setBrightness({ ...brightness, current: value })} - min={brightness.min} - max={brightness.max} - /> -
- )} - - {t('settings.power')} -
- - - - - - - - - - - - -
-
- } - > - - - ); -} +import { Icon } from '../../../shared/components/Icon'; +import { SettingsToolbarModule } from '../../../shared/schemas/Placeholders'; +import { invoke } from '@tauri-apps/api/core'; +import { emit } from '@tauri-apps/api/event'; +import { Popover, Slider, Tooltip } from 'antd'; +import React, { useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; + +import { BackgroundByLayersV2 } from '../../../seelenweg/components/BackgroundByLayers/infra'; +import { Item } from '../item/infra'; +import { VolumeControl } from '../media/infra/MediaControls'; +import { useAppBlur } from '../shared/hooks/infra'; + +import { Selectors } from '../shared/store/app'; + +import { RootState } from '../shared/store/domain'; + +interface Props { + module: SettingsToolbarModule; +} + +interface Brightness { + min: number; + max: number; + current: number; +} + +export function SettingsModule({ module }: Props) { + const [openPreview, setOpenPreview] = useState(false); + const [brightness, setBrightness] = useState({ + min: 0, + max: 0, + current: 0, + }); + + const defaultInput = useSelector((state: RootState) => + Selectors.mediaInputs(state).find((d) => d.is_default_multimedia), + ); + const defaultOutput = useSelector((state: RootState) => + Selectors.mediaOutputs(state).find((d) => d.is_default_multimedia), + ); + + const { t } = useTranslation(); + + useEffect(() => { + emit('register-media-events'); + }, []); + + useEffect(() => { + invoke('get_main_monitor_brightness') + .then(setBrightness) + .catch(() => { + // TODO brightness is always failing + // console.error(e); + }); + }, [openPreview]); + + useAppBlur(() => { + setOpenPreview(false); + }); + + return ( + + +
+ {t('settings.title')} + + + +
+ + {!!(defaultInput || defaultOutput) && ( + {t('media.master_volume')} + )} + + {!!defaultOutput && ( +
+ + } + /> +
+ )} + + {!!defaultInput && ( +
+ } + /> +
+ )} + + {brightness.max > 0 && ( +
+ + setBrightness({ ...brightness, current: value })} + min={brightness.min} + max={brightness.max} + /> +
+ )} + + {t('settings.power')} +
+ + + + + + + + + + + + +
+
+ } + > + + + ); +} diff --git a/src/apps/toolbar/modules/Tray/index.tsx b/src/apps/toolbar/modules/Tray/index.tsx index 99da8975..4e3359d5 100644 --- a/src/apps/toolbar/modules/Tray/index.tsx +++ b/src/apps/toolbar/modules/Tray/index.tsx @@ -1,71 +1,71 @@ -import { TrayTM } from '../../../shared/schemas/Placeholders'; -import { convertFileSrc, invoke } from '@tauri-apps/api/core'; -import { emit } from '@tauri-apps/api/event'; -import { Popover } from 'antd'; -import { useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; - -import { BackgroundByLayersV2 } from '../../../seelenweg/components/BackgroundByLayers/infra'; -import { Item } from '../item/infra'; -import { useAppBlur } from '../shared/hooks/infra'; -import { LAZY_CONSTANTS } from '../shared/utils/infra'; - -import { Selectors } from '../shared/store/app'; - -interface Props { - module: TrayTM; -} - -export function TrayModule({ module }: Props) { - const [openPreview, setOpenPreview] = useState(false); - - const trayList = useSelector(Selectors.systemTray); - - useEffect(() => { - emit('register-tray-events'); - }, []); - - useAppBlur(() => { - setOpenPreview(false); - }); - - return ( - { - if (open) { - invoke('temp_get_by_event_tray_info'); - } - setOpenPreview(open); - }} - arrow={false} - content={ - -
    - {trayList.map((tray, idx) => ( -
  • { - invoke('on_click_tray_icon', { idx }); - setOpenPreview(false); - }} - onContextMenu={() => invoke('on_context_menu_tray_icon', { idx })} - > -
    - -
    -
    {tray.label}
    -
  • - ))} -
-
- } - > - -
- ); -} +import { TrayTM } from '../../../shared/schemas/Placeholders'; +import { convertFileSrc, invoke } from '@tauri-apps/api/core'; +import { emit } from '@tauri-apps/api/event'; +import { Popover } from 'antd'; +import { useEffect, useState } from 'react'; +import { useSelector } from 'react-redux'; + +import { BackgroundByLayersV2 } from '../../../seelenweg/components/BackgroundByLayers/infra'; +import { Item } from '../item/infra'; +import { useAppBlur } from '../shared/hooks/infra'; +import { LAZY_CONSTANTS } from '../shared/utils/infra'; + +import { Selectors } from '../shared/store/app'; + +interface Props { + module: TrayTM; +} + +export function TrayModule({ module }: Props) { + const [openPreview, setOpenPreview] = useState(false); + + const trayList = useSelector(Selectors.systemTray); + + useEffect(() => { + emit('register-tray-events'); + }, []); + + useAppBlur(() => { + setOpenPreview(false); + }); + + return ( + { + if (open) { + invoke('temp_get_by_event_tray_info'); + } + setOpenPreview(open); + }} + arrow={false} + content={ + +
    + {trayList.map((tray, idx) => ( +
  • { + invoke('on_click_tray_icon', { idx }); + setOpenPreview(false); + }} + onContextMenu={() => invoke('on_context_menu_tray_icon', { idx })} + > +
    + +
    +
    {tray.label}
    +
  • + ))} +
+
+ } + > + +
+ ); +} diff --git a/src/apps/toolbar/modules/Workspaces/index.tsx b/src/apps/toolbar/modules/Workspaces/index.tsx index cd1de70c..d0346ccc 100644 --- a/src/apps/toolbar/modules/Workspaces/index.tsx +++ b/src/apps/toolbar/modules/Workspaces/index.tsx @@ -1,66 +1,66 @@ -import { WorkspacesTM, WorkspaceTMMode } from '../../../shared/schemas/Placeholders'; -import { cx } from '../../../shared/styles'; -import { invoke } from '@tauri-apps/api/core'; -import { Tooltip } from 'antd'; -import { Reorder } from 'framer-motion'; -import { useSelector } from 'react-redux'; - -import { Selectors } from '../shared/store/app'; - -interface Props { - module: WorkspacesTM; -} - -export function WorkspacesModule({ module }: Props) { - const workspaces = useSelector(Selectors.workspaces); - const activeWorkspace = useSelector(Selectors.activeWorkspace); - - const { mode } = module; - - if (mode === WorkspaceTMMode.Dotted) { - return ( - -
    - {workspaces.map((_, idx) => ( -
  • invoke('switch_workspace', { idx })} - className={cx('workspace-dot', { - 'workspace-dot-active': idx === activeWorkspace, - })} - /> - ))} -
-
- ); - } - - return ( - - {workspaces.map((name, idx) => { - return ( - -
invoke('switch_workspace', { idx })} - > -
- {mode === WorkspaceTMMode.Named ? `${name}` : `${idx + 1}`} -
-
-
- ); - })} -
- ); -} +import { WorkspacesTM, WorkspaceTMMode } from '../../../shared/schemas/Placeholders'; +import { cx } from '../../../shared/styles'; +import { invoke } from '@tauri-apps/api/core'; +import { Tooltip } from 'antd'; +import { Reorder } from 'framer-motion'; +import { useSelector } from 'react-redux'; + +import { Selectors } from '../shared/store/app'; + +interface Props { + module: WorkspacesTM; +} + +export function WorkspacesModule({ module }: Props) { + const workspaces = useSelector(Selectors.workspaces); + const activeWorkspace = useSelector(Selectors.activeWorkspace); + + const { mode } = module; + + if (mode === WorkspaceTMMode.Dotted) { + return ( + +
    + {workspaces.map((_, idx) => ( +
  • invoke('switch_workspace', { idx })} + className={cx('workspace-dot', { + 'workspace-dot-active': idx === activeWorkspace, + })} + /> + ))} +
+
+ ); + } + + return ( + + {workspaces.map((name, idx) => { + return ( + +
invoke('switch_workspace', { idx })} + > +
+ {mode === WorkspaceTMMode.Named ? `${name}` : `${idx + 1}`} +
+
+
+ ); + })} +
+ ); +} diff --git a/src/apps/toolbar/modules/item/app.ts b/src/apps/toolbar/modules/item/app.ts index 802c2a5d..bda8eeb9 100644 --- a/src/apps/toolbar/modules/item/app.ts +++ b/src/apps/toolbar/modules/item/app.ts @@ -1,90 +1,90 @@ -import { invoke } from '@tauri-apps/api/core'; -import { evaluate } from 'mathjs'; - -/** @deprecated remove on v2 */ -export enum Actions { - Open = 'open', - CopyToClipboard = 'copy-to-clipboard', - SwitchWorkspace = 'switch-workspace', -} - -/** @deprecated remove on v2 */ -export function performClick(onClick: string | null, scope: any) { - if (!onClick) { - return; - } - - const [_action, _argument] = onClick.split('->'); - const action = _action?.trim(); - const argument = _argument?.trim(); - - if (!action) { - return; - } - - switch (action) { - case Actions.Open: - if (argument) { - invoke('open_file', { path: evaluate(argument, scope) }); - } - break; - case Actions.CopyToClipboard: - if (argument) { - navigator.clipboard.writeText(evaluate(argument, scope)); - } - case Actions.SwitchWorkspace: - if (argument) { - invoke('switch_workspace', { idx: evaluate(argument, scope) }); - } - } -} - -export class Scope { - scope: Map; - - constructor() { - this.scope = new Map(); - } - - get(key: string) { - return this.scope.get(key); - } - - set(key: string, value: any) { - return this.scope.set(key, value); - } - - has(key: string) { - return this.scope.has(key); - } - - keys(): string[] | IterableIterator { - return this.scope.keys(); - } - - loadInvokeActions() { - for (const [key, value] of Object.entries(ActionsScope)) { - this.set(key, value); - } - } -} - -const ActionsScope = { - open(path: string) { - invoke('open_file', { path }).catch(console.error); - }, - run(program: string, ...args: string[]) { - invoke('run', { program, args }).catch(console.error); - }, - copyClipboard(text: string) { - navigator.clipboard.writeText(text); - }, -}; - -export function safeEval(expression: string, scope: Scope) { - try { - evaluate(expression, scope); - } catch (error) { - console.error(error); - } +import { invoke } from '@tauri-apps/api/core'; +import { evaluate } from 'mathjs'; + +/** @deprecated remove on v2 */ +export enum Actions { + Open = 'open', + CopyToClipboard = 'copy-to-clipboard', + SwitchWorkspace = 'switch-workspace', +} + +/** @deprecated remove on v2 */ +export function performClick(onClick: string | null, scope: any) { + if (!onClick) { + return; + } + + const [_action, _argument] = onClick.split('->'); + const action = _action?.trim(); + const argument = _argument?.trim(); + + if (!action) { + return; + } + + switch (action) { + case Actions.Open: + if (argument) { + invoke('open_file', { path: evaluate(argument, scope) }); + } + break; + case Actions.CopyToClipboard: + if (argument) { + navigator.clipboard.writeText(evaluate(argument, scope)); + } + case Actions.SwitchWorkspace: + if (argument) { + invoke('switch_workspace', { idx: evaluate(argument, scope) }); + } + } +} + +export class Scope { + scope: Map; + + constructor() { + this.scope = new Map(); + } + + get(key: string) { + return this.scope.get(key); + } + + set(key: string, value: any) { + return this.scope.set(key, value); + } + + has(key: string) { + return this.scope.has(key); + } + + keys(): string[] | IterableIterator { + return this.scope.keys(); + } + + loadInvokeActions() { + for (const [key, value] of Object.entries(ActionsScope)) { + this.set(key, value); + } + } +} + +const ActionsScope = { + open(path: string) { + invoke('open_file', { path }).catch(console.error); + }, + run(program: string, ...args: string[]) { + invoke('run', { program, args }).catch(console.error); + }, + copyClipboard(text: string) { + navigator.clipboard.writeText(text); + }, +}; + +export function safeEval(expression: string, scope: Scope) { + try { + evaluate(expression, scope); + } catch (error) { + console.error(error); + } } \ No newline at end of file diff --git a/src/apps/toolbar/modules/item/infra.tsx b/src/apps/toolbar/modules/item/infra.tsx index 3f44fc2d..86103aa0 100644 --- a/src/apps/toolbar/modules/item/infra.tsx +++ b/src/apps/toolbar/modules/item/infra.tsx @@ -1,231 +1,231 @@ -import { exposedIcons, Icon, IconName } from '../../../shared/components/Icon'; -import { ToolbarModule } from '../../../shared/schemas/Placeholders'; -import { cx } from '../../../shared/styles'; -import { convertFileSrc, invoke } from '@tauri-apps/api/core'; -import { Tooltip } from 'antd'; -import { Reorder } from 'framer-motion'; -import { cloneDeep } from 'lodash'; -import { evaluate } from 'mathjs'; -import React, { PropsWithChildren, useEffect, useRef } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; - -import { LAZY_CONSTANTS } from '../shared/utils/infra'; - -import { Selectors } from '../shared/store/app'; -import { performClick, safeEval, Scope } from './app'; - -interface Props extends PropsWithChildren { - module: ToolbarModule; - extraVars?: Record; - active?: boolean; - // needed for dropdown/popup wrappers - onClick?: (e: React.MouseEvent) => void; - onKeydown?: (e: React.KeyboardEvent) => void; -} - -interface StringToElementProps { - text: string; -} - -interface StringToElementState { - exe_icon_path: string; -} - -class StringToElement extends React.PureComponent { - static splitter = /:([^:]+):/; - - static imgPrefix = 'IMG:'; - static iconPrefix = 'ICON:'; - static exePrefix = 'EXE:'; - - static imgFromUrl(url: string, size = 16) { - if (!url) { - return ''; - } - return `[IMG:${size}px:${url}]`; - } - - static imgFromPath(path: string, size = 16) { - if (!path) { - return ''; - } - return StringToElement.imgFromUrl(convertFileSrc(path), size); - } - - static imgFromExe(exe_path: string, size = 16) { - if (!exe_path) { - return ''; - } - return `[EXE:${size}px:${exe_path}]`; - } - - constructor(props: StringToElementProps) { - super(props); - this.state = { exe_icon_path: LAZY_CONSTANTS.MISSING_ICON_PATH }; - } - - isImg() { - return this.props.text.startsWith(StringToElement.imgPrefix); - } - - isIcon() { - return this.props.text.startsWith(StringToElement.iconPrefix); - } - - isExe() { - return this.props.text.startsWith(StringToElement.exePrefix); - } - - setExeIcon(exe_path: string | null) { - this.setState({ exe_icon_path: exe_path || LAZY_CONSTANTS.MISSING_ICON_PATH }); - } - - loadExeIconToState() { - if (this.isExe()) { - const [_, _size, path] = this.props.text.split(StringToElement.splitter); - if (path) { - invoke('get_icon', { path }) - .then(this.setExeIcon.bind(this)) - .catch(console.error); - } - } - } - - componentDidMount() { - this.loadExeIconToState(); - } - - componentDidUpdate(prevProps: StringToElementProps) { - if (this.props.text !== prevProps.text) { - this.loadExeIconToState(); - } - } - - render() { - if (this.isExe()) { - const [_, width] = this.props.text.split(StringToElement.splitter); - return ; - } - - if (this.isImg()) { - const [_, width, url] = this.props.text.split(StringToElement.splitter); - return ; - } - - if (this.isIcon()) { - const [_, iconName, size] = this.props.text.split(':'); - return ( - - ); - } - - return {this.props.text}; - } -} - -export function ElementsFromEvaluated(content: any) { - let text: string = content; - - if (typeof content !== 'string') { - text = JSON.stringify(content); - } - - const parts: string[] = text.split(/\[|\]/g).filter((part: string) => part); - const result: React.ReactNode[] = parts.map((part: string, index: number) => { - return ; - }); - - return result; -} - -export function Item(props: Props) { - const { - extraVars, - module, - active, - onClick: onClickProp, - onKeydown: onKeydownProp, - children, - } = props; - const { template, tooltip, onClick: oldOnClick, onClickV2, style, id, badge } = module; - - const [mounted, setMounted] = React.useState(false); - const env = useSelector(Selectors.env); - const window = useSelector(Selectors.focused) || { - name: 'None', - title: 'No Window Focused', - }; - - const { t } = useTranslation(); - const scope = useRef(new Scope()); - - useEffect(() => { - scope.current.loadInvokeActions(); - - scope.current.set('icon', cloneDeep(exposedIcons)); - scope.current.set('env', cloneDeep(env)); - scope.current.set('imgFromUrl', StringToElement.imgFromUrl); - scope.current.set('imgFromPath', StringToElement.imgFromPath); - scope.current.set('imgFromExe', StringToElement.imgFromExe); - setMounted(true); - }, []); - - if (!mounted) { - return null; - } - - scope.current.set('t', t); - scope.current.set('window', { ...window }); - if (extraVars) { - Object.keys(extraVars).forEach((key) => { - scope.current.set(key, extraVars[key]); - }); - } - - const elements = ElementsFromEvaluated(evaluate(template, scope.current)); - if (!elements.length && !children) { - return null; - } - - const badgeContent = badge ? ElementsFromEvaluated(evaluate(badge, scope.current)) : null; - - return ( - - { - onClickProp?.(e); - - if (onClickV2) { - safeEval(onClickV2, scope.current); - } - - performClick(oldOnClick, scope.current); - }} - value={module} - as="div" - transition={{ duration: 0.15 }} - > -
- {children || elements} - {!!badgeContent?.length &&
{badgeContent}
} -
-
-
- ); -} +import { exposedIcons, Icon, IconName } from '../../../shared/components/Icon'; +import { ToolbarModule } from '../../../shared/schemas/Placeholders'; +import { cx } from '../../../shared/styles'; +import { convertFileSrc, invoke } from '@tauri-apps/api/core'; +import { Tooltip } from 'antd'; +import { Reorder } from 'framer-motion'; +import { cloneDeep } from 'lodash'; +import { evaluate } from 'mathjs'; +import React, { PropsWithChildren, useEffect, useRef } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; + +import { LAZY_CONSTANTS } from '../shared/utils/infra'; + +import { Selectors } from '../shared/store/app'; +import { performClick, safeEval, Scope } from './app'; + +interface Props extends PropsWithChildren { + module: ToolbarModule; + extraVars?: Record; + active?: boolean; + // needed for dropdown/popup wrappers + onClick?: (e: React.MouseEvent) => void; + onKeydown?: (e: React.KeyboardEvent) => void; +} + +interface StringToElementProps { + text: string; +} + +interface StringToElementState { + exe_icon_path: string; +} + +class StringToElement extends React.PureComponent { + static splitter = /:([^:]+):/; + + static imgPrefix = 'IMG:'; + static iconPrefix = 'ICON:'; + static exePrefix = 'EXE:'; + + static imgFromUrl(url: string, size = 16) { + if (!url) { + return ''; + } + return `[IMG:${size}px:${url}]`; + } + + static imgFromPath(path: string, size = 16) { + if (!path) { + return ''; + } + return StringToElement.imgFromUrl(convertFileSrc(path), size); + } + + static imgFromExe(exe_path: string, size = 16) { + if (!exe_path) { + return ''; + } + return `[EXE:${size}px:${exe_path}]`; + } + + constructor(props: StringToElementProps) { + super(props); + this.state = { exe_icon_path: LAZY_CONSTANTS.MISSING_ICON_PATH }; + } + + isImg() { + return this.props.text.startsWith(StringToElement.imgPrefix); + } + + isIcon() { + return this.props.text.startsWith(StringToElement.iconPrefix); + } + + isExe() { + return this.props.text.startsWith(StringToElement.exePrefix); + } + + setExeIcon(exe_path: string | null) { + this.setState({ exe_icon_path: exe_path || LAZY_CONSTANTS.MISSING_ICON_PATH }); + } + + loadExeIconToState() { + if (this.isExe()) { + const [_, _size, path] = this.props.text.split(StringToElement.splitter); + if (path) { + invoke('get_icon', { path }) + .then(this.setExeIcon.bind(this)) + .catch(console.error); + } + } + } + + componentDidMount() { + this.loadExeIconToState(); + } + + componentDidUpdate(prevProps: StringToElementProps) { + if (this.props.text !== prevProps.text) { + this.loadExeIconToState(); + } + } + + render() { + if (this.isExe()) { + const [_, width] = this.props.text.split(StringToElement.splitter); + return ; + } + + if (this.isImg()) { + const [_, width, url] = this.props.text.split(StringToElement.splitter); + return ; + } + + if (this.isIcon()) { + const [_, iconName, size] = this.props.text.split(':'); + return ( + + ); + } + + return {this.props.text}; + } +} + +export function ElementsFromEvaluated(content: any) { + let text: string = content; + + if (typeof content !== 'string') { + text = JSON.stringify(content); + } + + const parts: string[] = text.split(/\[|\]/g).filter((part: string) => part); + const result: React.ReactNode[] = parts.map((part: string, index: number) => { + return ; + }); + + return result; +} + +export function Item(props: Props) { + const { + extraVars, + module, + active, + onClick: onClickProp, + onKeydown: onKeydownProp, + children, + } = props; + const { template, tooltip, onClick: oldOnClick, onClickV2, style, id, badge } = module; + + const [mounted, setMounted] = React.useState(false); + const env = useSelector(Selectors.env); + const window = useSelector(Selectors.focused) || { + name: 'None', + title: 'No Window Focused', + }; + + const { t } = useTranslation(); + const scope = useRef(new Scope()); + + useEffect(() => { + scope.current.loadInvokeActions(); + + scope.current.set('icon', cloneDeep(exposedIcons)); + scope.current.set('env', cloneDeep(env)); + scope.current.set('imgFromUrl', StringToElement.imgFromUrl); + scope.current.set('imgFromPath', StringToElement.imgFromPath); + scope.current.set('imgFromExe', StringToElement.imgFromExe); + setMounted(true); + }, []); + + if (!mounted) { + return null; + } + + scope.current.set('t', t); + scope.current.set('window', { ...window }); + if (extraVars) { + Object.keys(extraVars).forEach((key) => { + scope.current.set(key, extraVars[key]); + }); + } + + const elements = ElementsFromEvaluated(evaluate(template, scope.current)); + if (!elements.length && !children) { + return null; + } + + const badgeContent = badge ? ElementsFromEvaluated(evaluate(badge, scope.current)) : null; + + return ( + + { + onClickProp?.(e); + + if (onClickV2) { + safeEval(onClickV2, scope.current); + } + + performClick(oldOnClick, scope.current); + }} + value={module} + as="div" + transition={{ duration: 0.15 }} + > +
+ {children || elements} + {!!badgeContent?.length &&
{badgeContent}
} +
+
+
+ ); +} diff --git a/src/apps/toolbar/modules/main/application.ts b/src/apps/toolbar/modules/main/application.ts index 791d309b..49f7a801 100644 --- a/src/apps/toolbar/modules/main/application.ts +++ b/src/apps/toolbar/modules/main/application.ts @@ -1,40 +1,40 @@ -import { - saveJsonSettings, - UserSettingsLoader, -} from '../../../settings/modules/shared/store/storeApi'; -import { path } from '@tauri-apps/api'; -import { writeTextFile } from '@tauri-apps/plugin-fs'; -import yaml from 'js-yaml'; -import { cloneDeep, debounce } from 'lodash'; - -import { store } from '../shared/store/infra'; - -export const IsSavingCustom = { - current: false, -}; - -export const SavePlaceholderAsCustom = debounce(async () => { - const { placeholder, env } = store.getState(); - - if (!placeholder) return; - - const toBeSaved = cloneDeep(placeholder); - toBeSaved.info.author = env.USERNAME || 'Me'; - toBeSaved.info.displayName = 'Custom'; - toBeSaved.info.description = 'Customized by me'; - toBeSaved.info.filename = 'custom.yml'; - - const filePath = await path.join( - await path.appDataDir(), - 'placeholders', - toBeSaved.info.filename, - ); - - await writeTextFile(filePath, yaml.dump(toBeSaved)); - - let { jsonSettings } = await new UserSettingsLoader().withThemes(false).load(); - jsonSettings.fancyToolbar.placeholder = toBeSaved.info.filename; - - IsSavingCustom.current = true; - await saveJsonSettings(jsonSettings); -}, 1000); +import { + saveJsonSettings, + UserSettingsLoader, +} from '../../../settings/modules/shared/store/storeApi'; +import { path } from '@tauri-apps/api'; +import { writeTextFile } from '@tauri-apps/plugin-fs'; +import yaml from 'js-yaml'; +import { cloneDeep, debounce } from 'lodash'; + +import { store } from '../shared/store/infra'; + +export const IsSavingCustom = { + current: false, +}; + +export const SavePlaceholderAsCustom = debounce(async () => { + const { placeholder, env } = store.getState(); + + if (!placeholder) return; + + const toBeSaved = cloneDeep(placeholder); + toBeSaved.info.author = env.USERNAME || 'Me'; + toBeSaved.info.displayName = 'Custom'; + toBeSaved.info.description = 'Customized by me'; + toBeSaved.info.filename = 'custom.yml'; + + const filePath = await path.join( + await path.appDataDir(), + 'placeholders', + toBeSaved.info.filename, + ); + + await writeTextFile(filePath, yaml.dump(toBeSaved)); + + let { jsonSettings } = await new UserSettingsLoader().withThemes(false).load(); + jsonSettings.fancyToolbar.placeholder = toBeSaved.info.filename; + + IsSavingCustom.current = true; + await saveJsonSettings(jsonSettings); +}, 1000); diff --git a/src/apps/toolbar/modules/main/infra.tsx b/src/apps/toolbar/modules/main/infra.tsx index 88eff380..14b52c91 100644 --- a/src/apps/toolbar/modules/main/infra.tsx +++ b/src/apps/toolbar/modules/main/infra.tsx @@ -1,106 +1,106 @@ -import { - Placeholder, - ToolbarModule, - ToolbarModuleType, -} from '../../../shared/schemas/Placeholders'; -import { TrayModule } from '../Tray'; -import { WorkspacesModule } from '../Workspaces'; -import { Reorder, useForceUpdate } from 'framer-motion'; -import { debounce } from 'lodash'; -import { JSXElementConstructor, useCallback } from 'react'; -import { useDispatch } from 'react-redux'; - -import { BackgroundByLayersV2 } from '../../../seelenweg/components/BackgroundByLayers/infra'; -import { DateModule } from '../Date/infra'; -import { DeviceModule } from '../Device/infra'; -import { Item } from '../item/infra'; -import { MediaModule } from '../media/infra/Module'; -import { NetworkModule } from '../network/infra/Module'; -import { NotificationsModule } from '../Notifications/infra/Module'; -import { PowerModule } from '../Power/infra'; -import { SettingsModule } from '../Settings/infra'; - -import { RootActions } from '../shared/store/app'; -import { SavePlaceholderAsCustom } from './application'; - -const modulesByType: Record> = { - [ToolbarModuleType.Generic]: Item, - [ToolbarModuleType.Text]: Item, - [ToolbarModuleType.Date]: DateModule, - [ToolbarModuleType.Power]: PowerModule, - [ToolbarModuleType.Settings]: SettingsModule, - [ToolbarModuleType.Workspaces]: WorkspacesModule, - [ToolbarModuleType.Tray]: TrayModule, - [ToolbarModuleType.Network]: NetworkModule, - [ToolbarModuleType.Media]: MediaModule, - [ToolbarModuleType.Device]: DeviceModule, - [ToolbarModuleType.Notifications]: NotificationsModule, -}; - -interface Props { - structure: Placeholder; -} - -const DividerStart = 'CenterStart'; -const DividerEnd = 'CenterEnd'; - -function componentByModule(module: ToolbarModule) { - let Component = modulesByType[module.type]; - return ; -} - -export function ToolBar({ structure }: Props) { - const dispatch = useDispatch(); - const [forceUpdate] = useForceUpdate(); - - const onReorderPinned = useCallback( - debounce((apps: (ToolbarModule | string)[]) => { - let dividerStart = apps.indexOf(DividerStart); - let dividerEnd = apps.indexOf(DividerEnd); - - if (dividerStart === -1 || dividerEnd === -1) { - forceUpdate(); - return; - } - - let payload = apps.slice(0, dividerStart) as ToolbarModule[]; - dispatch(RootActions.setItemsOnLeft(payload)); - - payload = apps.slice(dividerStart + 1, dividerEnd) as ToolbarModule[]; - dispatch(RootActions.setItemsOnCenter(payload)); - - payload = apps.slice(dividerEnd + 1) as ToolbarModule[]; - dispatch(RootActions.setItemsOnRight(payload)); - - SavePlaceholderAsCustom()?.catch(console.error); - }, 10), - [], - ); - - return ( - - -
- {structure.left.map(componentByModule)} - -
-
{structure.center.map(componentByModule)}
-
- - {structure.right.map(componentByModule)} -
-
- ); -} +import { + Placeholder, + ToolbarModule, + ToolbarModuleType, +} from '../../../shared/schemas/Placeholders'; +import { TrayModule } from '../Tray'; +import { WorkspacesModule } from '../Workspaces'; +import { Reorder, useForceUpdate } from 'framer-motion'; +import { debounce } from 'lodash'; +import { JSXElementConstructor, useCallback } from 'react'; +import { useDispatch } from 'react-redux'; + +import { BackgroundByLayersV2 } from '../../../seelenweg/components/BackgroundByLayers/infra'; +import { DateModule } from '../Date/infra'; +import { DeviceModule } from '../Device/infra'; +import { Item } from '../item/infra'; +import { MediaModule } from '../media/infra/Module'; +import { NetworkModule } from '../network/infra/Module'; +import { NotificationsModule } from '../Notifications/infra/Module'; +import { PowerModule } from '../Power/infra'; +import { SettingsModule } from '../Settings/infra'; + +import { RootActions } from '../shared/store/app'; +import { SavePlaceholderAsCustom } from './application'; + +const modulesByType: Record> = { + [ToolbarModuleType.Generic]: Item, + [ToolbarModuleType.Text]: Item, + [ToolbarModuleType.Date]: DateModule, + [ToolbarModuleType.Power]: PowerModule, + [ToolbarModuleType.Settings]: SettingsModule, + [ToolbarModuleType.Workspaces]: WorkspacesModule, + [ToolbarModuleType.Tray]: TrayModule, + [ToolbarModuleType.Network]: NetworkModule, + [ToolbarModuleType.Media]: MediaModule, + [ToolbarModuleType.Device]: DeviceModule, + [ToolbarModuleType.Notifications]: NotificationsModule, +}; + +interface Props { + structure: Placeholder; +} + +const DividerStart = 'CenterStart'; +const DividerEnd = 'CenterEnd'; + +function componentByModule(module: ToolbarModule) { + let Component = modulesByType[module.type]; + return ; +} + +export function ToolBar({ structure }: Props) { + const dispatch = useDispatch(); + const [forceUpdate] = useForceUpdate(); + + const onReorderPinned = useCallback( + debounce((apps: (ToolbarModule | string)[]) => { + let dividerStart = apps.indexOf(DividerStart); + let dividerEnd = apps.indexOf(DividerEnd); + + if (dividerStart === -1 || dividerEnd === -1) { + forceUpdate(); + return; + } + + let payload = apps.slice(0, dividerStart) as ToolbarModule[]; + dispatch(RootActions.setItemsOnLeft(payload)); + + payload = apps.slice(dividerStart + 1, dividerEnd) as ToolbarModule[]; + dispatch(RootActions.setItemsOnCenter(payload)); + + payload = apps.slice(dividerEnd + 1) as ToolbarModule[]; + dispatch(RootActions.setItemsOnRight(payload)); + + SavePlaceholderAsCustom()?.catch(console.error); + }, 10), + [], + ); + + return ( + + +
+ {structure.left.map(componentByModule)} + +
+
{structure.center.map(componentByModule)}
+
+ + {structure.right.map(componentByModule)} +
+
+ ); +} diff --git a/src/apps/toolbar/modules/media/application.ts b/src/apps/toolbar/modules/media/application.ts index 6de10ed4..d07af224 100644 --- a/src/apps/toolbar/modules/media/application.ts +++ b/src/apps/toolbar/modules/media/application.ts @@ -1,43 +1,43 @@ -/** Returns a number between 0 and 255 */ -export function calcLuminance(imageUrl: string): Promise { - return new Promise((resolve, reject) => { - const img = new Image(); - img.crossOrigin = 'Anonymous'; - img.src = imageUrl; - - img.onload = () => { - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - - if (!ctx) { - reject(new Error('Unable to get canvas context')); - return; - } - - canvas.width = img.width; - canvas.height = img.height; - ctx.drawImage(img, 0, 0, img.width, img.height); - - const imageData = ctx.getImageData(0, 0, img.width, img.height); - const data = imageData.data; - let totalLuminance = 0; - - for (let i = 0; i < data.length; i += 4) { - const r = data[i] || 0; - const g = data[i + 1] || 0; - const b = data[i + 2] || 0; - - // Calculate luminance - const luminance = 0.299 * r + 0.587 * g + 0.114 * b; - totalLuminance += luminance; - } - - const avgLuminance = totalLuminance / (data.length / 4); - resolve(avgLuminance); - }; - - img.onerror = (err) => { - reject(err); - }; - }); -} +/** Returns a number between 0 and 255 */ +export function calcLuminance(imageUrl: string): Promise { + return new Promise((resolve, reject) => { + const img = new Image(); + img.crossOrigin = 'Anonymous'; + img.src = imageUrl; + + img.onload = () => { + const canvas = document.createElement('canvas'); + const ctx = canvas.getContext('2d'); + + if (!ctx) { + reject(new Error('Unable to get canvas context')); + return; + } + + canvas.width = img.width; + canvas.height = img.height; + ctx.drawImage(img, 0, 0, img.width, img.height); + + const imageData = ctx.getImageData(0, 0, img.width, img.height); + const data = imageData.data; + let totalLuminance = 0; + + for (let i = 0; i < data.length; i += 4) { + const r = data[i] || 0; + const g = data[i + 1] || 0; + const b = data[i + 2] || 0; + + // Calculate luminance + const luminance = 0.299 * r + 0.587 * g + 0.114 * b; + totalLuminance += luminance; + } + + const avgLuminance = totalLuminance / (data.length / 4); + resolve(avgLuminance); + }; + + img.onerror = (err) => { + reject(err); + }; + }); +} diff --git a/src/apps/toolbar/modules/media/infra/MediaControls.tsx b/src/apps/toolbar/modules/media/infra/MediaControls.tsx index 4c876ec5..5326c921 100644 --- a/src/apps/toolbar/modules/media/infra/MediaControls.tsx +++ b/src/apps/toolbar/modules/media/infra/MediaControls.tsx @@ -1,260 +1,260 @@ -import { Icon } from '../../../../shared/components/Icon'; -import { OverflowTooltip } from '../../../../shared/components/OverflowTooltip'; -import { convertFileSrc, invoke } from '@tauri-apps/api/core'; -import { Button, Popover, Slider, Tooltip } from 'antd'; -import { debounce } from 'lodash'; -import React, { PropsWithChildren, useCallback, useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; - -import { BackgroundByLayersV2 } from '../../../../seelenweg/components/BackgroundByLayers/infra'; -import { useAppBlur } from '../../shared/hooks/infra'; -import { LAZY_CONSTANTS } from '../../shared/utils/infra'; - -import { Selectors } from '../../shared/store/app'; -import { calcLuminance } from '../application'; - -import { MediaChannelTransportData, MediaDevice } from '../../shared/store/domain'; - -import './index.css'; - -const MAX_LUMINANCE = 210; -const MIN_LUMINANCE = 40; -const BRIGHTNESS_MULTIPLIER = 1.5; // used in css - -function MediaSession({ session }: { session: MediaChannelTransportData }) { - const [luminance, setLuminance] = useState(0); - - let src = convertFileSrc( - session.thumbnail ? session.thumbnail : LAZY_CONSTANTS.DEFAULT_THUMBNAIL, - ); - - useEffect(() => { - calcLuminance(src).then(setLuminance).catch(console.error); - }, [src]); - - const filteredLuminance = Math.max( - Math.min(luminance * BRIGHTNESS_MULTIPLIER, MAX_LUMINANCE), - MIN_LUMINANCE, - ); - const color = filteredLuminance < 125 ? '#efefef' : '#222222'; - - const onClickBtn = (cmd: string) => { - invoke(cmd, { id: session.id }).catch(console.error); - }; - - return ( -
- - - -
-

{session.title}

- {session.author} -
- - - -
-
-
- ); -} - -function Device({ device }: { device: MediaDevice }) { - const { t } = useTranslation(); - - const onClickMultimedia = () => { - if (!device.is_default_multimedia) { - invoke('media_set_default_device', { id: device.id, role: 'multimedia' }) - .then(() => invoke('media_set_default_device', { id: device.id, role: 'console' })) - .catch(console.error); - } - }; - - const onClickCommunications = () => { - if (!device.is_default_communications) { - invoke('media_set_default_device', { id: device.id, role: 'communications' }).catch( - console.error, - ); - } - }; - - return ( -
- - - - - - - - - -
- ); -} - -function DeviceGroup({ devices }: { devices: MediaDevice[] }) { - return ( -
- {devices.map((d) => ( - - ))} -
- ); -} - -interface VolumeControlProps { - value: number; - icon: React.ReactNode; - deviceId: string; - sessionId?: string; -} - -export function VolumeControl(props: VolumeControlProps) { - const { value, icon, deviceId, sessionId } = props; - - const [internalValue, setInternalValue] = useState(value); - - useEffect(() => { - setInternalValue(value); - }, [value]); - - const onExternalChange = useCallback( - debounce((value: number) => { - invoke('set_volume_level', { id: deviceId, level: value }).catch(console.error); - }, 100), - [deviceId, sessionId], - ); - - const onInternalChange = (value: number) => { - setInternalValue(value); - onExternalChange(value); - }; - - return ( -
- - `${(100 * (value || 0)).toFixed(0)}`, - }} - /> - -
- ); -} - -function MediaControls() { - const { t } = useTranslation(); - - const inputs = useSelector(Selectors.mediaInputs); - const defaultInput = inputs.find((d) => d.is_default_multimedia); - - const outputs = useSelector(Selectors.mediaOutputs); - const defaultOutput = outputs.find((d) => d.is_default_multimedia); - - const sessions = useSelector(Selectors.mediaSessions); - - return ( - - {t('media.master_volume')} - {!!defaultOutput && ( - - } - /> - )} - - {!!defaultInput && ( - } - /> - )} - - {outputs.length > 0 && ( - <> - {t('media.output_device')} - - - )} - - {inputs.length > 0 && ( - <> - {t('media.input_device')} - - - )} - - {sessions.length > 0 && ( - <> - {t('media.players')} -
- {sessions.map((session, index) => ( - - ))} -
- - )} -
- ); -} - -export function WithMediaControls({ children }: PropsWithChildren) { - const [openPreview, setOpenPreview] = useState(false); - - useAppBlur(() => { - setOpenPreview(false); - }); - - return ( - } - > - {children} - - ); -} +import { Icon } from '../../../../shared/components/Icon'; +import { OverflowTooltip } from '../../../../shared/components/OverflowTooltip'; +import { convertFileSrc, invoke } from '@tauri-apps/api/core'; +import { Button, Popover, Slider, Tooltip } from 'antd'; +import { debounce } from 'lodash'; +import React, { PropsWithChildren, useCallback, useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; + +import { BackgroundByLayersV2 } from '../../../../seelenweg/components/BackgroundByLayers/infra'; +import { useAppBlur } from '../../shared/hooks/infra'; +import { LAZY_CONSTANTS } from '../../shared/utils/infra'; + +import { Selectors } from '../../shared/store/app'; +import { calcLuminance } from '../application'; + +import { MediaChannelTransportData, MediaDevice } from '../../shared/store/domain'; + +import './index.css'; + +const MAX_LUMINANCE = 210; +const MIN_LUMINANCE = 40; +const BRIGHTNESS_MULTIPLIER = 1.5; // used in css + +function MediaSession({ session }: { session: MediaChannelTransportData }) { + const [luminance, setLuminance] = useState(0); + + let src = convertFileSrc( + session.thumbnail ? session.thumbnail : LAZY_CONSTANTS.DEFAULT_THUMBNAIL, + ); + + useEffect(() => { + calcLuminance(src).then(setLuminance).catch(console.error); + }, [src]); + + const filteredLuminance = Math.max( + Math.min(luminance * BRIGHTNESS_MULTIPLIER, MAX_LUMINANCE), + MIN_LUMINANCE, + ); + const color = filteredLuminance < 125 ? '#efefef' : '#222222'; + + const onClickBtn = (cmd: string) => { + invoke(cmd, { id: session.id }).catch(console.error); + }; + + return ( +
+ + + +
+

{session.title}

+ {session.author} +
+ + + +
+
+
+ ); +} + +function Device({ device }: { device: MediaDevice }) { + const { t } = useTranslation(); + + const onClickMultimedia = () => { + if (!device.is_default_multimedia) { + invoke('media_set_default_device', { id: device.id, role: 'multimedia' }) + .then(() => invoke('media_set_default_device', { id: device.id, role: 'console' })) + .catch(console.error); + } + }; + + const onClickCommunications = () => { + if (!device.is_default_communications) { + invoke('media_set_default_device', { id: device.id, role: 'communications' }).catch( + console.error, + ); + } + }; + + return ( +
+ + + + + + + + + +
+ ); +} + +function DeviceGroup({ devices }: { devices: MediaDevice[] }) { + return ( +
+ {devices.map((d) => ( + + ))} +
+ ); +} + +interface VolumeControlProps { + value: number; + icon: React.ReactNode; + deviceId: string; + sessionId?: string; +} + +export function VolumeControl(props: VolumeControlProps) { + const { value, icon, deviceId, sessionId } = props; + + const [internalValue, setInternalValue] = useState(value); + + useEffect(() => { + setInternalValue(value); + }, [value]); + + const onExternalChange = useCallback( + debounce((value: number) => { + invoke('set_volume_level', { id: deviceId, level: value }).catch(console.error); + }, 100), + [deviceId, sessionId], + ); + + const onInternalChange = (value: number) => { + setInternalValue(value); + onExternalChange(value); + }; + + return ( +
+ + `${(100 * (value || 0)).toFixed(0)}`, + }} + /> + +
+ ); +} + +function MediaControls() { + const { t } = useTranslation(); + + const inputs = useSelector(Selectors.mediaInputs); + const defaultInput = inputs.find((d) => d.is_default_multimedia); + + const outputs = useSelector(Selectors.mediaOutputs); + const defaultOutput = outputs.find((d) => d.is_default_multimedia); + + const sessions = useSelector(Selectors.mediaSessions); + + return ( + + {t('media.master_volume')} + {!!defaultOutput && ( + + } + /> + )} + + {!!defaultInput && ( + } + /> + )} + + {outputs.length > 0 && ( + <> + {t('media.output_device')} + + + )} + + {inputs.length > 0 && ( + <> + {t('media.input_device')} + + + )} + + {sessions.length > 0 && ( + <> + {t('media.players')} +
+ {sessions.map((session, index) => ( + + ))} +
+ + )} +
+ ); +} + +export function WithMediaControls({ children }: PropsWithChildren) { + const [openPreview, setOpenPreview] = useState(false); + + useAppBlur(() => { + setOpenPreview(false); + }); + + return ( + } + > + {children} + + ); +} diff --git a/src/apps/toolbar/modules/media/infra/Module.tsx b/src/apps/toolbar/modules/media/infra/Module.tsx index dd5acfab..05ead9da 100644 --- a/src/apps/toolbar/modules/media/infra/Module.tsx +++ b/src/apps/toolbar/modules/media/infra/Module.tsx @@ -1,34 +1,34 @@ -import { MediaTM } from '../../../../shared/schemas/Placeholders'; -import { WithMediaControls } from './MediaControls'; -import { emit } from '@tauri-apps/api/event'; -import { useEffect } from 'react'; -import { useSelector } from 'react-redux'; - -import { Item } from '../../item/infra'; - -import { Selectors } from '../../shared/store/app'; - -interface Props { - module: MediaTM; -} - -function MediaModuleItem({ module, ...rest }: Props) { - const { volume = 0, muted: isMuted = false } = - useSelector((state: any) => Selectors.mediaOutputs(state).find((d) => d.is_default_multimedia)) || {}; - - return ; -} - -export function MediaModule({ module }: Props) { - useEffect(() => { - emit('register-media-events'); - }, []); - - return module.withMediaControls ? ( - - - - ) : ( - - ); -} +import { MediaTM } from '../../../../shared/schemas/Placeholders'; +import { WithMediaControls } from './MediaControls'; +import { emit } from '@tauri-apps/api/event'; +import { useEffect } from 'react'; +import { useSelector } from 'react-redux'; + +import { Item } from '../../item/infra'; + +import { Selectors } from '../../shared/store/app'; + +interface Props { + module: MediaTM; +} + +function MediaModuleItem({ module, ...rest }: Props) { + const { volume = 0, muted: isMuted = false } = + useSelector((state: any) => Selectors.mediaOutputs(state).find((d) => d.is_default_multimedia)) || {}; + + return ; +} + +export function MediaModule({ module }: Props) { + useEffect(() => { + emit('register-media-events'); + }, []); + + return module.withMediaControls ? ( + + + + ) : ( + + ); +} diff --git a/src/apps/toolbar/modules/media/infra/index.css b/src/apps/toolbar/modules/media/infra/index.css index 377daf80..192fad35 100644 --- a/src/apps/toolbar/modules/media/infra/index.css +++ b/src/apps/toolbar/modules/media/infra/index.css @@ -1,51 +1,51 @@ -.media-control { - .media-control-volume { - .ant-slider { - flex: 1; - } - } - - .media-control-sessions { - position: relative; - z-index: 1; - display: flex; - flex-direction: column; - gap: 6px; - } - - .media-session { - position: relative; - overflow: hidden; - } - - .media-session-actions { - .ant-btn { - color: inherit !important; - } - } - - .media-session-thumbnail { - z-index: 2; - } - - .media-session-blurred-thumbnail { - filter: blur(15px) brightness(125%) contrast(125%); - position: absolute; - width: 100%; - height: 100%; - object-fit: fill; - } - - .media-device-group { - display: flex; - flex-direction: column; - gap: 6px; - - .media-device { - display: grid; - align-items: center; - grid-template-columns: 50px 1fr; - gap: 6px; - } - } -} +.media-control { + .media-control-volume { + .ant-slider { + flex: 1; + } + } + + .media-control-sessions { + position: relative; + z-index: 1; + display: flex; + flex-direction: column; + gap: 6px; + } + + .media-session { + position: relative; + overflow: hidden; + } + + .media-session-actions { + .ant-btn { + color: inherit !important; + } + } + + .media-session-thumbnail { + z-index: 2; + } + + .media-session-blurred-thumbnail { + filter: blur(15px) brightness(125%) contrast(125%); + position: absolute; + width: 100%; + height: 100%; + object-fit: fill; + } + + .media-device-group { + display: flex; + flex-direction: column; + gap: 6px; + + .media-device { + display: grid; + align-items: center; + grid-template-columns: 50px 1fr; + gap: 6px; + } + } +} diff --git a/src/apps/toolbar/modules/network/domain.ts b/src/apps/toolbar/modules/network/domain.ts index 7a52c559..0fd58b32 100644 --- a/src/apps/toolbar/modules/network/domain.ts +++ b/src/apps/toolbar/modules/network/domain.ts @@ -1,16 +1,16 @@ -export interface WlanBssEntry { - ssid: string | null; - bssid: string; - channel_frequency: number; - signal: number; - connected: boolean; - connected_channel: boolean; -} - -export interface WlanProfile { - profileName: string; - ssid: string; - authentication: string; - encryption: string; - password: string; -} +export interface WlanBssEntry { + ssid: string | null; + bssid: string; + channel_frequency: number; + signal: number; + connected: boolean; + connected_channel: boolean; +} + +export interface WlanProfile { + profileName: string; + ssid: string; + authentication: string; + encryption: string; + password: string; +} diff --git a/src/apps/toolbar/modules/network/infra/Module.tsx b/src/apps/toolbar/modules/network/infra/Module.tsx index 26e0fa7a..3c9406c9 100644 --- a/src/apps/toolbar/modules/network/infra/Module.tsx +++ b/src/apps/toolbar/modules/network/infra/Module.tsx @@ -1,47 +1,47 @@ -import { NetworkTM } from '../../../../shared/schemas/Placeholders'; -import { WithWlanSelector } from './WlanSelector'; -import { emit } from '@tauri-apps/api/event'; -import { useEffect } from 'react'; -import { useSelector } from 'react-redux'; - -import { Item } from '../../item/infra'; - -import { Selectors } from '../../shared/store/app'; - -interface Props { - module: NetworkTM; -} - -function NetworkModuleItem({ module, ...rest }: Props) { - const networkAdapters = useSelector(Selectors.networkAdapters); - const defaultIp = useSelector(Selectors.networkLocalIp); - const online = useSelector(Selectors.online); - - const usingAdapter = networkAdapters.find((i) => i.ipv4 === defaultIp) || null; - - return ( - - ); -} - -export function NetworkModule({ module }: Props) { - useEffect(() => { - emit('register-network-events'); - }, []); - - return module.withWlanSelector ? ( - - - - ) : ( - - ); -} +import { NetworkTM } from '../../../../shared/schemas/Placeholders'; +import { WithWlanSelector } from './WlanSelector'; +import { emit } from '@tauri-apps/api/event'; +import { useEffect } from 'react'; +import { useSelector } from 'react-redux'; + +import { Item } from '../../item/infra'; + +import { Selectors } from '../../shared/store/app'; + +interface Props { + module: NetworkTM; +} + +function NetworkModuleItem({ module, ...rest }: Props) { + const networkAdapters = useSelector(Selectors.networkAdapters); + const defaultIp = useSelector(Selectors.networkLocalIp); + const online = useSelector(Selectors.online); + + const usingAdapter = networkAdapters.find((i) => i.ipv4 === defaultIp) || null; + + return ( + + ); +} + +export function NetworkModule({ module }: Props) { + useEffect(() => { + emit('register-network-events'); + }, []); + + return module.withWlanSelector ? ( + + + + ) : ( + + ); +} diff --git a/src/apps/toolbar/modules/network/infra/WlanSelector.tsx b/src/apps/toolbar/modules/network/infra/WlanSelector.tsx index 05c39f4b..908299cd 100644 --- a/src/apps/toolbar/modules/network/infra/WlanSelector.tsx +++ b/src/apps/toolbar/modules/network/infra/WlanSelector.tsx @@ -1,84 +1,84 @@ -import { WlanSelectorEntry } from './WlanSelectorEntry'; -import { invoke } from '@tauri-apps/api/core'; -import { Popover } from 'antd'; -import { PropsWithChildren, useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; - -import { BackgroundByLayersV2 } from '../../../../seelenweg/components/BackgroundByLayers/infra'; -import { useAppBlur } from '../../shared/hooks/infra'; - -import { Selectors } from '../../shared/store/app'; - -export function WithWlanSelector({ children }: PropsWithChildren) { - const [openPreview, setOpenPreview] = useState(false); - const [selected, setSelected] = useState(null); - - const entries = useSelector(Selectors.wlanBssEntries); - - const { t } = useTranslation(); - - useEffect(() => { - if (openPreview) { - invoke('wlan_start_scanning'); - } else { - setSelected(null); - invoke('wlan_stop_scanning'); - } - }, [openPreview]); - - useAppBlur(() => { - setOpenPreview(false); - }); - - let ssids = new Set(); - let filtered = entries - .toSorted((a, b) => b.signal - a.signal) - .filter((entry) => { - let ssid = entry.ssid || '__HIDDEN_SSID__'; - if (ssids.has(ssid)) { - return false; - } - ssids.add(ssid); - return true; - }); - - return ( - -
- -
- {filtered.length === 0 && ( -
{t('network.not_found')}
- )} - {filtered.map((entry) => { - let ssid = entry.ssid || '__HIDDEN_SSID__'; - return ( - setSelected(ssid)} - /> - ); - })} -
-
- invoke('open_file', { path: 'ms-settings:network' })}> - {t('network.more')} - -
-
- - } - > - {children} -
- ); -} +import { WlanSelectorEntry } from './WlanSelectorEntry'; +import { invoke } from '@tauri-apps/api/core'; +import { Popover } from 'antd'; +import { PropsWithChildren, useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; + +import { BackgroundByLayersV2 } from '../../../../seelenweg/components/BackgroundByLayers/infra'; +import { useAppBlur } from '../../shared/hooks/infra'; + +import { Selectors } from '../../shared/store/app'; + +export function WithWlanSelector({ children }: PropsWithChildren) { + const [openPreview, setOpenPreview] = useState(false); + const [selected, setSelected] = useState(null); + + const entries = useSelector(Selectors.wlanBssEntries); + + const { t } = useTranslation(); + + useEffect(() => { + if (openPreview) { + invoke('wlan_start_scanning'); + } else { + setSelected(null); + invoke('wlan_stop_scanning'); + } + }, [openPreview]); + + useAppBlur(() => { + setOpenPreview(false); + }); + + let ssids = new Set(); + let filtered = entries + .toSorted((a, b) => b.signal - a.signal) + .filter((entry) => { + let ssid = entry.ssid || '__HIDDEN_SSID__'; + if (ssids.has(ssid)) { + return false; + } + ssids.add(ssid); + return true; + }); + + return ( + +
+ +
+ {filtered.length === 0 && ( +
{t('network.not_found')}
+ )} + {filtered.map((entry) => { + let ssid = entry.ssid || '__HIDDEN_SSID__'; + return ( + setSelected(ssid)} + /> + ); + })} +
+
+ invoke('open_file', { path: 'ms-settings:network' })}> + {t('network.more')} + +
+
+ + } + > + {children} +
+ ); +} diff --git a/src/apps/toolbar/modules/network/infra/WlanSelectorEntry.tsx b/src/apps/toolbar/modules/network/infra/WlanSelectorEntry.tsx index 4b234985..32b0f21a 100644 --- a/src/apps/toolbar/modules/network/infra/WlanSelectorEntry.tsx +++ b/src/apps/toolbar/modules/network/infra/WlanSelectorEntry.tsx @@ -1,141 +1,141 @@ -import { Icon, IconName } from '../../../../shared/components/Icon'; -import { cx } from '../../../../shared/styles'; -import { invoke } from '@tauri-apps/api/core'; -import { Button, Input } from 'antd'; -import { useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; - -import { WlanBssEntry, WlanProfile } from '../domain'; - -export function WlanSelectorEntry(props: { - entry: WlanBssEntry; - selected: boolean; - onClick: () => void; -}) { - let { entry, selected, onClick } = props; - - let [loading, setLoading] = useState(false); - let [showFields, setShowFields] = useState(false); - let [showErrors, setShowErrors] = useState(false); - - let [ssid, setSsid] = useState(entry.ssid || ''); - let [password, setPassword] = useState(''); - - const { t } = useTranslation(); - - useEffect(() => { - if (!selected) { - setShowFields(false); - setShowErrors(false); - setSsid(entry.ssid || ''); - setPassword(''); - } - }, [selected]); - - function onConnection() { - setLoading(true); - - function onrejected(error: any) { - console.error(error); - setLoading(false); - setShowErrors(true); - } - - if (entry.connected) { - invoke('wlan_disconnect').then(() => setLoading(false), onrejected); - return; - } - - if (!entry.ssid && !showFields) { - setShowFields(true); - setLoading(false); - return; - } - - function onfulfilled(success: boolean) { - setLoading(false); - setShowFields(!success); - setShowErrors(!success); - } - - if (showFields) { - invoke('wlan_connect', { ssid, password, hidden: !entry.ssid }).then( - onfulfilled, - onrejected, - ); - return; - } - - invoke('wlan_get_profiles') - .then((profiles) => { - let profile = profiles.find((profile) => profile.ssid === entry.ssid); - if (!profile) { - setShowFields(true); - setLoading(false); - return; - } - - invoke('wlan_connect', { - ssid: profile.ssid, - password: profile.password, - hidden: !entry.ssid, - }).then(onfulfilled, onrejected); - }) - .catch(onrejected); - } - - let signalIcon: IconName = 'GrWifiNone'; - if (entry.signal > 75) { - signalIcon = 'GrWifi'; - } else if (entry.signal > 50) { - signalIcon = 'GrWifiMedium'; - } else if (entry.signal > 25) { - signalIcon = 'GrWifiLow'; - } - - return ( -
-
- - {entry.ssid || t('network.hidden')} -
- {showFields && ( -
- {!entry.ssid && ( - setSsid(e.target.value)} - autoFocus - onPressEnter={(e) => (e.currentTarget.nextSibling as HTMLInputElement)?.focus()} - /> - )} - setPassword(e.target.value)} - onPressEnter={onConnection} - autoFocus={!!entry.ssid} - /> - - )} - {selected && ( -
- -
- )} -
- ); -} +import { Icon, IconName } from '../../../../shared/components/Icon'; +import { cx } from '../../../../shared/styles'; +import { invoke } from '@tauri-apps/api/core'; +import { Button, Input } from 'antd'; +import { useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; + +import { WlanBssEntry, WlanProfile } from '../domain'; + +export function WlanSelectorEntry(props: { + entry: WlanBssEntry; + selected: boolean; + onClick: () => void; +}) { + let { entry, selected, onClick } = props; + + let [loading, setLoading] = useState(false); + let [showFields, setShowFields] = useState(false); + let [showErrors, setShowErrors] = useState(false); + + let [ssid, setSsid] = useState(entry.ssid || ''); + let [password, setPassword] = useState(''); + + const { t } = useTranslation(); + + useEffect(() => { + if (!selected) { + setShowFields(false); + setShowErrors(false); + setSsid(entry.ssid || ''); + setPassword(''); + } + }, [selected]); + + function onConnection() { + setLoading(true); + + function onrejected(error: any) { + console.error(error); + setLoading(false); + setShowErrors(true); + } + + if (entry.connected) { + invoke('wlan_disconnect').then(() => setLoading(false), onrejected); + return; + } + + if (!entry.ssid && !showFields) { + setShowFields(true); + setLoading(false); + return; + } + + function onfulfilled(success: boolean) { + setLoading(false); + setShowFields(!success); + setShowErrors(!success); + } + + if (showFields) { + invoke('wlan_connect', { ssid, password, hidden: !entry.ssid }).then( + onfulfilled, + onrejected, + ); + return; + } + + invoke('wlan_get_profiles') + .then((profiles) => { + let profile = profiles.find((profile) => profile.ssid === entry.ssid); + if (!profile) { + setShowFields(true); + setLoading(false); + return; + } + + invoke('wlan_connect', { + ssid: profile.ssid, + password: profile.password, + hidden: !entry.ssid, + }).then(onfulfilled, onrejected); + }) + .catch(onrejected); + } + + let signalIcon: IconName = 'GrWifiNone'; + if (entry.signal > 75) { + signalIcon = 'GrWifi'; + } else if (entry.signal > 50) { + signalIcon = 'GrWifiMedium'; + } else if (entry.signal > 25) { + signalIcon = 'GrWifiLow'; + } + + return ( +
+
+ + {entry.ssid || t('network.hidden')} +
+ {showFields && ( +
+ {!entry.ssid && ( + setSsid(e.target.value)} + autoFocus + onPressEnter={(e) => (e.currentTarget.nextSibling as HTMLInputElement)?.focus()} + /> + )} + setPassword(e.target.value)} + onPressEnter={onConnection} + autoFocus={!!entry.ssid} + /> + + )} + {selected && ( +
+ +
+ )} +
+ ); +} diff --git a/src/apps/toolbar/modules/shared/hooks/infra.ts b/src/apps/toolbar/modules/shared/hooks/infra.ts index f03765de..f41841b7 100644 --- a/src/apps/toolbar/modules/shared/hooks/infra.ts +++ b/src/apps/toolbar/modules/shared/hooks/infra.ts @@ -1,37 +1,37 @@ -import { ExtraCallbacksOnActivate, ExtraCallbacksOnLeave } from '../../../events'; -import { useEffect, useRef } from 'react'; - -export function useAppBlur(cb: () => void, deps: any[] = []) { - const key = useRef(crypto.randomUUID()); - useEffect(() => { - ExtraCallbacksOnLeave.remove(key.current); - ExtraCallbacksOnLeave.add(cb, key.current); - return () => { - ExtraCallbacksOnLeave.remove(key.current); - }; - }, deps); -} - -export function useAppActivation(cb: () => void, deps: any[] = []) { - const key = useRef(crypto.randomUUID()); - useEffect(() => { - ExtraCallbacksOnActivate.remove(key.current); - ExtraCallbacksOnActivate.add(cb, key.current); - return () => { - ExtraCallbacksOnActivate.remove(key.current); - }; - }, deps); -} - -export function useInterval(callback: () => void, delay: number, deps: any[] = []) { - const key = useRef(); - - // Set up the interval. - useEffect(() => { - if (key.current) { - clearInterval(key.current); - } - key.current = window.setInterval(callback, delay); - return () => clearInterval(key.current); - }, [callback, delay, ...deps]); +import { ExtraCallbacksOnActivate, ExtraCallbacksOnLeave } from '../../../events'; +import { useEffect, useRef } from 'react'; + +export function useAppBlur(cb: () => void, deps: any[] = []) { + const key = useRef(crypto.randomUUID()); + useEffect(() => { + ExtraCallbacksOnLeave.remove(key.current); + ExtraCallbacksOnLeave.add(cb, key.current); + return () => { + ExtraCallbacksOnLeave.remove(key.current); + }; + }, deps); +} + +export function useAppActivation(cb: () => void, deps: any[] = []) { + const key = useRef(crypto.randomUUID()); + useEffect(() => { + ExtraCallbacksOnActivate.remove(key.current); + ExtraCallbacksOnActivate.add(cb, key.current); + return () => { + ExtraCallbacksOnActivate.remove(key.current); + }; + }, deps); +} + +export function useInterval(callback: () => void, delay: number, deps: any[] = []) { + const key = useRef(); + + // Set up the interval. + useEffect(() => { + if (key.current) { + clearInterval(key.current); + } + key.current = window.setInterval(callback, delay); + return () => clearInterval(key.current); + }, [callback, delay, ...deps]); } \ No newline at end of file diff --git a/src/apps/toolbar/modules/shared/store/app.ts b/src/apps/toolbar/modules/shared/store/app.ts index 4bd39298..2acd37a9 100644 --- a/src/apps/toolbar/modules/shared/store/app.ts +++ b/src/apps/toolbar/modules/shared/store/app.ts @@ -1,78 +1,78 @@ -import { parseAsCamel } from '../../../../shared/schemas'; -import { FancyToolbarSchema } from '../../../../shared/schemas/FancyToolbar'; -import { Placeholder, ToolbarModule } from '../../../../shared/schemas/Placeholders'; -import { StateBuilder } from '../../../../shared/StateBuilder'; -import { createSlice, PayloadAction } from '@reduxjs/toolkit'; - -import { RootState } from './domain'; - -const initialState: RootState = { - version: 0, - focused: null, - placeholder: null, - settings: parseAsCamel(FancyToolbarSchema, {}), - env: {}, - // default values of https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-system_power_status - powerStatus: { - ACLineStatus: 255, - BatteryFlag: 255, - BatteryLifePercent: 255, - SystemStatusFlag: 0, - BatteryLifeTime: -1, - BatteryFullLifeTime: -1, - }, - batteries: [], - workspaces: [], - activeWorkspace: 0, - systemTray: [], - networkAdapters: [], - networkLocalIp: null, - online: false, - wlanBssEntries: [], - mediaSessions: [], - mediaOutputs: [], - mediaInputs: [], - notifications: [], - colors: { - background: '#ffffff', - foreground: '#000000', - accent_darkest: '#000000', - accent_darker: '#000000', - accent_dark: '#000000', - accent: '#000000', - accent_light: '#000000', - accent_lighter: '#000000', - accent_lightest: '#000000', - complement: null, - }, -}; - -export const RootSlice = createSlice({ - name: 'root', - initialState, - reducers: { - ...StateBuilder.reducersFor(initialState), - setPlaceholder(state, action: PayloadAction) { - state.placeholder = action.payload; - state.version++; - }, - setItemsOnLeft(state, action: PayloadAction) { - if (state.placeholder) { - state.placeholder.left = action.payload; - } - }, - setItemsOnCenter(state, action: PayloadAction) { - if (state.placeholder) { - state.placeholder.center = action.payload; - } - }, - setItemsOnRight(state, action: PayloadAction) { - if (state.placeholder) { - state.placeholder.right = action.payload; - } - }, - }, -}); - -export const RootActions = RootSlice.actions; +import { parseAsCamel } from '../../../../shared/schemas'; +import { FancyToolbarSchema } from '../../../../shared/schemas/FancyToolbar'; +import { Placeholder, ToolbarModule } from '../../../../shared/schemas/Placeholders'; +import { StateBuilder } from '../../../../shared/StateBuilder'; +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; + +import { RootState } from './domain'; + +const initialState: RootState = { + version: 0, + focused: null, + placeholder: null, + settings: parseAsCamel(FancyToolbarSchema, {}), + env: {}, + // default values of https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-system_power_status + powerStatus: { + ACLineStatus: 255, + BatteryFlag: 255, + BatteryLifePercent: 255, + SystemStatusFlag: 0, + BatteryLifeTime: -1, + BatteryFullLifeTime: -1, + }, + batteries: [], + workspaces: [], + activeWorkspace: 0, + systemTray: [], + networkAdapters: [], + networkLocalIp: null, + online: false, + wlanBssEntries: [], + mediaSessions: [], + mediaOutputs: [], + mediaInputs: [], + notifications: [], + colors: { + background: '#ffffff', + foreground: '#000000', + accent_darkest: '#000000', + accent_darker: '#000000', + accent_dark: '#000000', + accent: '#000000', + accent_light: '#000000', + accent_lighter: '#000000', + accent_lightest: '#000000', + complement: null, + }, +}; + +export const RootSlice = createSlice({ + name: 'root', + initialState, + reducers: { + ...StateBuilder.reducersFor(initialState), + setPlaceholder(state, action: PayloadAction) { + state.placeholder = action.payload; + state.version++; + }, + setItemsOnLeft(state, action: PayloadAction) { + if (state.placeholder) { + state.placeholder.left = action.payload; + } + }, + setItemsOnCenter(state, action: PayloadAction) { + if (state.placeholder) { + state.placeholder.center = action.payload; + } + }, + setItemsOnRight(state, action: PayloadAction) { + if (state.placeholder) { + state.placeholder.right = action.payload; + } + }, + }, +}); + +export const RootActions = RootSlice.actions; export const Selectors = StateBuilder.compositeSelector(initialState); \ No newline at end of file diff --git a/src/apps/toolbar/modules/shared/store/domain.ts b/src/apps/toolbar/modules/shared/store/domain.ts index 49a05598..42a1a0e8 100644 --- a/src/apps/toolbar/modules/shared/store/domain.ts +++ b/src/apps/toolbar/modules/shared/store/domain.ts @@ -1,107 +1,107 @@ -import { IRootState } from '../../../../../shared.interfaces'; -import { FancyToolbar } from '../../../../shared/schemas/FancyToolbar'; -import { Placeholder } from '../../../../shared/schemas/Placeholders'; - -import { WlanBssEntry } from '../../network/domain'; - -export interface ActiveApp { - name: string; - title: string; - exe: string | null; -} - -export interface PowerStatus { - ACLineStatus: number; - BatteryFlag: number; - BatteryLifePercent: number; - SystemStatusFlag: number; - BatteryLifeTime: number; - BatteryFullLifeTime: number; -} - -export interface Battery { - percent: number; -} - -export interface TrayInfo { - label: string; - icon: string | null; -} - -export interface NetworkAdapter { - ipv4: string | null; - ipv6: string | null; -} - -export interface MediaChannelTransportData { - id: string; - title: string; - author: string; - thumbnail: string | null; - playing: boolean; - default: boolean; -} - -export interface MediaDeviceChannel { - id: string; - instance_id: string; - process_id: number; - name: string; - icon_path: string | null; - is_system: boolean; - volume: number; - muted: boolean; -} - -export interface MediaDevice { - id: string; - name: string; - is_default_multimedia: boolean; - is_default_communications: boolean; - sessions: MediaDeviceChannel[]; - volume: number; - muted: boolean; -} - -export interface AppNotification { - id: number; - app_name: string; - app_description: string; - app_logo: string | null; - body: string[]; - date: number; -} - -export interface UIColors { - background: string; - foreground: string; - accent_darkest: string; - accent_darker: string; - accent_dark: string; - accent: string; - accent_light: string; - accent_lighter: string; - accent_lightest: string; - complement: string | null; -} - -export interface RootState extends IRootState { - version: number; - focused: ActiveApp | null; - placeholder: Placeholder | null; - env: Record; - powerStatus: PowerStatus; - batteries: Battery[]; - workspaces: string[]; - activeWorkspace: number; - systemTray: TrayInfo[]; - networkAdapters: NetworkAdapter[]; - networkLocalIp: string | null; - online: boolean; - wlanBssEntries: WlanBssEntry[]; - mediaSessions: MediaChannelTransportData[]; - mediaOutputs: MediaDevice[]; - mediaInputs: MediaDevice[]; - notifications: AppNotification[]; - colors: UIColors; -} +import { IRootState } from '../../../../../shared.interfaces'; +import { FancyToolbar } from '../../../../shared/schemas/FancyToolbar'; +import { Placeholder } from '../../../../shared/schemas/Placeholders'; + +import { WlanBssEntry } from '../../network/domain'; + +export interface ActiveApp { + name: string; + title: string; + exe: string | null; +} + +export interface PowerStatus { + ACLineStatus: number; + BatteryFlag: number; + BatteryLifePercent: number; + SystemStatusFlag: number; + BatteryLifeTime: number; + BatteryFullLifeTime: number; +} + +export interface Battery { + percent: number; +} + +export interface TrayInfo { + label: string; + icon: string | null; +} + +export interface NetworkAdapter { + ipv4: string | null; + ipv6: string | null; +} + +export interface MediaChannelTransportData { + id: string; + title: string; + author: string; + thumbnail: string | null; + playing: boolean; + default: boolean; +} + +export interface MediaDeviceChannel { + id: string; + instance_id: string; + process_id: number; + name: string; + icon_path: string | null; + is_system: boolean; + volume: number; + muted: boolean; +} + +export interface MediaDevice { + id: string; + name: string; + is_default_multimedia: boolean; + is_default_communications: boolean; + sessions: MediaDeviceChannel[]; + volume: number; + muted: boolean; +} + +export interface AppNotification { + id: number; + app_name: string; + app_description: string; + app_logo: string | null; + body: string[]; + date: number; +} + +export interface UIColors { + background: string; + foreground: string; + accent_darkest: string; + accent_darker: string; + accent_dark: string; + accent: string; + accent_light: string; + accent_lighter: string; + accent_lightest: string; + complement: string | null; +} + +export interface RootState extends IRootState { + version: number; + focused: ActiveApp | null; + placeholder: Placeholder | null; + env: Record; + powerStatus: PowerStatus; + batteries: Battery[]; + workspaces: string[]; + activeWorkspace: number; + systemTray: TrayInfo[]; + networkAdapters: NetworkAdapter[]; + networkLocalIp: string | null; + online: boolean; + wlanBssEntries: WlanBssEntry[]; + mediaSessions: MediaChannelTransportData[]; + mediaOutputs: MediaDevice[]; + mediaInputs: MediaDevice[]; + notifications: AppNotification[]; + colors: UIColors; +} diff --git a/src/apps/toolbar/modules/shared/store/infra.ts b/src/apps/toolbar/modules/shared/store/infra.ts index 56aa9033..ee58e0b3 100644 --- a/src/apps/toolbar/modules/shared/store/infra.ts +++ b/src/apps/toolbar/modules/shared/store/infra.ts @@ -1,154 +1,154 @@ -import { UserSettings } from '../../../../../shared.interfaces'; -import { UserSettingsLoader } from '../../../../settings/modules/shared/store/storeApi'; -import { loadThemeCSS, setColorsAsCssVariables } from '../../../../shared'; -import { FileChange } from '../../../../shared/events'; -import { FancyToolbar } from '../../../../shared/schemas/FancyToolbar'; -import i18n from '../../../i18n'; -import { configureStore } from '@reduxjs/toolkit'; -import { listen as listenGlobal } from '@tauri-apps/api/event'; -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; -import { debounce } from 'lodash'; - -import { IsSavingCustom } from '../../main/application'; -import { RootActions, RootSlice } from './app'; - -import { WlanBssEntry } from '../../network/domain'; -import { - ActiveApp, - AppNotification, - Battery, - MediaChannelTransportData, - MediaDevice, - NetworkAdapter, - PowerStatus, - TrayInfo, - UIColors, -} from './domain'; - -export const store = configureStore({ - reducer: RootSlice.reducer, -}); - -export async function registerStoreEvents() { - const view = getCurrentWebviewWindow(); - - await view.listen('focus-changed', (e) => { - store.dispatch(RootActions.setFocused(e.payload)); - }); - - await listenGlobal( - FileChange.Settings, - debounce(async (_event) => { - await loadStore(); - }, 100), - ); - - await listenGlobal('power-status', (event) => { - store.dispatch(RootActions.setPowerStatus(event.payload)); - }); - - await listenGlobal('batteries-status', (event) => { - store.dispatch(RootActions.setBatteries(event.payload)); - }); - - await listenGlobal('workspaces-changed', (event) => { - store.dispatch(RootActions.setWorkspaces(event.payload)); - }); - - await listenGlobal('active-workspace-changed', (event) => { - store.dispatch(RootActions.setActiveWorkspace(event.payload)); - }); - - await listenGlobal('tray-info', (event) => { - store.dispatch(RootActions.setSystemTray(event.payload)); - }); - - await listenGlobal('media-sessions', (event) => { - store.dispatch(RootActions.setMediaSessions(event.payload)); - }); - - await listenGlobal('media-outputs', (event) => { - store.dispatch(RootActions.setMediaOutputs(event.payload)); - }); - - await listenGlobal('media-inputs', (event) => { - store.dispatch(RootActions.setMediaInputs(event.payload)); - }); - - await listenGlobal('notifications', (event) => { - store.dispatch(RootActions.setNotifications(event.payload.sort((a, b) => b.date - a.date))); - }); - - await listenGlobal('network-adapters', (event) => { - store.dispatch(RootActions.setNetworkAdapters(event.payload)); - }); - - await listenGlobal('network-default-local-ip', (event) => { - store.dispatch(RootActions.setNetworkLocalIp(event.payload)); - }); - - await listenGlobal('network-internet-connection', (event) => { - store.dispatch(RootActions.setOnline(event.payload)); - }); - - await listenGlobal('wlan-scanned', (event) => { - store.dispatch(RootActions.setWlanBssEntries(event.payload)); - }); - - await listenGlobal('colors', (event) => { - setColorsAsCssVariables(event.payload); - store.dispatch(RootActions.setColors(event.payload)); - }); - - await listenGlobal( - FileChange.Themes, - debounce(async () => { - const userSettings = await new UserSettingsLoader().load(); - loadThemeCSS(userSettings); - }, 100), - ); - - await listenGlobal( - FileChange.Placeholders, - debounce(async () => { - if (IsSavingCustom.current) { - IsSavingCustom.current = false; - return; - } - const userSettings = await new UserSettingsLoader().withPlaceholders().load(); - setPlaceholder(userSettings); - }, 100), - ); - - await view.emitTo(view.label, 'store-events-ready'); -} - -function setPlaceholder(userSettings: UserSettings) { - const settings = userSettings.jsonSettings.fancyToolbar; - const placeholder = - userSettings.placeholders.find( - (placeholder) => placeholder.info.filename === settings.placeholder, - ) || null; - - store.dispatch(RootActions.setPlaceholder(placeholder)); -} - -export async function loadStore() { - const userSettings = await new UserSettingsLoader().withPlaceholders().load(); - const settings = userSettings.jsonSettings.fancyToolbar; - i18n.changeLanguage(userSettings.jsonSettings.language); - - loadSettingsCSS(settings); - store.dispatch(RootActions.setSettings(settings)); - - loadThemeCSS(userSettings); - setPlaceholder(userSettings); - - store.dispatch(RootActions.setEnv(userSettings.env)); -} - -export function loadSettingsCSS(settings: FancyToolbar) { - const styles = document.documentElement.style; - - styles.setProperty('--config-height', `${settings.height}px`); -} +import { UserSettings } from '../../../../../shared.interfaces'; +import { UserSettingsLoader } from '../../../../settings/modules/shared/store/storeApi'; +import { loadThemeCSS, setColorsAsCssVariables } from '../../../../shared'; +import { FileChange } from '../../../../shared/events'; +import { FancyToolbar } from '../../../../shared/schemas/FancyToolbar'; +import i18n from '../../../i18n'; +import { configureStore } from '@reduxjs/toolkit'; +import { listen as listenGlobal } from '@tauri-apps/api/event'; +import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; +import { debounce } from 'lodash'; + +import { IsSavingCustom } from '../../main/application'; +import { RootActions, RootSlice } from './app'; + +import { WlanBssEntry } from '../../network/domain'; +import { + ActiveApp, + AppNotification, + Battery, + MediaChannelTransportData, + MediaDevice, + NetworkAdapter, + PowerStatus, + TrayInfo, + UIColors, +} from './domain'; + +export const store = configureStore({ + reducer: RootSlice.reducer, +}); + +export async function registerStoreEvents() { + const view = getCurrentWebviewWindow(); + + await view.listen('focus-changed', (e) => { + store.dispatch(RootActions.setFocused(e.payload)); + }); + + await listenGlobal( + FileChange.Settings, + debounce(async (_event) => { + await loadStore(); + }, 100), + ); + + await listenGlobal('power-status', (event) => { + store.dispatch(RootActions.setPowerStatus(event.payload)); + }); + + await listenGlobal('batteries-status', (event) => { + store.dispatch(RootActions.setBatteries(event.payload)); + }); + + await listenGlobal('workspaces-changed', (event) => { + store.dispatch(RootActions.setWorkspaces(event.payload)); + }); + + await listenGlobal('active-workspace-changed', (event) => { + store.dispatch(RootActions.setActiveWorkspace(event.payload)); + }); + + await listenGlobal('tray-info', (event) => { + store.dispatch(RootActions.setSystemTray(event.payload)); + }); + + await listenGlobal('media-sessions', (event) => { + store.dispatch(RootActions.setMediaSessions(event.payload)); + }); + + await listenGlobal('media-outputs', (event) => { + store.dispatch(RootActions.setMediaOutputs(event.payload)); + }); + + await listenGlobal('media-inputs', (event) => { + store.dispatch(RootActions.setMediaInputs(event.payload)); + }); + + await listenGlobal('notifications', (event) => { + store.dispatch(RootActions.setNotifications(event.payload.sort((a, b) => b.date - a.date))); + }); + + await listenGlobal('network-adapters', (event) => { + store.dispatch(RootActions.setNetworkAdapters(event.payload)); + }); + + await listenGlobal('network-default-local-ip', (event) => { + store.dispatch(RootActions.setNetworkLocalIp(event.payload)); + }); + + await listenGlobal('network-internet-connection', (event) => { + store.dispatch(RootActions.setOnline(event.payload)); + }); + + await listenGlobal('wlan-scanned', (event) => { + store.dispatch(RootActions.setWlanBssEntries(event.payload)); + }); + + await listenGlobal('colors', (event) => { + setColorsAsCssVariables(event.payload); + store.dispatch(RootActions.setColors(event.payload)); + }); + + await listenGlobal( + FileChange.Themes, + debounce(async () => { + const userSettings = await new UserSettingsLoader().load(); + loadThemeCSS(userSettings); + }, 100), + ); + + await listenGlobal( + FileChange.Placeholders, + debounce(async () => { + if (IsSavingCustom.current) { + IsSavingCustom.current = false; + return; + } + const userSettings = await new UserSettingsLoader().withPlaceholders().load(); + setPlaceholder(userSettings); + }, 100), + ); + + await view.emitTo(view.label, 'store-events-ready'); +} + +function setPlaceholder(userSettings: UserSettings) { + const settings = userSettings.jsonSettings.fancyToolbar; + const placeholder = + userSettings.placeholders.find( + (placeholder) => placeholder.info.filename === settings.placeholder, + ) || null; + + store.dispatch(RootActions.setPlaceholder(placeholder)); +} + +export async function loadStore() { + const userSettings = await new UserSettingsLoader().withPlaceholders().load(); + const settings = userSettings.jsonSettings.fancyToolbar; + i18n.changeLanguage(userSettings.jsonSettings.language); + + loadSettingsCSS(settings); + store.dispatch(RootActions.setSettings(settings)); + + loadThemeCSS(userSettings); + setPlaceholder(userSettings); + + store.dispatch(RootActions.setEnv(userSettings.env)); +} + +export function loadSettingsCSS(settings: FancyToolbar) { + const styles = document.documentElement.style; + + styles.setProperty('--config-height', `${settings.height}px`); +} diff --git a/src/apps/toolbar/modules/shared/utils/app.ts b/src/apps/toolbar/modules/shared/utils/app.ts index 66ed0791..4eea8474 100644 --- a/src/apps/toolbar/modules/shared/utils/app.ts +++ b/src/apps/toolbar/modules/shared/utils/app.ts @@ -1,15 +1,15 @@ -export class CallbacksManager { - callbacks: Record void> = {}; - - add(cb: () => void, key: string) { - this.callbacks[key] = cb; - } - - remove(key: string) { - delete this.callbacks[key]; - } - - execute() { - Object.values(this.callbacks).forEach((cb) => cb()); - } +export class CallbacksManager { + callbacks: Record void> = {}; + + add(cb: () => void, key: string) { + this.callbacks[key] = cb; + } + + remove(key: string) { + delete this.callbacks[key]; + } + + execute() { + Object.values(this.callbacks).forEach((cb) => cb()); + } } \ No newline at end of file diff --git a/src/apps/toolbar/modules/shared/utils/domain.ts b/src/apps/toolbar/modules/shared/utils/domain.ts index a13cdc56..9a9cb2db 100644 --- a/src/apps/toolbar/modules/shared/utils/domain.ts +++ b/src/apps/toolbar/modules/shared/utils/domain.ts @@ -1,2 +1,2 @@ -export const HITBOX_TARGET = 'fancy-toolbar-hitbox'; +export const HITBOX_TARGET = 'fancy-toolbar-hitbox'; export const SELF_TARGET = 'fancy-toolbar'; \ No newline at end of file diff --git a/src/apps/toolbar/modules/shared/utils/infra.ts b/src/apps/toolbar/modules/shared/utils/infra.ts index ec381651..43967ab9 100644 --- a/src/apps/toolbar/modules/shared/utils/infra.ts +++ b/src/apps/toolbar/modules/shared/utils/infra.ts @@ -1,24 +1,24 @@ -import { path } from '@tauri-apps/api'; - -export const LAZY_CONSTANTS = { - MISSING_ICON_PATH: '', - DEFAULT_THUMBNAIL: '', -}; - -export async function loadConstants() { - let resourceDir = await path.resourceDir(); - - LAZY_CONSTANTS.MISSING_ICON_PATH = await path.resolve( - resourceDir, - 'static', - 'icons', - 'missing.png', - ); - - LAZY_CONSTANTS.DEFAULT_THUMBNAIL = await path.resolve( - resourceDir, - 'static', - 'icons', - 'default_thumbnail.jpg', - ); -} +import { path } from '@tauri-apps/api'; + +export const LAZY_CONSTANTS = { + MISSING_ICON_PATH: '', + DEFAULT_THUMBNAIL: '', +}; + +export async function loadConstants() { + let resourceDir = await path.resourceDir(); + + LAZY_CONSTANTS.MISSING_ICON_PATH = await path.resolve( + resourceDir, + 'static', + 'icons', + 'missing.png', + ); + + LAZY_CONSTANTS.DEFAULT_THUMBNAIL = await path.resolve( + resourceDir, + 'static', + 'icons', + 'default_thumbnail.jpg', + ); +} diff --git a/src/apps/toolbar/styles/colors.css b/src/apps/toolbar/styles/colors.css index ec8ed844..f12ab260 100644 --- a/src/apps/toolbar/styles/colors.css +++ b/src/apps/toolbar/styles/colors.css @@ -1,599 +1,599 @@ -:root { - /* Persisted colors variables (not changed on dark mode) */ - --color-persist-white: #ffffff; - --color-persist-gray-50: #fdfdfd; - --color-persist-gray-100: #f8f8f8; - --color-persist-gray-200: #e6e6e6; - --color-persist-gray-300: #d5d5d5; - --color-persist-gray-400: #b1b1b1; - --color-persist-gray-500: #909090; - --color-persist-gray-600: #6d6d6d; - --color-persist-gray-700: #464646; - --color-persist-gray-800: #222222; - --color-persist-gray-900: #151515; - --color-persist-black: #000000; - - --color-persist-blue-100: #e0f2ff; - --color-persist-blue-200: #cae8ff; - --color-persist-blue-300: #b5deff; - --color-persist-blue-400: #96cefd; - --color-persist-blue-500: #78bbfa; - --color-persist-blue-600: #59a7f6; - --color-persist-blue-700: #3892f3; - --color-persist-blue-800: #147af3; - --color-persist-blue-900: #0265dc; - --color-persist-blue-1000: #0054b6; - --color-persist-blue-1100: #004491; - --color-persist-blue-1200: #003571; - --color-persist-blue-1300: #002754; - - --color-persist-green-100: #cef8e0; - --color-persist-green-200: #adf4ce; - --color-persist-green-300: #89ecbc; - --color-persist-green-400: #67dea8; - --color-persist-green-500: #49cc93; - --color-persist-green-600: #2fb880; - --color-persist-green-700: #15a46e; - --color-persist-green-800: #008f5d; - --color-persist-green-900: #007a4d; - --color-persist-green-1000: #00653e; - --color-persist-green-1100: #005132; - --color-persist-green-1200: #053f27; - --color-persist-green-1300: #0a2e1d; - - --color-persist-orange-100: #ffeccc; - --color-persist-orange-200: #ffdfad; - --color-persist-orange-300: #fdd291; - --color-persist-orange-400: #ffbb63; - --color-persist-orange-500: #ffa037; - --color-persist-orange-600: #f68511; - --color-persist-orange-700: #e46f00; - --color-persist-orange-800: #cb5d00; - --color-persist-orange-900: #b14c00; - --color-persist-orange-1000: #953d00; - --color-persist-orange-1100: #7a2f00; - --color-persist-orange-1200: #612300; - --color-persist-orange-1300: #491901; - - --color-persist-red-100: #ffebe7; - --color-persist-red-200: #ffddd6; - --color-persist-red-300: #ffcdc3; - --color-persist-red-400: #ffb7a9; - --color-persist-red-500: #ff9b88; - --color-persist-red-600: #ff7c65; - --color-persist-red-700: #f75c46; - --color-persist-red-800: #ea3829; - --color-persist-red-900: #d31510; - --color-persist-red-1000: #b40000; - --color-persist-red-1100: #930000; - --color-persist-red-1200: #740000; - --color-persist-red-1300: #590000; - - --color-persist-celery-100: #cdfcbf; - --color-persist-celery-200: #aef69d; - --color-persist-celery-300: #96ee85; - --color-persist-celery-400: #72e06a; - --color-persist-celery-500: #4ecf50; - --color-persist-celery-600: #27bb36; - --color-persist-celery-700: #07a721; - --color-persist-celery-800: #009112; - --color-persist-celery-900: #007c0f; - --color-persist-celery-1000: #00670f; - --color-persist-celery-1100: #00530d; - --color-persist-celery-1200: #00400a; - --color-persist-celery-1300: #003007; - - --color-persist-chartreuse-100: #dbfc6e; - --color-persist-chartreuse-200: #cbf443; - --color-persist-chartreuse-300: #bce92a; - --color-persist-chartreuse-400: #aad816; - --color-persist-chartreuse-500: #98c50a; - --color-persist-chartreuse-600: #87b103; - --color-persist-chartreuse-700: #769c00; - --color-persist-chartreuse-800: #678800; - --color-persist-chartreuse-900: #577400; - --color-persist-chartreuse-1000: #486000; - --color-persist-chartreuse-1100: #3a4d00; - --color-persist-chartreuse-1200: #2c3b00; - --color-persist-chartreuse-1300: #212c00; - - --color-persist-cyan-100: #c5f8ff; - --color-persist-cyan-200: #a4f0ff; - --color-persist-cyan-300: #88e7fa; - --color-persist-cyan-400: #60d8f3; - --color-persist-cyan-500: #33c5e8; - --color-persist-cyan-600: #12b0da; - --color-persist-cyan-700: #019cc8; - --color-persist-cyan-800: #0086b4; - --color-persist-cyan-900: #00719f; - --color-persist-cyan-1000: #005d89; - --color-persist-cyan-1100: #004a73; - --color-persist-cyan-1200: #00395d; - --color-persist-cyan-1300: #002a46; - - --color-persist-fuchsia-100: #ffe9fc; - --color-persist-fuchsia-200: #ffdafa; - --color-persist-fuchsia-300: #fec7f8; - --color-persist-fuchsia-400: #fbaef6; - --color-persist-fuchsia-500: #f592f3; - --color-persist-fuchsia-600: #ed74ed; - --color-persist-fuchsia-700: #e055e2; - --color-persist-fuchsia-800: #cd3ace; - --color-persist-fuchsia-900: #b622b7; - --color-persist-fuchsia-1000: #9d039e; - --color-persist-fuchsia-1100: #800081; - --color-persist-fuchsia-1200: #640664; - --color-persist-fuchsia-1300: #470e46; - - --color-persist-indigo-100: #edeeff; - --color-persist-indigo-200: #e0e2ff; - --color-persist-indigo-300: #d3d5ff; - --color-persist-indigo-400: #c1c4ff; - --color-persist-indigo-500: #acafff; - --color-persist-indigo-600: #9599ff; - --color-persist-indigo-700: #7e84fc; - --color-persist-indigo-800: #686df4; - --color-persist-indigo-900: #5258e4; - --color-persist-indigo-1000: #4046ca; - --color-persist-indigo-1100: #3236a8; - --color-persist-indigo-1200: #262986; - --color-persist-indigo-1300: #1b1e64; - - --color-persist-magenta-100: #ffeaf1; - --color-persist-magenta-200: #ffdce8; - --color-persist-magenta-300: #ffcadd; - --color-persist-magenta-400: #ffb2ce; - --color-persist-magenta-500: #ff95bd; - --color-persist-magenta-600: #fa77aa; - --color-persist-magenta-700: #ef5a98; - --color-persist-magenta-800: #de3d82; - --color-persist-magenta-900: #c82269; - --color-persist-magenta-1000: #ad0955; - --color-persist-magenta-1100: #8e0045; - --color-persist-magenta-1200: #700037; - --color-persist-magenta-1300: #54032a; - - --color-persist-purple-100: #f6ebff; - --color-persist-purple-200: #eeddff; - --color-persist-purple-300: #e6d0ff; - --color-persist-purple-400: #dbbbfe; - --color-persist-purple-500: #cca4fd; - --color-persist-purple-600: #bd8bfc; - --color-persist-purple-700: #ae72f9; - --color-persist-purple-800: #9d57f4; - --color-persist-purple-900: #893de7; - --color-persist-purple-1000: #7326d3; - --color-persist-purple-1100: #5d13b7; - --color-persist-purple-1200: #470c94; - --color-persist-purple-1300: #33106a; - - --color-persist-seafoam-100: #cef7f3; - --color-persist-seafoam-200: #aaf1ea; - --color-persist-seafoam-300: #8ce9e2; - --color-persist-seafoam-400: #65dad2; - --color-persist-seafoam-500: #3fc9c1; - --color-persist-seafoam-600: #0fb5ae; - --color-persist-seafoam-700: #00a19a; - --color-persist-seafoam-800: #008c87; - --color-persist-seafoam-900: #007772; - --color-persist-seafoam-1000: #00635f; - --color-persist-seafoam-1100: #0c4f4c; - --color-persist-seafoam-1200: #123c3a; - --color-persist-seafoam-1300: #122c2b; - - --color-persist-yellow-100: #fbf198; - --color-persist-yellow-200: #f8e750; - --color-persist-yellow-300: #f8d904; - --color-persist-yellow-400: #e8c600; - --color-persist-yellow-500: #d7b300; - --color-persist-yellow-600: #c49f00; - --color-persist-yellow-700: #b08c00; - --color-persist-yellow-800: #9b7800; - --color-persist-yellow-900: #856600; - --color-persist-yellow-1000: #705300; - --color-persist-yellow-1100: #5b4300; - --color-persist-yellow-1200: #483300; - --color-persist-yellow-1300: #362500; -} - -@media (prefers-color-scheme: dark) { - :root { - --color-white: #000000; - - --color-gray-50: #151515; - --color-gray-100: #222222; - --color-gray-200: #464646; - --color-gray-300: #6d6d6d; - --color-gray-400: #909090; - --color-gray-500: #b1b1b1; - --color-gray-600: #d5d5d5; - --color-gray-700: #e6e6e6; - --color-gray-800: #f8f8f8; - --color-gray-900: #fdfdfd; - - --color-black: #ffffff; - - --color-blue-100: #003877; - --color-blue-200: #00418a; - --color-blue-300: #004da3; - --color-blue-400: #0059c2; - --color-blue-500: #0367e0; - --color-blue-600: #1379f3; - --color-blue-700: #348ff4; - --color-blue-800: #54a3f6; - --color-blue-900: #72b7f9; - --color-blue-1000: #8fcafc; - --color-blue-1100: #aedbfe; - --color-blue-1200: #cce9ff; - --color-blue-1300: #e8f6ff; - - --color-green-100: #044329; - --color-green-200: #004e2f; - --color-green-300: #005c38; - --color-green-400: #006c43; - --color-green-500: #007d4e; - --color-green-600: #008f5d; - --color-green-700: #12a26c; - --color-green-800: #2bb47d; - --color-green-900: #43c78f; - --color-green-1000: #5ed9a2; - --color-green-1100: #81e9b8; - --color-green-1200: #b1f4d1; - --color-green-1300: #dffaea; - - --color-orange-100: #662500; - --color-orange-200: #752d00; - --color-orange-300: #893700; - --color-orange-400: #9e4200; - --color-orange-500: #b44e00; - --color-orange-600: #ca5d00; - --color-orange-700: #e16d00; - --color-orange-800: #f4810c; - --color-orange-900: #fe9a2e; - --color-orange-1000: #ffb558; - --color-orange-1100: #fdce88; - --color-orange-1200: #ffe1b3; - --color-orange-1300: #fff2dd; - - --color-red-100: #7b0000; - --color-red-200: #8d0000; - --color-red-300: #a50000; - --color-red-400: #be0403; - --color-red-500: #d71913; - --color-red-600: #ea3829; - --color-red-700: #f65843; - --color-red-800: #ff755e; - --color-red-900: #ff9581; - --color-red-1000: #ffb0a1; - --color-red-1100: #ffc9bd; - --color-red-1200: #ffded8; - --color-red-1300: #fff1ee; - - --color-celery-100: #00450a; - --color-celery-200: #00500c; - --color-celery-300: #005e0e; - --color-celery-400: #006d0f; - --color-celery-500: #007f0f; - --color-celery-600: #009112; - --color-celery-700: #04a51e; - --color-celery-800: #22b833; - --color-celery-900: #44ca49; - --color-celery-1000: #69dc63; - --color-celery-1100: #8eeb7f; - --color-celery-1200: #b4f7a2; - --color-celery-1300: #ddfdd3; - - --color-chartreuse-100: #304000; - --color-chartreuse-200: #374a00; - --color-chartreuse-300: #415700; - --color-chartreuse-400: #4c6600; - --color-chartreuse-500: #597600; - --color-chartreuse-600: #668800; - --color-chartreuse-700: #759a00; - --color-chartreuse-800: #84ad01; - --color-chartreuse-900: #94c008; - --color-chartreuse-1000: #a6d312; - --color-chartreuse-1100: #b8e525; - --color-chartreuse-1200: #cdf547; - --color-chartreuse-1300: #e7fe9a; - - --color-cyan-100: #003d62; - --color-cyan-200: #00476f; - --color-cyan-300: #00557f; - --color-cyan-400: #006491; - --color-cyan-500: #0074a2; - --color-cyan-600: #0086b4; - --color-cyan-700: #0099c6; - --color-cyan-800: #0eadd7; - --color-cyan-900: #2cc1e6; - --color-cyan-1000: #54d3f1; - --color-cyan-1100: #7fe4f9; - --color-cyan-1200: #a7f1ff; - --color-cyan-1300: #d7faff; - - --color-fuchsia-100: #6b036a; - --color-fuchsia-200: #7b007b; - --color-fuchsia-300: #900091; - --color-fuchsia-400: #a50da6; - --color-fuchsia-500: #b925b9; - --color-fuchsia-600: #cd39ce; - --color-fuchsia-700: #df51e0; - --color-fuchsia-800: #eb6eec; - --color-fuchsia-900: #f48cf2; - --color-fuchsia-1000: #faa8f5; - --color-fuchsia-1100: #fec2f8; - --color-fuchsia-1200: #ffdbfa; - --color-fuchsia-1300: #ffeffc; - - --color-indigo-100: #282c8c; - --color-indigo-200: #2f34a3; - --color-indigo-300: #393fbb; - --color-indigo-400: #464bd3; - --color-indigo-500: #555be7; - --color-indigo-600: #686df4; - --color-indigo-700: #7c81fb; - --color-indigo-800: #9195ff; - --color-indigo-900: #a7aaff; - --color-indigo-1000: #bcbeff; - --color-indigo-1100: #d0d2ff; - --color-indigo-1200: #e2e4ff; - --color-indigo-1300: #f3f3fe; - - --color-magenta-100: #76003a; - --color-magenta-200: #890042; - --color-magenta-300: #a0004d; - --color-magenta-400: #b6125a; - --color-magenta-500: #cb266d; - --color-magenta-600: #de3d82; - --color-magenta-700: #ed5795; - --color-magenta-800: #f972a7; - --color-magenta-900: #ff8fb9; - --color-magenta-1000: #ffacca; - --color-magenta-1100: #ffc6da; - --color-magenta-1200: #ffdde9; - --color-magenta-1300: #fff0f5; - - --color-purple-100: #4c0d9d; - --color-purple-200: #5911b1; - --color-purple-300: #691cc8; - --color-purple-400: #7a2dda; - --color-purple-500: #8c41e9; - --color-purple-600: #9d57f3; - --color-purple-700: #ac6ff9; - --color-purple-800: #bb87fb; - --color-purple-900: #ca9ffc; - --color-purple-1000: #d7b6fe; - --color-purple-1100: #e4ccfe; - --color-purple-1200: #efdfff; - --color-purple-1300: #f9f0ff; - - --color-seafoam-100: #12413f; - --color-seafoam-200: #0e4c49; - --color-seafoam-300: #045a57; - --color-seafoam-400: #006965; - --color-seafoam-500: #007a75; - --color-seafoam-600: #008c87; - --color-seafoam-700: #009e98; - --color-seafoam-800: #03b2ab; - --color-seafoam-900: #36c5bd; - --color-seafoam-1000: #5dd6cf; - --color-seafoam-1100: #84e6df; - --color-seafoam-1200: #b0f2ec; - --color-seafoam-1300: #dff9f6; - - --color-yellow-100: #4c3600; - --color-yellow-200: #584000; - --color-yellow-300: #674c00; - --color-yellow-400: #775900; - --color-yellow-500: #886800; - --color-yellow-600: #9b7800; - --color-yellow-700: #ae8900; - --color-yellow-800: #c09c00; - --color-yellow-900: #d3ae00; - --color-yellow-1000: #e4c200; - --color-yellow-1100: #f4d500; - --color-yellow-1200: #f9e85c; - --color-yellow-1300: #fcf6bb; - } -} - -@media (prefers-color-scheme: light) { - :root { - --color-white: #ffffff; - - --color-gray-50: #fdfdfd; - --color-gray-100: #f8f8f8; - --color-gray-200: #e6e6e6; - --color-gray-300: #d5d5d5; - --color-gray-400: #b1b1b1; - --color-gray-500: #909090; - --color-gray-600: #6d6d6d; - --color-gray-700: #464646; - --color-gray-800: #222222; - --color-gray-900: #151515; - - --color-black: #000000; - - --color-blue-100: #e0f2ff; - --color-blue-200: #cae8ff; - --color-blue-300: #b5deff; - --color-blue-400: #96cefd; - --color-blue-500: #78bbfa; - --color-blue-600: #59a7f6; - --color-blue-700: #3892f3; - --color-blue-800: #147af3; - --color-blue-900: #0265dc; - --color-blue-1000: #0054b6; - --color-blue-1100: #004491; - --color-blue-1200: #003571; - --color-blue-1300: #002754; - - --color-green-100: #cef8e0; - --color-green-200: #adf4ce; - --color-green-300: #89ecbc; - --color-green-400: #67dea8; - --color-green-500: #49cc93; - --color-green-600: #2fb880; - --color-green-700: #15a46e; - --color-green-800: #008f5d; - --color-green-900: #007a4d; - --color-green-1000: #00653e; - --color-green-1100: #005132; - --color-green-1200: #053f27; - --color-green-1300: #0a2e1d; - - --color-orange-100: #ffeccc; - --color-orange-200: #ffdfad; - --color-orange-300: #fdd291; - --color-orange-400: #ffbb63; - --color-orange-500: #ffa037; - --color-orange-600: #f68511; - --color-orange-700: #e46f00; - --color-orange-800: #cb5d00; - --color-orange-900: #b14c00; - --color-orange-1000: #953d00; - --color-orange-1100: #7a2f00; - --color-orange-1200: #612300; - --color-orange-1300: #491901; - - --color-red-100: #ffebe7; - --color-red-200: #ffddd6; - --color-red-300: #ffcdc3; - --color-red-400: #ffb7a9; - --color-red-500: #ff9b88; - --color-red-600: #ff7c65; - --color-red-700: #f75c46; - --color-red-800: #ea3829; - --color-red-900: #d31510; - --color-red-1000: #b40000; - --color-red-1100: #930000; - --color-red-1200: #740000; - --color-red-1300: #590000; - - --color-celery-100: #cdfcbf; - --color-celery-200: #aef69d; - --color-celery-300: #96ee85; - --color-celery-400: #72e06a; - --color-celery-500: #4ecf50; - --color-celery-600: #27bb36; - --color-celery-700: #07a721; - --color-celery-800: #009112; - --color-celery-900: #007c0f; - --color-celery-1000: #00670f; - --color-celery-1100: #00530d; - --color-celery-1200: #00400a; - --color-celery-1300: #003007; - - --color-chartreuse-100: #dbfc6e; - --color-chartreuse-200: #cbf443; - --color-chartreuse-300: #bce92a; - --color-chartreuse-400: #aad816; - --color-chartreuse-500: #98c50a; - --color-chartreuse-600: #87b103; - --color-chartreuse-700: #769c00; - --color-chartreuse-800: #678800; - --color-chartreuse-900: #577400; - --color-chartreuse-1000: #486000; - --color-chartreuse-1100: #3a4d00; - --color-chartreuse-1200: #2c3b00; - --color-chartreuse-1300: #212c00; - - --color-cyan-100: #c5f8ff; - --color-cyan-200: #a4f0ff; - --color-cyan-300: #88e7fa; - --color-cyan-400: #60d8f3; - --color-cyan-500: #33c5e8; - --color-cyan-600: #12b0da; - --color-cyan-700: #019cc8; - --color-cyan-800: #0086b4; - --color-cyan-900: #00719f; - --color-cyan-1000: #005d89; - --color-cyan-1100: #004a73; - --color-cyan-1200: #00395d; - --color-cyan-1300: #002a46; - - --color-fuchsia-100: #ffe9fc; - --color-fuchsia-200: #ffdafa; - --color-fuchsia-300: #fec7f8; - --color-fuchsia-400: #fbaef6; - --color-fuchsia-500: #f592f3; - --color-fuchsia-600: #ed74ed; - --color-fuchsia-700: #e055e2; - --color-fuchsia-800: #cd3ace; - --color-fuchsia-900: #b622b7; - --color-fuchsia-1000: #9d039e; - --color-fuchsia-1100: #800081; - --color-fuchsia-1200: #640664; - --color-fuchsia-1300: #470e46; - - --color-indigo-100: #edeeff; - --color-indigo-200: #e0e2ff; - --color-indigo-300: #d3d5ff; - --color-indigo-400: #c1c4ff; - --color-indigo-500: #acafff; - --color-indigo-600: #9599ff; - --color-indigo-700: #7e84fc; - --color-indigo-800: #686df4; - --color-indigo-900: #5258e4; - --color-indigo-1000: #4046ca; - --color-indigo-1100: #3236a8; - --color-indigo-1200: #262986; - --color-indigo-1300: #1b1e64; - - --color-magenta-100: #ffeaf1; - --color-magenta-200: #ffdce8; - --color-magenta-300: #ffcadd; - --color-magenta-400: #ffb2ce; - --color-magenta-500: #ff95bd; - --color-magenta-600: #fa77aa; - --color-magenta-700: #ef5a98; - --color-magenta-800: #de3d82; - --color-magenta-900: #c82269; - --color-magenta-1000: #ad0955; - --color-magenta-1100: #8e0045; - --color-magenta-1200: #700037; - --color-magenta-1300: #54032a; - - --color-purple-100: #f6ebff; - --color-purple-200: #eeddff; - --color-purple-300: #e6d0ff; - --color-purple-400: #dbbbfe; - --color-purple-500: #cca4fd; - --color-purple-600: #bd8bfc; - --color-purple-700: #ae72f9; - --color-purple-800: #9d57f4; - --color-purple-900: #893de7; - --color-purple-1000: #7326d3; - --color-purple-1100: #5d13b7; - --color-purple-1200: #470c94; - --color-purple-1300: #33106a; - - --color-seafoam-100: #cef7f3; - --color-seafoam-200: #aaf1ea; - --color-seafoam-300: #8ce9e2; - --color-seafoam-400: #65dad2; - --color-seafoam-500: #3fc9c1; - --color-seafoam-600: #0fb5ae; - --color-seafoam-700: #00a19a; - --color-seafoam-800: #008c87; - --color-seafoam-900: #007772; - --color-seafoam-1000: #00635f; - --color-seafoam-1100: #0c4f4c; - --color-seafoam-1200: #123c3a; - --color-seafoam-1300: #122c2b; - - --color-yellow-100: #fbf198; - --color-yellow-200: #f8e750; - --color-yellow-300: #f8d904; - --color-yellow-400: #e8c600; - --color-yellow-500: #d7b300; - --color-yellow-600: #c49f00; - --color-yellow-700: #b08c00; - --color-yellow-800: #9b7800; - --color-yellow-900: #856600; - --color-yellow-1000: #705300; - --color-yellow-1100: #5b4300; - --color-yellow-1200: #483300; - --color-yellow-1300: #362500; - } -} +:root { + /* Persisted colors variables (not changed on dark mode) */ + --color-persist-white: #ffffff; + --color-persist-gray-50: #fdfdfd; + --color-persist-gray-100: #f8f8f8; + --color-persist-gray-200: #e6e6e6; + --color-persist-gray-300: #d5d5d5; + --color-persist-gray-400: #b1b1b1; + --color-persist-gray-500: #909090; + --color-persist-gray-600: #6d6d6d; + --color-persist-gray-700: #464646; + --color-persist-gray-800: #222222; + --color-persist-gray-900: #151515; + --color-persist-black: #000000; + + --color-persist-blue-100: #e0f2ff; + --color-persist-blue-200: #cae8ff; + --color-persist-blue-300: #b5deff; + --color-persist-blue-400: #96cefd; + --color-persist-blue-500: #78bbfa; + --color-persist-blue-600: #59a7f6; + --color-persist-blue-700: #3892f3; + --color-persist-blue-800: #147af3; + --color-persist-blue-900: #0265dc; + --color-persist-blue-1000: #0054b6; + --color-persist-blue-1100: #004491; + --color-persist-blue-1200: #003571; + --color-persist-blue-1300: #002754; + + --color-persist-green-100: #cef8e0; + --color-persist-green-200: #adf4ce; + --color-persist-green-300: #89ecbc; + --color-persist-green-400: #67dea8; + --color-persist-green-500: #49cc93; + --color-persist-green-600: #2fb880; + --color-persist-green-700: #15a46e; + --color-persist-green-800: #008f5d; + --color-persist-green-900: #007a4d; + --color-persist-green-1000: #00653e; + --color-persist-green-1100: #005132; + --color-persist-green-1200: #053f27; + --color-persist-green-1300: #0a2e1d; + + --color-persist-orange-100: #ffeccc; + --color-persist-orange-200: #ffdfad; + --color-persist-orange-300: #fdd291; + --color-persist-orange-400: #ffbb63; + --color-persist-orange-500: #ffa037; + --color-persist-orange-600: #f68511; + --color-persist-orange-700: #e46f00; + --color-persist-orange-800: #cb5d00; + --color-persist-orange-900: #b14c00; + --color-persist-orange-1000: #953d00; + --color-persist-orange-1100: #7a2f00; + --color-persist-orange-1200: #612300; + --color-persist-orange-1300: #491901; + + --color-persist-red-100: #ffebe7; + --color-persist-red-200: #ffddd6; + --color-persist-red-300: #ffcdc3; + --color-persist-red-400: #ffb7a9; + --color-persist-red-500: #ff9b88; + --color-persist-red-600: #ff7c65; + --color-persist-red-700: #f75c46; + --color-persist-red-800: #ea3829; + --color-persist-red-900: #d31510; + --color-persist-red-1000: #b40000; + --color-persist-red-1100: #930000; + --color-persist-red-1200: #740000; + --color-persist-red-1300: #590000; + + --color-persist-celery-100: #cdfcbf; + --color-persist-celery-200: #aef69d; + --color-persist-celery-300: #96ee85; + --color-persist-celery-400: #72e06a; + --color-persist-celery-500: #4ecf50; + --color-persist-celery-600: #27bb36; + --color-persist-celery-700: #07a721; + --color-persist-celery-800: #009112; + --color-persist-celery-900: #007c0f; + --color-persist-celery-1000: #00670f; + --color-persist-celery-1100: #00530d; + --color-persist-celery-1200: #00400a; + --color-persist-celery-1300: #003007; + + --color-persist-chartreuse-100: #dbfc6e; + --color-persist-chartreuse-200: #cbf443; + --color-persist-chartreuse-300: #bce92a; + --color-persist-chartreuse-400: #aad816; + --color-persist-chartreuse-500: #98c50a; + --color-persist-chartreuse-600: #87b103; + --color-persist-chartreuse-700: #769c00; + --color-persist-chartreuse-800: #678800; + --color-persist-chartreuse-900: #577400; + --color-persist-chartreuse-1000: #486000; + --color-persist-chartreuse-1100: #3a4d00; + --color-persist-chartreuse-1200: #2c3b00; + --color-persist-chartreuse-1300: #212c00; + + --color-persist-cyan-100: #c5f8ff; + --color-persist-cyan-200: #a4f0ff; + --color-persist-cyan-300: #88e7fa; + --color-persist-cyan-400: #60d8f3; + --color-persist-cyan-500: #33c5e8; + --color-persist-cyan-600: #12b0da; + --color-persist-cyan-700: #019cc8; + --color-persist-cyan-800: #0086b4; + --color-persist-cyan-900: #00719f; + --color-persist-cyan-1000: #005d89; + --color-persist-cyan-1100: #004a73; + --color-persist-cyan-1200: #00395d; + --color-persist-cyan-1300: #002a46; + + --color-persist-fuchsia-100: #ffe9fc; + --color-persist-fuchsia-200: #ffdafa; + --color-persist-fuchsia-300: #fec7f8; + --color-persist-fuchsia-400: #fbaef6; + --color-persist-fuchsia-500: #f592f3; + --color-persist-fuchsia-600: #ed74ed; + --color-persist-fuchsia-700: #e055e2; + --color-persist-fuchsia-800: #cd3ace; + --color-persist-fuchsia-900: #b622b7; + --color-persist-fuchsia-1000: #9d039e; + --color-persist-fuchsia-1100: #800081; + --color-persist-fuchsia-1200: #640664; + --color-persist-fuchsia-1300: #470e46; + + --color-persist-indigo-100: #edeeff; + --color-persist-indigo-200: #e0e2ff; + --color-persist-indigo-300: #d3d5ff; + --color-persist-indigo-400: #c1c4ff; + --color-persist-indigo-500: #acafff; + --color-persist-indigo-600: #9599ff; + --color-persist-indigo-700: #7e84fc; + --color-persist-indigo-800: #686df4; + --color-persist-indigo-900: #5258e4; + --color-persist-indigo-1000: #4046ca; + --color-persist-indigo-1100: #3236a8; + --color-persist-indigo-1200: #262986; + --color-persist-indigo-1300: #1b1e64; + + --color-persist-magenta-100: #ffeaf1; + --color-persist-magenta-200: #ffdce8; + --color-persist-magenta-300: #ffcadd; + --color-persist-magenta-400: #ffb2ce; + --color-persist-magenta-500: #ff95bd; + --color-persist-magenta-600: #fa77aa; + --color-persist-magenta-700: #ef5a98; + --color-persist-magenta-800: #de3d82; + --color-persist-magenta-900: #c82269; + --color-persist-magenta-1000: #ad0955; + --color-persist-magenta-1100: #8e0045; + --color-persist-magenta-1200: #700037; + --color-persist-magenta-1300: #54032a; + + --color-persist-purple-100: #f6ebff; + --color-persist-purple-200: #eeddff; + --color-persist-purple-300: #e6d0ff; + --color-persist-purple-400: #dbbbfe; + --color-persist-purple-500: #cca4fd; + --color-persist-purple-600: #bd8bfc; + --color-persist-purple-700: #ae72f9; + --color-persist-purple-800: #9d57f4; + --color-persist-purple-900: #893de7; + --color-persist-purple-1000: #7326d3; + --color-persist-purple-1100: #5d13b7; + --color-persist-purple-1200: #470c94; + --color-persist-purple-1300: #33106a; + + --color-persist-seafoam-100: #cef7f3; + --color-persist-seafoam-200: #aaf1ea; + --color-persist-seafoam-300: #8ce9e2; + --color-persist-seafoam-400: #65dad2; + --color-persist-seafoam-500: #3fc9c1; + --color-persist-seafoam-600: #0fb5ae; + --color-persist-seafoam-700: #00a19a; + --color-persist-seafoam-800: #008c87; + --color-persist-seafoam-900: #007772; + --color-persist-seafoam-1000: #00635f; + --color-persist-seafoam-1100: #0c4f4c; + --color-persist-seafoam-1200: #123c3a; + --color-persist-seafoam-1300: #122c2b; + + --color-persist-yellow-100: #fbf198; + --color-persist-yellow-200: #f8e750; + --color-persist-yellow-300: #f8d904; + --color-persist-yellow-400: #e8c600; + --color-persist-yellow-500: #d7b300; + --color-persist-yellow-600: #c49f00; + --color-persist-yellow-700: #b08c00; + --color-persist-yellow-800: #9b7800; + --color-persist-yellow-900: #856600; + --color-persist-yellow-1000: #705300; + --color-persist-yellow-1100: #5b4300; + --color-persist-yellow-1200: #483300; + --color-persist-yellow-1300: #362500; +} + +@media (prefers-color-scheme: dark) { + :root { + --color-white: #000000; + + --color-gray-50: #151515; + --color-gray-100: #222222; + --color-gray-200: #464646; + --color-gray-300: #6d6d6d; + --color-gray-400: #909090; + --color-gray-500: #b1b1b1; + --color-gray-600: #d5d5d5; + --color-gray-700: #e6e6e6; + --color-gray-800: #f8f8f8; + --color-gray-900: #fdfdfd; + + --color-black: #ffffff; + + --color-blue-100: #003877; + --color-blue-200: #00418a; + --color-blue-300: #004da3; + --color-blue-400: #0059c2; + --color-blue-500: #0367e0; + --color-blue-600: #1379f3; + --color-blue-700: #348ff4; + --color-blue-800: #54a3f6; + --color-blue-900: #72b7f9; + --color-blue-1000: #8fcafc; + --color-blue-1100: #aedbfe; + --color-blue-1200: #cce9ff; + --color-blue-1300: #e8f6ff; + + --color-green-100: #044329; + --color-green-200: #004e2f; + --color-green-300: #005c38; + --color-green-400: #006c43; + --color-green-500: #007d4e; + --color-green-600: #008f5d; + --color-green-700: #12a26c; + --color-green-800: #2bb47d; + --color-green-900: #43c78f; + --color-green-1000: #5ed9a2; + --color-green-1100: #81e9b8; + --color-green-1200: #b1f4d1; + --color-green-1300: #dffaea; + + --color-orange-100: #662500; + --color-orange-200: #752d00; + --color-orange-300: #893700; + --color-orange-400: #9e4200; + --color-orange-500: #b44e00; + --color-orange-600: #ca5d00; + --color-orange-700: #e16d00; + --color-orange-800: #f4810c; + --color-orange-900: #fe9a2e; + --color-orange-1000: #ffb558; + --color-orange-1100: #fdce88; + --color-orange-1200: #ffe1b3; + --color-orange-1300: #fff2dd; + + --color-red-100: #7b0000; + --color-red-200: #8d0000; + --color-red-300: #a50000; + --color-red-400: #be0403; + --color-red-500: #d71913; + --color-red-600: #ea3829; + --color-red-700: #f65843; + --color-red-800: #ff755e; + --color-red-900: #ff9581; + --color-red-1000: #ffb0a1; + --color-red-1100: #ffc9bd; + --color-red-1200: #ffded8; + --color-red-1300: #fff1ee; + + --color-celery-100: #00450a; + --color-celery-200: #00500c; + --color-celery-300: #005e0e; + --color-celery-400: #006d0f; + --color-celery-500: #007f0f; + --color-celery-600: #009112; + --color-celery-700: #04a51e; + --color-celery-800: #22b833; + --color-celery-900: #44ca49; + --color-celery-1000: #69dc63; + --color-celery-1100: #8eeb7f; + --color-celery-1200: #b4f7a2; + --color-celery-1300: #ddfdd3; + + --color-chartreuse-100: #304000; + --color-chartreuse-200: #374a00; + --color-chartreuse-300: #415700; + --color-chartreuse-400: #4c6600; + --color-chartreuse-500: #597600; + --color-chartreuse-600: #668800; + --color-chartreuse-700: #759a00; + --color-chartreuse-800: #84ad01; + --color-chartreuse-900: #94c008; + --color-chartreuse-1000: #a6d312; + --color-chartreuse-1100: #b8e525; + --color-chartreuse-1200: #cdf547; + --color-chartreuse-1300: #e7fe9a; + + --color-cyan-100: #003d62; + --color-cyan-200: #00476f; + --color-cyan-300: #00557f; + --color-cyan-400: #006491; + --color-cyan-500: #0074a2; + --color-cyan-600: #0086b4; + --color-cyan-700: #0099c6; + --color-cyan-800: #0eadd7; + --color-cyan-900: #2cc1e6; + --color-cyan-1000: #54d3f1; + --color-cyan-1100: #7fe4f9; + --color-cyan-1200: #a7f1ff; + --color-cyan-1300: #d7faff; + + --color-fuchsia-100: #6b036a; + --color-fuchsia-200: #7b007b; + --color-fuchsia-300: #900091; + --color-fuchsia-400: #a50da6; + --color-fuchsia-500: #b925b9; + --color-fuchsia-600: #cd39ce; + --color-fuchsia-700: #df51e0; + --color-fuchsia-800: #eb6eec; + --color-fuchsia-900: #f48cf2; + --color-fuchsia-1000: #faa8f5; + --color-fuchsia-1100: #fec2f8; + --color-fuchsia-1200: #ffdbfa; + --color-fuchsia-1300: #ffeffc; + + --color-indigo-100: #282c8c; + --color-indigo-200: #2f34a3; + --color-indigo-300: #393fbb; + --color-indigo-400: #464bd3; + --color-indigo-500: #555be7; + --color-indigo-600: #686df4; + --color-indigo-700: #7c81fb; + --color-indigo-800: #9195ff; + --color-indigo-900: #a7aaff; + --color-indigo-1000: #bcbeff; + --color-indigo-1100: #d0d2ff; + --color-indigo-1200: #e2e4ff; + --color-indigo-1300: #f3f3fe; + + --color-magenta-100: #76003a; + --color-magenta-200: #890042; + --color-magenta-300: #a0004d; + --color-magenta-400: #b6125a; + --color-magenta-500: #cb266d; + --color-magenta-600: #de3d82; + --color-magenta-700: #ed5795; + --color-magenta-800: #f972a7; + --color-magenta-900: #ff8fb9; + --color-magenta-1000: #ffacca; + --color-magenta-1100: #ffc6da; + --color-magenta-1200: #ffdde9; + --color-magenta-1300: #fff0f5; + + --color-purple-100: #4c0d9d; + --color-purple-200: #5911b1; + --color-purple-300: #691cc8; + --color-purple-400: #7a2dda; + --color-purple-500: #8c41e9; + --color-purple-600: #9d57f3; + --color-purple-700: #ac6ff9; + --color-purple-800: #bb87fb; + --color-purple-900: #ca9ffc; + --color-purple-1000: #d7b6fe; + --color-purple-1100: #e4ccfe; + --color-purple-1200: #efdfff; + --color-purple-1300: #f9f0ff; + + --color-seafoam-100: #12413f; + --color-seafoam-200: #0e4c49; + --color-seafoam-300: #045a57; + --color-seafoam-400: #006965; + --color-seafoam-500: #007a75; + --color-seafoam-600: #008c87; + --color-seafoam-700: #009e98; + --color-seafoam-800: #03b2ab; + --color-seafoam-900: #36c5bd; + --color-seafoam-1000: #5dd6cf; + --color-seafoam-1100: #84e6df; + --color-seafoam-1200: #b0f2ec; + --color-seafoam-1300: #dff9f6; + + --color-yellow-100: #4c3600; + --color-yellow-200: #584000; + --color-yellow-300: #674c00; + --color-yellow-400: #775900; + --color-yellow-500: #886800; + --color-yellow-600: #9b7800; + --color-yellow-700: #ae8900; + --color-yellow-800: #c09c00; + --color-yellow-900: #d3ae00; + --color-yellow-1000: #e4c200; + --color-yellow-1100: #f4d500; + --color-yellow-1200: #f9e85c; + --color-yellow-1300: #fcf6bb; + } +} + +@media (prefers-color-scheme: light) { + :root { + --color-white: #ffffff; + + --color-gray-50: #fdfdfd; + --color-gray-100: #f8f8f8; + --color-gray-200: #e6e6e6; + --color-gray-300: #d5d5d5; + --color-gray-400: #b1b1b1; + --color-gray-500: #909090; + --color-gray-600: #6d6d6d; + --color-gray-700: #464646; + --color-gray-800: #222222; + --color-gray-900: #151515; + + --color-black: #000000; + + --color-blue-100: #e0f2ff; + --color-blue-200: #cae8ff; + --color-blue-300: #b5deff; + --color-blue-400: #96cefd; + --color-blue-500: #78bbfa; + --color-blue-600: #59a7f6; + --color-blue-700: #3892f3; + --color-blue-800: #147af3; + --color-blue-900: #0265dc; + --color-blue-1000: #0054b6; + --color-blue-1100: #004491; + --color-blue-1200: #003571; + --color-blue-1300: #002754; + + --color-green-100: #cef8e0; + --color-green-200: #adf4ce; + --color-green-300: #89ecbc; + --color-green-400: #67dea8; + --color-green-500: #49cc93; + --color-green-600: #2fb880; + --color-green-700: #15a46e; + --color-green-800: #008f5d; + --color-green-900: #007a4d; + --color-green-1000: #00653e; + --color-green-1100: #005132; + --color-green-1200: #053f27; + --color-green-1300: #0a2e1d; + + --color-orange-100: #ffeccc; + --color-orange-200: #ffdfad; + --color-orange-300: #fdd291; + --color-orange-400: #ffbb63; + --color-orange-500: #ffa037; + --color-orange-600: #f68511; + --color-orange-700: #e46f00; + --color-orange-800: #cb5d00; + --color-orange-900: #b14c00; + --color-orange-1000: #953d00; + --color-orange-1100: #7a2f00; + --color-orange-1200: #612300; + --color-orange-1300: #491901; + + --color-red-100: #ffebe7; + --color-red-200: #ffddd6; + --color-red-300: #ffcdc3; + --color-red-400: #ffb7a9; + --color-red-500: #ff9b88; + --color-red-600: #ff7c65; + --color-red-700: #f75c46; + --color-red-800: #ea3829; + --color-red-900: #d31510; + --color-red-1000: #b40000; + --color-red-1100: #930000; + --color-red-1200: #740000; + --color-red-1300: #590000; + + --color-celery-100: #cdfcbf; + --color-celery-200: #aef69d; + --color-celery-300: #96ee85; + --color-celery-400: #72e06a; + --color-celery-500: #4ecf50; + --color-celery-600: #27bb36; + --color-celery-700: #07a721; + --color-celery-800: #009112; + --color-celery-900: #007c0f; + --color-celery-1000: #00670f; + --color-celery-1100: #00530d; + --color-celery-1200: #00400a; + --color-celery-1300: #003007; + + --color-chartreuse-100: #dbfc6e; + --color-chartreuse-200: #cbf443; + --color-chartreuse-300: #bce92a; + --color-chartreuse-400: #aad816; + --color-chartreuse-500: #98c50a; + --color-chartreuse-600: #87b103; + --color-chartreuse-700: #769c00; + --color-chartreuse-800: #678800; + --color-chartreuse-900: #577400; + --color-chartreuse-1000: #486000; + --color-chartreuse-1100: #3a4d00; + --color-chartreuse-1200: #2c3b00; + --color-chartreuse-1300: #212c00; + + --color-cyan-100: #c5f8ff; + --color-cyan-200: #a4f0ff; + --color-cyan-300: #88e7fa; + --color-cyan-400: #60d8f3; + --color-cyan-500: #33c5e8; + --color-cyan-600: #12b0da; + --color-cyan-700: #019cc8; + --color-cyan-800: #0086b4; + --color-cyan-900: #00719f; + --color-cyan-1000: #005d89; + --color-cyan-1100: #004a73; + --color-cyan-1200: #00395d; + --color-cyan-1300: #002a46; + + --color-fuchsia-100: #ffe9fc; + --color-fuchsia-200: #ffdafa; + --color-fuchsia-300: #fec7f8; + --color-fuchsia-400: #fbaef6; + --color-fuchsia-500: #f592f3; + --color-fuchsia-600: #ed74ed; + --color-fuchsia-700: #e055e2; + --color-fuchsia-800: #cd3ace; + --color-fuchsia-900: #b622b7; + --color-fuchsia-1000: #9d039e; + --color-fuchsia-1100: #800081; + --color-fuchsia-1200: #640664; + --color-fuchsia-1300: #470e46; + + --color-indigo-100: #edeeff; + --color-indigo-200: #e0e2ff; + --color-indigo-300: #d3d5ff; + --color-indigo-400: #c1c4ff; + --color-indigo-500: #acafff; + --color-indigo-600: #9599ff; + --color-indigo-700: #7e84fc; + --color-indigo-800: #686df4; + --color-indigo-900: #5258e4; + --color-indigo-1000: #4046ca; + --color-indigo-1100: #3236a8; + --color-indigo-1200: #262986; + --color-indigo-1300: #1b1e64; + + --color-magenta-100: #ffeaf1; + --color-magenta-200: #ffdce8; + --color-magenta-300: #ffcadd; + --color-magenta-400: #ffb2ce; + --color-magenta-500: #ff95bd; + --color-magenta-600: #fa77aa; + --color-magenta-700: #ef5a98; + --color-magenta-800: #de3d82; + --color-magenta-900: #c82269; + --color-magenta-1000: #ad0955; + --color-magenta-1100: #8e0045; + --color-magenta-1200: #700037; + --color-magenta-1300: #54032a; + + --color-purple-100: #f6ebff; + --color-purple-200: #eeddff; + --color-purple-300: #e6d0ff; + --color-purple-400: #dbbbfe; + --color-purple-500: #cca4fd; + --color-purple-600: #bd8bfc; + --color-purple-700: #ae72f9; + --color-purple-800: #9d57f4; + --color-purple-900: #893de7; + --color-purple-1000: #7326d3; + --color-purple-1100: #5d13b7; + --color-purple-1200: #470c94; + --color-purple-1300: #33106a; + + --color-seafoam-100: #cef7f3; + --color-seafoam-200: #aaf1ea; + --color-seafoam-300: #8ce9e2; + --color-seafoam-400: #65dad2; + --color-seafoam-500: #3fc9c1; + --color-seafoam-600: #0fb5ae; + --color-seafoam-700: #00a19a; + --color-seafoam-800: #008c87; + --color-seafoam-900: #007772; + --color-seafoam-1000: #00635f; + --color-seafoam-1100: #0c4f4c; + --color-seafoam-1200: #123c3a; + --color-seafoam-1300: #122c2b; + + --color-yellow-100: #fbf198; + --color-yellow-200: #f8e750; + --color-yellow-300: #f8d904; + --color-yellow-400: #e8c600; + --color-yellow-500: #d7b300; + --color-yellow-600: #c49f00; + --color-yellow-700: #b08c00; + --color-yellow-800: #9b7800; + --color-yellow-900: #856600; + --color-yellow-1000: #705300; + --color-yellow-1100: #5b4300; + --color-yellow-1200: #483300; + --color-yellow-1300: #362500; + } +} diff --git a/src/apps/toolbar/styles/global.css b/src/apps/toolbar/styles/global.css index c3a8de51..7a88e6ba 100644 --- a/src/apps/toolbar/styles/global.css +++ b/src/apps/toolbar/styles/global.css @@ -1,223 +1,223 @@ -/** - * The styles in this file are only structural for toolbar, - * all the design should be added to the default theme css. - */ -body { - overflow: hidden; - cursor: default; - background: transparent; - width: 100vw; - height: 100vh; -} - -.fancy-toolbar { - width: 100vw; - line-height: 1em; - - .ft-bar { - position: relative; - width: 100%; - height: var(--config-height); - display: flex; - justify-content: space-between; - align-items: center; - padding: 0 var(--config-padding-at-side); - - .ft-bar-left, - .ft-bar-center, - .ft-bar-right { - display: flex; - align-items: stretch; - height: min-content; - gap: 6px; - } - - .ft-bar-left { - max-width: 50%; - width: 50%; - overflow: hidden; - justify-content: flex-start; - } - - .ft-bar-center { - justify-content: center; - padding: 0 6px; - } - - .ft-bar-right { - max-width: 50%; - width: 50%; - overflow: hidden; - justify-content: flex-end; - } - } -} - -.ft-bar-item-tooltip { - top: calc(var(--config-height) + 4px) !important; /* Override inline style */ -} - -.ft-bar-group { - display: flex; - align-items: center; - gap: 6px; -} - -.ft-bar-item { - display: flex; - align-items: center; - justify-content: center; - min-width: 0; - - .ft-bar-item-content { - display: flex; - align-items: center; - width: 100%; - - > span { - text-overflow: ellipsis; - overflow: hidden; - white-space: pre; - } - - &.workspaces { - gap: 12px; - margin: 0 4px; - - .workspace-dot { - width: 6px; - height: 6px; - border-radius: 3px; - - &.workspace-dot-active { - width: 18px; - } - } - } - } -} - -.tray { - position: relative; - width: 250px; - - .tray-list { - position: relative; - z-index: 1; - - .tray-item-icon { - display: flex; - align-items: center; - justify-content: center; - } - } -} - -.wlan-selector { - position: relative; - width: 300px; - - .wlan-selector-entries { - position: relative; - z-index: 1; - display: flex; - flex-direction: column; - gap: 6px; - - .wlan-selector-empty { - display: flex; - align-items: center; - justify-content: center; - padding: 12px; - } - - .wlan-entry { - display: flex; - flex-direction: column; - gap: 6px; - - .wlan-entry-info { - display: flex; - align-items: center; - justify-content: space-between; - gap: 6px; - - .wlan-entry-info-ssid { - flex: 1; - } - } - - .wlan-entry-fields { - display: flex; - flex-direction: column; - gap: 6px; - } - - .wlan-entry-actions { - display: flex; - justify-content: flex-end; - } - } - } - - .wlan-selector-footer { - position: relative; - z-index: 1; - } -} - -.fast-settings { - position: relative; - display: flex; - flex-direction: column; - gap: 4px; - width: 300px; - - .fast-settings-title { - z-index: 1; - font-weight: 600; - position: relative; - display: flex; - align-items: center; - justify-content: center; - - .fast-settings-item-title-button { - position: absolute; - top: 0; - right: 0; - padding: 6px; - border-radius: 6px; - - &:hover { - backdrop-filter: brightness(0.8); - } - } - } - - .fast-settings-item { - z-index: 1; - display: flex; - gap: 6px; - align-items: center; - - .ant-slider { - flex: 1; - } - } - - .fast-settings-power { - display: flex; - gap: 6px; - - > .fast-settings-item-button { - flex: 1; - } - } - - .fast-settings-item-button { - display: flex; - align-items: center; - justify-content: center; - padding: 8px 12px; - } -} +/** + * The styles in this file are only structural for toolbar, + * all the design should be added to the default theme css. + */ +body { + overflow: hidden; + cursor: default; + background: transparent; + width: 100vw; + height: 100vh; +} + +.fancy-toolbar { + width: 100vw; + line-height: 1em; + + .ft-bar { + position: relative; + width: 100%; + height: var(--config-height); + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 var(--config-padding-at-side); + + .ft-bar-left, + .ft-bar-center, + .ft-bar-right { + display: flex; + align-items: stretch; + height: min-content; + gap: 6px; + } + + .ft-bar-left { + max-width: 50%; + width: 50%; + overflow: hidden; + justify-content: flex-start; + } + + .ft-bar-center { + justify-content: center; + padding: 0 6px; + } + + .ft-bar-right { + max-width: 50%; + width: 50%; + overflow: hidden; + justify-content: flex-end; + } + } +} + +.ft-bar-item-tooltip { + top: calc(var(--config-height) + 4px) !important; /* Override inline style */ +} + +.ft-bar-group { + display: flex; + align-items: center; + gap: 6px; +} + +.ft-bar-item { + display: flex; + align-items: center; + justify-content: center; + min-width: 0; + + .ft-bar-item-content { + display: flex; + align-items: center; + width: 100%; + + > span { + text-overflow: ellipsis; + overflow: hidden; + white-space: pre; + } + + &.workspaces { + gap: 12px; + margin: 0 4px; + + .workspace-dot { + width: 6px; + height: 6px; + border-radius: 3px; + + &.workspace-dot-active { + width: 18px; + } + } + } + } +} + +.tray { + position: relative; + width: 250px; + + .tray-list { + position: relative; + z-index: 1; + + .tray-item-icon { + display: flex; + align-items: center; + justify-content: center; + } + } +} + +.wlan-selector { + position: relative; + width: 300px; + + .wlan-selector-entries { + position: relative; + z-index: 1; + display: flex; + flex-direction: column; + gap: 6px; + + .wlan-selector-empty { + display: flex; + align-items: center; + justify-content: center; + padding: 12px; + } + + .wlan-entry { + display: flex; + flex-direction: column; + gap: 6px; + + .wlan-entry-info { + display: flex; + align-items: center; + justify-content: space-between; + gap: 6px; + + .wlan-entry-info-ssid { + flex: 1; + } + } + + .wlan-entry-fields { + display: flex; + flex-direction: column; + gap: 6px; + } + + .wlan-entry-actions { + display: flex; + justify-content: flex-end; + } + } + } + + .wlan-selector-footer { + position: relative; + z-index: 1; + } +} + +.fast-settings { + position: relative; + display: flex; + flex-direction: column; + gap: 4px; + width: 300px; + + .fast-settings-title { + z-index: 1; + font-weight: 600; + position: relative; + display: flex; + align-items: center; + justify-content: center; + + .fast-settings-item-title-button { + position: absolute; + top: 0; + right: 0; + padding: 6px; + border-radius: 6px; + + &:hover { + backdrop-filter: brightness(0.8); + } + } + } + + .fast-settings-item { + z-index: 1; + display: flex; + gap: 6px; + align-items: center; + + .ant-slider { + flex: 1; + } + } + + .fast-settings-power { + display: flex; + gap: 6px; + + > .fast-settings-item-button { + flex: 1; + } + } + + .fast-settings-item-button { + display: flex; + align-items: center; + justify-content: center; + padding: 8px 12px; + } +} diff --git a/src/apps/toolbar/styles/reset.css b/src/apps/toolbar/styles/reset.css index 596dad8d..af4e57ca 100644 --- a/src/apps/toolbar/styles/reset.css +++ b/src/apps/toolbar/styles/reset.css @@ -1,135 +1,135 @@ -:root { - font-size: 100%; - --main-typo: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; - --primary-color: var(--color-gray-900); - --secondary-color: var(--color-gray-50); -} - -*, *:after, *:before { - margin: 0; - padding: 0; - border: 0; - outline: none; - box-sizing: border-box; - vertical-align: baseline; - -webkit-user-select: none; - user-select: none; -} - -img, image, picture, video, iframe, figure { - max-width: 100%; - width: 100%; - display: block; -} - -a { - display: block; -} - -p a { - display: inline; -} - -li { - list-style-type: none; -} - -html { - scroll-behavior: smooth; -} - -h1, h2, h3, h4, h5, h6, p, span, a, strong, blockquote, i, b, em, pre { - font-size: 1em; - font-weight: inherit; - font-style: inherit; - text-decoration: none; - color: inherit; -} - -form, input, textarea, select, button, label { - font-family: inherit; - font-size: inherit; - hyphens: auto; - background-color: transparent; - display: block; - color: inherit; -} - -table, tr, td { - border-collapse: collapse; - border-spacing: 0; -} - -svg { - width: 100%; - display: block; -} - -body { - font-size: 1em; - line-height: 1.4em; - font-family: var(--main-typo); - color: var(--primary-color); - background-color: var(--secondary-color); - hyphens: auto; - font-smooth: always; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -hr { - border: 1px solid; - margin: 1em 0; - opacity: 0.8; - color: var(--color-gray-200); -} - -/* Antd reset */ -#root { - .ant-popover { - .ant-popover-inner { - background: transparent; - border-radius: 0; - box-shadow: none; - padding: 0; - } - } - - .ant-dropdown-menu-submenu, - .ant-dropdown-menu, - .ant-menu { - background: transparent; - box-shadow: none; - display: flex; - flex-direction: column; - gap: 4px; - - .ant-menu-item, - .ant-dropdown-menu-item { - padding: 10px; - height: min-content; - width: 100%; - line-height: 12px; - margin: 0; - border-radius: 8px; - } - - .ant-menu-item:not(.ant-menu-item-danger), - .ant-dropdown-menu-item:not(.ant-dropdown-menu-item-danger) { - color: inherit; - - &:hover { - backdrop-filter: brightness(0.6); - } - } - - .ant-menu-item-divider, - .ant-dropdown-menu-item-divider { - backdrop-filter: brightness(0.85); - } - - .ant-dropdown-menu-submenu-title { - color: inherit; - } - } +:root { + font-size: 100%; + --main-typo: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + --primary-color: var(--color-gray-900); + --secondary-color: var(--color-gray-50); +} + +*, *:after, *:before { + margin: 0; + padding: 0; + border: 0; + outline: none; + box-sizing: border-box; + vertical-align: baseline; + -webkit-user-select: none; + user-select: none; +} + +img, image, picture, video, iframe, figure { + max-width: 100%; + width: 100%; + display: block; +} + +a { + display: block; +} + +p a { + display: inline; +} + +li { + list-style-type: none; +} + +html { + scroll-behavior: smooth; +} + +h1, h2, h3, h4, h5, h6, p, span, a, strong, blockquote, i, b, em, pre { + font-size: 1em; + font-weight: inherit; + font-style: inherit; + text-decoration: none; + color: inherit; +} + +form, input, textarea, select, button, label { + font-family: inherit; + font-size: inherit; + hyphens: auto; + background-color: transparent; + display: block; + color: inherit; +} + +table, tr, td { + border-collapse: collapse; + border-spacing: 0; +} + +svg { + width: 100%; + display: block; +} + +body { + font-size: 1em; + line-height: 1.4em; + font-family: var(--main-typo); + color: var(--primary-color); + background-color: var(--secondary-color); + hyphens: auto; + font-smooth: always; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +hr { + border: 1px solid; + margin: 1em 0; + opacity: 0.8; + color: var(--color-gray-200); +} + +/* Antd reset */ +#root { + .ant-popover { + .ant-popover-inner { + background: transparent; + border-radius: 0; + box-shadow: none; + padding: 0; + } + } + + .ant-dropdown-menu-submenu, + .ant-dropdown-menu, + .ant-menu { + background: transparent; + box-shadow: none; + display: flex; + flex-direction: column; + gap: 4px; + + .ant-menu-item, + .ant-dropdown-menu-item { + padding: 10px; + height: min-content; + width: 100%; + line-height: 12px; + margin: 0; + border-radius: 8px; + } + + .ant-menu-item:not(.ant-menu-item-danger), + .ant-dropdown-menu-item:not(.ant-dropdown-menu-item-danger) { + color: inherit; + + &:hover { + backdrop-filter: brightness(0.6); + } + } + + .ant-menu-item-divider, + .ant-dropdown-menu-item-divider { + backdrop-filter: brightness(0.85); + } + + .ant-dropdown-menu-submenu-title { + color: inherit; + } + } } \ No newline at end of file diff --git a/src/apps/toolbar/styles/variables.css b/src/apps/toolbar/styles/variables.css index d8f69a08..4a6bce03 100644 --- a/src/apps/toolbar/styles/variables.css +++ b/src/apps/toolbar/styles/variables.css @@ -1,7 +1,7 @@ -:root { - --config-height: 30px; - --config-padding-at-side: 14px; - - --config-accent-color: #ff0000; - --config-accent-color-rgb: 255, 0, 0; -} +:root { + --config-height: 30px; + --config-padding-at-side: 14px; + + --config-accent-color: #ff0000; + --config-accent-color-rgb: 255, 0, 0; +} diff --git a/src/apps/update/app.tsx b/src/apps/update/app.tsx index a7e8c6a5..ad237836 100644 --- a/src/apps/update/app.tsx +++ b/src/apps/update/app.tsx @@ -1,43 +1,43 @@ -import { useDarkMode } from '../shared/styles'; -import { UpdateModal } from './update'; -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; -import { check, Update } from '@tauri-apps/plugin-updater'; -import { ConfigProvider, theme } from 'antd'; -import { useEffect, useState } from 'react'; - -export function App() { - const [update, setUpdate] = useState(null); - - const isDarkMode = useDarkMode(); - - useEffect(() => { - const webview = getCurrentWebviewWindow(); - check({}) - .then((update) => { - if (!update) { - webview.close(); - return; - } - webview.show(); - setUpdate(update); - }) - .catch((e) => { - console.error(e); - webview.close(); - }); - }, []); - - if (!update) { - return null; - } - - return ( - - - - ); -} +import { useDarkMode } from '../shared/styles'; +import { UpdateModal } from './update'; +import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; +import { check, Update } from '@tauri-apps/plugin-updater'; +import { ConfigProvider, theme } from 'antd'; +import { useEffect, useState } from 'react'; + +export function App() { + const [update, setUpdate] = useState(null); + + const isDarkMode = useDarkMode(); + + useEffect(() => { + const webview = getCurrentWebviewWindow(); + check({}) + .then((update) => { + if (!update) { + webview.close(); + return; + } + webview.show(); + setUpdate(update); + }) + .catch((e) => { + console.error(e); + webview.close(); + }); + }, []); + + if (!update) { + return null; + } + + return ( + + + + ); +} diff --git a/src/apps/update/i18n/index.ts b/src/apps/update/i18n/index.ts index 5ab49876..37302bac 100644 --- a/src/apps/update/i18n/index.ts +++ b/src/apps/update/i18n/index.ts @@ -1,98 +1,98 @@ -import { Lang } from '../../shared/lang'; -import i18n from 'i18next'; -import yaml from 'js-yaml'; -import { initReactI18next } from 'react-i18next'; - -i18n.use(initReactI18next).init( - { - lng: 'en', - fallbackLng: 'en', - interpolation: { - escapeValue: false, - }, - debug: true, - resources: {}, - }, - undefined, -); - -export async function loadTranslations() { - const translations: Record = { - en: await import('./translations/en.yml'), - es: await import('./translations/es.yml'), - de: await import('./translations/de.yml'), - zh: await import('./translations/zh.yml'), - ko: await import('./translations/ko.yml'), - fr: await import('./translations/fr.yml'), - ar: await import('./translations/ar.yml'), - pt: await import('./translations/pt.yml'), - hi: await import('./translations/hi.yml'), - ru: await import('./translations/ru.yml'), - ja: await import('./translations/ja.yml'), - it: await import('./translations/it.yml'), - nl: await import('./translations/nl.yml'), - tr: await import('./translations/tr.yml'), - pl: await import('./translations/pl.yml'), - uk: await import('./translations/uk.yml'), - id: await import('./translations/id.yml'), - cs: await import('./translations/cs.yml'), - th: await import('./translations/th.yml'), - vi: await import('./translations/vi.yml'), - ms: await import('./translations/ms.yml'), - he: await import('./translations/he.yml'), - ro: await import('./translations/ro.yml'), - el: await import('./translations/el.yml'), - sv: await import('./translations/sv.yml'), - no: await import('./translations/no.yml'), - fi: await import('./translations/fi.yml'), - da: await import('./translations/da.yml'), - hu: await import('./translations/hu.yml'), - lt: await import('./translations/lt.yml'), - bg: await import('./translations/bg.yml'), - sk: await import('./translations/sk.yml'), - hr: await import('./translations/hr.yml'), - lv: await import('./translations/lv.yml'), - et: await import('./translations/et.yml'), - tl: await import('./translations/tl.yml'), - ca: await import('./translations/ca.yml'), - af: await import('./translations/af.yml'), - bn: await import('./translations/bn.yml'), - fa: await import('./translations/fa.yml'), - pa: await import('./translations/pa.yml'), - sw: await import('./translations/sw.yml'), - ta: await import('./translations/ta.yml'), - ur: await import('./translations/ur.yml'), - cy: await import('./translations/cy.yml'), - am: await import('./translations/am.yml'), - hy: await import('./translations/hy.yml'), - az: await import('./translations/az.yml'), - eu: await import('./translations/eu.yml'), - bs: await import('./translations/bs.yml'), - ka: await import('./translations/ka.yml'), - gu: await import('./translations/gu.yml'), - is: await import('./translations/is.yml'), - km: await import('./translations/km.yml'), - ku: await import('./translations/ku.yml'), - lo: await import('./translations/lo.yml'), - lb: await import('./translations/lb.yml'), - mk: await import('./translations/mk.yml'), - mt: await import('./translations/mt.yml'), - mn: await import('./translations/mn.yml'), - ne: await import('./translations/ne.yml'), - ps: await import('./translations/ps.yml'), - sr: await import('./translations/sr.yml'), - si: await import('./translations/si.yml'), - so: await import('./translations/so.yml'), - tg: await import('./translations/tg.yml'), - te: await import('./translations/te.yml'), - uz: await import('./translations/uz.yml'), - yo: await import('./translations/yo.yml'), - zu: await import('./translations/zu.yml'), - }; - - for (const [key, value] of Object.entries(translations)) { - i18n.addResourceBundle(key, 'translation', yaml.load(value.default)); - } -} - -export default i18n; +import { Lang } from '../../shared/lang'; +import i18n from 'i18next'; +import yaml from 'js-yaml'; +import { initReactI18next } from 'react-i18next'; + +i18n.use(initReactI18next).init( + { + lng: 'en', + fallbackLng: 'en', + interpolation: { + escapeValue: false, + }, + debug: true, + resources: {}, + }, + undefined, +); + +export async function loadTranslations() { + const translations: Record = { + en: await import('./translations/en.yml'), + es: await import('./translations/es.yml'), + de: await import('./translations/de.yml'), + zh: await import('./translations/zh.yml'), + ko: await import('./translations/ko.yml'), + fr: await import('./translations/fr.yml'), + ar: await import('./translations/ar.yml'), + pt: await import('./translations/pt.yml'), + hi: await import('./translations/hi.yml'), + ru: await import('./translations/ru.yml'), + ja: await import('./translations/ja.yml'), + it: await import('./translations/it.yml'), + nl: await import('./translations/nl.yml'), + tr: await import('./translations/tr.yml'), + pl: await import('./translations/pl.yml'), + uk: await import('./translations/uk.yml'), + id: await import('./translations/id.yml'), + cs: await import('./translations/cs.yml'), + th: await import('./translations/th.yml'), + vi: await import('./translations/vi.yml'), + ms: await import('./translations/ms.yml'), + he: await import('./translations/he.yml'), + ro: await import('./translations/ro.yml'), + el: await import('./translations/el.yml'), + sv: await import('./translations/sv.yml'), + no: await import('./translations/no.yml'), + fi: await import('./translations/fi.yml'), + da: await import('./translations/da.yml'), + hu: await import('./translations/hu.yml'), + lt: await import('./translations/lt.yml'), + bg: await import('./translations/bg.yml'), + sk: await import('./translations/sk.yml'), + hr: await import('./translations/hr.yml'), + lv: await import('./translations/lv.yml'), + et: await import('./translations/et.yml'), + tl: await import('./translations/tl.yml'), + ca: await import('./translations/ca.yml'), + af: await import('./translations/af.yml'), + bn: await import('./translations/bn.yml'), + fa: await import('./translations/fa.yml'), + pa: await import('./translations/pa.yml'), + sw: await import('./translations/sw.yml'), + ta: await import('./translations/ta.yml'), + ur: await import('./translations/ur.yml'), + cy: await import('./translations/cy.yml'), + am: await import('./translations/am.yml'), + hy: await import('./translations/hy.yml'), + az: await import('./translations/az.yml'), + eu: await import('./translations/eu.yml'), + bs: await import('./translations/bs.yml'), + ka: await import('./translations/ka.yml'), + gu: await import('./translations/gu.yml'), + is: await import('./translations/is.yml'), + km: await import('./translations/km.yml'), + ku: await import('./translations/ku.yml'), + lo: await import('./translations/lo.yml'), + lb: await import('./translations/lb.yml'), + mk: await import('./translations/mk.yml'), + mt: await import('./translations/mt.yml'), + mn: await import('./translations/mn.yml'), + ne: await import('./translations/ne.yml'), + ps: await import('./translations/ps.yml'), + sr: await import('./translations/sr.yml'), + si: await import('./translations/si.yml'), + so: await import('./translations/so.yml'), + tg: await import('./translations/tg.yml'), + te: await import('./translations/te.yml'), + uz: await import('./translations/uz.yml'), + yo: await import('./translations/yo.yml'), + zu: await import('./translations/zu.yml'), + }; + + for (const [key, value] of Object.entries(translations)) { + i18n.addResourceBundle(key, 'translation', yaml.load(value.default)); + } +} + +export default i18n; diff --git a/src/apps/update/i18n/translations/af.yml b/src/apps/update/i18n/translations/af.yml index 1ce99c46..dc7061d5 100644 --- a/src/apps/update/i18n/translations/af.yml +++ b/src/apps/update/i18n/translations/af.yml @@ -1,12 +1,12 @@ -update: - title: Opdatering beskikbaar! - date: Datum - version: Weergawe - downloading: Laai tans af... - cancel: Later - installing: Installeer tans … - page: GitHub-vrystellingbladsy - download: Dateer op en installeer - extra_info: >- - Om die volledige veranderingslog te lees, besoek asseblief die - veranderingslogbladsy +update: + title: Opdatering beskikbaar! + date: Datum + version: Weergawe + downloading: Laai tans af... + cancel: Later + installing: Installeer tans … + page: GitHub-vrystellingbladsy + download: Dateer op en installeer + extra_info: >- + Om die volledige veranderingslog te lees, besoek asseblief die + veranderingslogbladsy diff --git a/src/apps/update/i18n/translations/am.yml b/src/apps/update/i18n/translations/am.yml index a630a537..0bea7800 100644 --- a/src/apps/update/i18n/translations/am.yml +++ b/src/apps/update/i18n/translations/am.yml @@ -1,10 +1,10 @@ -update: - page: GitHub የሚለቀቅበት ገጽ - installing: በመጫን ላይ... - extra_info: ሙሉውን የለውጥ ማስታወሻ ለማንበብ፣ እባክዎን የለውጥ መዝገብ ገጹን ይጎብኙ - title: ማዘመን አለ! - download: አዘምን እና ጫን - downloading: በማውረድ ላይ... - date: ቀን - cancel: በኋላ - version: ሥሪት +update: + page: GitHub የሚለቀቅበት ገጽ + installing: በመጫን ላይ... + extra_info: ሙሉውን የለውጥ ማስታወሻ ለማንበብ፣ እባክዎን የለውጥ መዝገብ ገጹን ይጎብኙ + title: ማዘመን አለ! + download: አዘምን እና ጫን + downloading: በማውረድ ላይ... + date: ቀን + cancel: በኋላ + version: ሥሪት diff --git a/src/apps/update/i18n/translations/ar.yml b/src/apps/update/i18n/translations/ar.yml index a5a0b8c9..67fa7bcb 100644 --- a/src/apps/update/i18n/translations/ar.yml +++ b/src/apps/update/i18n/translations/ar.yml @@ -1,10 +1,10 @@ -update: - title: التحديث متاح! - date: تاريخ - version: إصدار - extra_info: لقراءة سجل التغيير الكامل، يرجى زيارة صفحة سجل التغيير - page: صفحة إصدار جيثب - cancel: لاحقاً - download: تحديث - downloading: جارى التحميل... - installing: جارٍ التثبيت... +update: + title: التحديث متاح! + date: تاريخ + version: إصدار + extra_info: لقراءة سجل التغيير الكامل، يرجى زيارة صفحة سجل التغيير + page: صفحة إصدار جيثب + cancel: لاحقاً + download: تحديث + downloading: جارى التحميل... + installing: جارٍ التثبيت... diff --git a/src/apps/update/i18n/translations/az.yml b/src/apps/update/i18n/translations/az.yml index dd0d2550..c4f299b1 100644 --- a/src/apps/update/i18n/translations/az.yml +++ b/src/apps/update/i18n/translations/az.yml @@ -1,12 +1,12 @@ -update: - date: Tarix - cancel: Daha sonra - page: GitHub Buraxılış Səhifəsi - title: Yeniləmə əlçatandır! - download: Yeniləyin və Quraşdırın - installing: Quraşdırılır... - downloading: Endirilir... - extra_info: >- - Tam dəyişiklik jurnalını oxumaq üçün lütfən dəyişiklik jurnalı səhifəsinə - daxil olun - version: Versiya +update: + date: Tarix + cancel: Daha sonra + page: GitHub Buraxılış Səhifəsi + title: Yeniləmə əlçatandır! + download: Yeniləyin və Quraşdırın + installing: Quraşdırılır... + downloading: Endirilir... + extra_info: >- + Tam dəyişiklik jurnalını oxumaq üçün lütfən dəyişiklik jurnalı səhifəsinə + daxil olun + version: Versiya diff --git a/src/apps/update/i18n/translations/bg.yml b/src/apps/update/i18n/translations/bg.yml index b16c4928..7c4079aa 100644 --- a/src/apps/update/i18n/translations/bg.yml +++ b/src/apps/update/i18n/translations/bg.yml @@ -1,10 +1,10 @@ -update: - version: Версия - cancel: По късно - date: Дата - extra_info: За да прочетете пълния Changelog, моля, посетете страницата на Changelog - download: Актуализирайте и инсталирайте - installing: Инсталиране ... - downloading: Изтегляне ... - title: Налична актуализация! - page: Страница за освобождаване на GitHub +update: + version: Версия + cancel: По късно + date: Дата + extra_info: За да прочетете пълния Changelog, моля, посетете страницата на Changelog + download: Актуализирайте и инсталирайте + installing: Инсталиране ... + downloading: Изтегляне ... + title: Налична актуализация! + page: Страница за освобождаване на GitHub diff --git a/src/apps/update/i18n/translations/bn.yml b/src/apps/update/i18n/translations/bn.yml index c680a161..b6f63b5b 100644 --- a/src/apps/update/i18n/translations/bn.yml +++ b/src/apps/update/i18n/translations/bn.yml @@ -1,10 +1,10 @@ -update: - date: তারিখ - version: সংস্করণ - cancel: পরে - installing: ইনস্টল করা হচ্ছে... - downloading: ডাউনলোড হচ্ছে... - title: আপডেট উপলব্ধ! - download: আপডেট এবং ইনস্টল করুন - page: গিটহাব রিলিজ পৃষ্ঠা - extra_info: সম্পূর্ণ চেঞ্জলগ পড়তে, অনুগ্রহ করে চেঞ্জলগ পৃষ্ঠায় যান +update: + date: তারিখ + version: সংস্করণ + cancel: পরে + installing: ইনস্টল করা হচ্ছে... + downloading: ডাউনলোড হচ্ছে... + title: আপডেট উপলব্ধ! + download: আপডেট এবং ইনস্টল করুন + page: গিটহাব রিলিজ পৃষ্ঠা + extra_info: সম্পূর্ণ চেঞ্জলগ পড়তে, অনুগ্রহ করে চেঞ্জলগ পৃষ্ঠায় যান diff --git a/src/apps/update/i18n/translations/bs.yml b/src/apps/update/i18n/translations/bs.yml index 225676a2..8ed92402 100644 --- a/src/apps/update/i18n/translations/bs.yml +++ b/src/apps/update/i18n/translations/bs.yml @@ -1,10 +1,10 @@ -update: - cancel: Kasnije - date: Datum - version: Verzija - page: Stranica izdanja GitHub-a - downloading: Preuzimanje... - download: Ažurirajte i instalirajte - installing: Instaliranje... - extra_info: Da pročitate cijeli dnevnik promjena, posjetite stranicu dnevnika promjena - title: Dostupno je ažuriranje! +update: + cancel: Kasnije + date: Datum + version: Verzija + page: Stranica izdanja GitHub-a + downloading: Preuzimanje... + download: Ažurirajte i instalirajte + installing: Instaliranje... + extra_info: Da pročitate cijeli dnevnik promjena, posjetite stranicu dnevnika promjena + title: Dostupno je ažuriranje! diff --git a/src/apps/update/i18n/translations/ca.yml b/src/apps/update/i18n/translations/ca.yml index 3d657544..500a8dc2 100644 --- a/src/apps/update/i18n/translations/ca.yml +++ b/src/apps/update/i18n/translations/ca.yml @@ -1,10 +1,10 @@ -update: - title: Actualització disponible! - version: Versió - date: Data - page: Pàgina de llançament de GitHub - download: Actualitzar i instal·lar - downloading: Descarregant ... - installing: Instal·lació ... - extra_info: Per llegir el canvi complet, visiteu la pàgina de Changelog - cancel: Més tard +update: + title: Actualització disponible! + version: Versió + date: Data + page: Pàgina de llançament de GitHub + download: Actualitzar i instal·lar + downloading: Descarregant ... + installing: Instal·lació ... + extra_info: Per llegir el canvi complet, visiteu la pàgina de Changelog + cancel: Més tard diff --git a/src/apps/update/i18n/translations/cs.yml b/src/apps/update/i18n/translations/cs.yml index c39ecc1f..eeea16a9 100644 --- a/src/apps/update/i18n/translations/cs.yml +++ b/src/apps/update/i18n/translations/cs.yml @@ -1,10 +1,10 @@ -update: - title: Aktualizace k dispozici! - date: Datum - version: Verze - extra_info: Pro přečtení úplného seznamu změn navštivte stránku změn - page: Stránka vydání na GitHubu - cancel: Později - download: Aktualizovat a nainstalovat - downloading: Stahování... - installing: Instalace... +update: + title: Aktualizace k dispozici! + date: Datum + version: Verze + extra_info: Pro přečtení úplného seznamu změn navštivte stránku změn + page: Stránka vydání na GitHubu + cancel: Později + download: Aktualizovat a nainstalovat + downloading: Stahování... + installing: Instalace... diff --git a/src/apps/update/i18n/translations/cy.yml b/src/apps/update/i18n/translations/cy.yml index ee1fd808..bf97bad1 100644 --- a/src/apps/update/i18n/translations/cy.yml +++ b/src/apps/update/i18n/translations/cy.yml @@ -1,10 +1,10 @@ -update: - date: Dyddiad - cancel: Yn ddiweddarach - version: Fersiwn - download: Diweddaru a Gosod - title: Diweddariad ar gael! - page: Tudalen Rhyddhau GitHub - installing: Wrthi'n gosod... - downloading: Wrthi'n llwytho i lawr... - extra_info: I ddarllen y changelog llawn, ewch i'r dudalen changelog +update: + date: Dyddiad + cancel: Yn ddiweddarach + version: Fersiwn + download: Diweddaru a Gosod + title: Diweddariad ar gael! + page: Tudalen Rhyddhau GitHub + installing: Wrthi'n gosod... + downloading: Wrthi'n llwytho i lawr... + extra_info: I ddarllen y changelog llawn, ewch i'r dudalen changelog diff --git a/src/apps/update/i18n/translations/da.yml b/src/apps/update/i18n/translations/da.yml index aa7c253a..19f73e7e 100644 --- a/src/apps/update/i18n/translations/da.yml +++ b/src/apps/update/i18n/translations/da.yml @@ -1,10 +1,10 @@ -update: - title: Opdatering tilgængelig! - date: Dato - version: Version - extra_info: For at læse den fulde ændringslog, besøg venligst ændringslog-siden - page: GitHub-udgivelsesside - cancel: Senere - download: Opdater & installer - downloading: Downloader... - installing: Installerer... +update: + title: Opdatering tilgængelig! + date: Dato + version: Version + extra_info: For at læse den fulde ændringslog, besøg venligst ændringslog-siden + page: GitHub-udgivelsesside + cancel: Senere + download: Opdater & installer + downloading: Downloader... + installing: Installerer... diff --git a/src/apps/update/i18n/translations/de.yml b/src/apps/update/i18n/translations/de.yml index 40aa7e70..eea6ae1e 100644 --- a/src/apps/update/i18n/translations/de.yml +++ b/src/apps/update/i18n/translations/de.yml @@ -1,12 +1,12 @@ -update: - title: Update verfügbar! - date: Datum - version: Version - extra_info: >- - Um das vollständige Änderungsprotokoll zu lesen, besuchen Sie bitte die - Änderungsprotokollseite - page: GitHub-Veröffentlichungsseite - cancel: Später - download: Aktualisieren & installieren - downloading: Herunterladen... - installing: Installieren... +update: + title: Update verfügbar! + date: Datum + version: Version + extra_info: >- + Um das vollständige Änderungsprotokoll zu lesen, besuchen Sie bitte die + Änderungsprotokollseite + page: GitHub-Veröffentlichungsseite + cancel: Später + download: Aktualisieren & installieren + downloading: Herunterladen... + installing: Installieren... diff --git a/src/apps/update/i18n/translations/el.yml b/src/apps/update/i18n/translations/el.yml index ab96179d..959825b1 100644 --- a/src/apps/update/i18n/translations/el.yml +++ b/src/apps/update/i18n/translations/el.yml @@ -1,10 +1,10 @@ -update: - date: Ημερομηνία - cancel: Αργότερα - version: Εκδοχή - title: Διαθέσιμη ενημέρωση! - download: Ενημέρωση και εγκατάσταση - extra_info: Για να διαβάσετε το πλήρες Changelog, επισκεφθείτε τη σελίδα Changelog - downloading: Λήψη ... - page: Σελίδα απελευθέρωσης GitHub - installing: Εγκατάσταση ... +update: + date: Ημερομηνία + cancel: Αργότερα + version: Εκδοχή + title: Διαθέσιμη ενημέρωση! + download: Ενημέρωση και εγκατάσταση + extra_info: Για να διαβάσετε το πλήρες Changelog, επισκεφθείτε τη σελίδα Changelog + downloading: Λήψη ... + page: Σελίδα απελευθέρωσης GitHub + installing: Εγκατάσταση ... diff --git a/src/apps/update/i18n/translations/en.yml b/src/apps/update/i18n/translations/en.yml index 117474d5..ff9df8c7 100644 --- a/src/apps/update/i18n/translations/en.yml +++ b/src/apps/update/i18n/translations/en.yml @@ -1,10 +1,10 @@ -update: - title: Update available! - date: Date - version: Version - extra_info: To read the full changelog, please visit the changelog page - page: GitHub Release Page - cancel: Later - download: Update & Install - downloading: Downloading... - installing: Installing... +update: + title: Update available! + date: Date + version: Version + extra_info: To read the full changelog, please visit the changelog page + page: GitHub Release Page + cancel: Later + download: Update & Install + downloading: Downloading... + installing: Installing... diff --git a/src/apps/update/i18n/translations/es.yml b/src/apps/update/i18n/translations/es.yml index 5472ed54..52ddb013 100644 --- a/src/apps/update/i18n/translations/es.yml +++ b/src/apps/update/i18n/translations/es.yml @@ -1,12 +1,12 @@ -update: - title: ¡Actualización disponible! - date: Fecha - version: Versión - extra_info: >- - Para leer el registro completo de cambios, por favor visita la página del - registro de cambios - page: Página de lanzamientos en GitHub - cancel: Más tarde - download: Actualizar e instalar - downloading: Descargando... - installing: Instalando... +update: + title: ¡Actualización disponible! + date: Fecha + version: Versión + extra_info: >- + Para leer el registro completo de cambios, por favor visita la página del + registro de cambios + page: Página de lanzamientos en GitHub + cancel: Más tarde + download: Actualizar e instalar + downloading: Descargando... + installing: Instalando... diff --git a/src/apps/update/i18n/translations/et.yml b/src/apps/update/i18n/translations/et.yml index 8f3287c6..7cba12f1 100644 --- a/src/apps/update/i18n/translations/et.yml +++ b/src/apps/update/i18n/translations/et.yml @@ -1,10 +1,10 @@ -update: - title: Uuendus saadaval! - date: Kuupäev - version: Versioon - extra_info: Täieliku muutuste logi lugemiseks külastage palun muutuste lehte - page: GitHubi väljaannete leht - cancel: Hiljem - download: Uuenda ja installi - downloading: Allalaadimine... - installing: Installimine... +update: + title: Uuendus saadaval! + date: Kuupäev + version: Versioon + extra_info: Täieliku muutuste logi lugemiseks külastage palun muutuste lehte + page: GitHubi väljaannete leht + cancel: Hiljem + download: Uuenda ja installi + downloading: Allalaadimine... + installing: Installimine... diff --git a/src/apps/update/i18n/translations/eu.yml b/src/apps/update/i18n/translations/eu.yml index 07614561..2a8ad40d 100644 --- a/src/apps/update/i18n/translations/eu.yml +++ b/src/apps/update/i18n/translations/eu.yml @@ -1,12 +1,12 @@ -update: - downloading: Deskargatzen... - cancel: Beranduago - date: Data - version: Bertsioa - page: GitHub bertsioaren orria - title: Eguneratzea eskuragarri! - download: Eguneratu eta instalatu - installing: Instalatzen... - extra_info: >- - Aldaketa-erregistro osoa irakurtzeko, mesedez bisitatu aldaketa-erregistroa - orria +update: + downloading: Deskargatzen... + cancel: Beranduago + date: Data + version: Bertsioa + page: GitHub bertsioaren orria + title: Eguneratzea eskuragarri! + download: Eguneratu eta instalatu + installing: Instalatzen... + extra_info: >- + Aldaketa-erregistro osoa irakurtzeko, mesedez bisitatu aldaketa-erregistroa + orria diff --git a/src/apps/update/i18n/translations/fa.yml b/src/apps/update/i18n/translations/fa.yml index 2ecc7eff..5d9f5814 100644 --- a/src/apps/update/i18n/translations/fa.yml +++ b/src/apps/update/i18n/translations/fa.yml @@ -1,10 +1,10 @@ -update: - title: به روز رسانی در دسترس است! - downloading: در حال دانلود... - version: نسخه - installing: در حال نصب... - cancel: بعد - date: تاریخ - page: صفحه انتشار GitHub - download: به روز رسانی و نصب - extra_info: برای مطالعه تغییرات کامل، لطفاً به صفحه تغییرات وارد شوید +update: + title: به روز رسانی در دسترس است! + downloading: در حال دانلود... + version: نسخه + installing: در حال نصب... + cancel: بعد + date: تاریخ + page: صفحه انتشار GitHub + download: به روز رسانی و نصب + extra_info: برای مطالعه تغییرات کامل، لطفاً به صفحه تغییرات وارد شوید diff --git a/src/apps/update/i18n/translations/fi.yml b/src/apps/update/i18n/translations/fi.yml index 4063742a..72a2818d 100644 --- a/src/apps/update/i18n/translations/fi.yml +++ b/src/apps/update/i18n/translations/fi.yml @@ -1,10 +1,10 @@ -update: - version: Versio - cancel: Myöhemmin - title: Päivitys saatavilla! - date: Päivämäärä - download: Päivitä ja asenna - extra_info: Jos haluat lukea koko muutoslogin, käy ChangeLog -sivulla - downloading: Lataaminen ... - installing: Asentaminen ... - page: GitHub -julkaisusivu +update: + version: Versio + cancel: Myöhemmin + title: Päivitys saatavilla! + date: Päivämäärä + download: Päivitä ja asenna + extra_info: Jos haluat lukea koko muutoslogin, käy ChangeLog -sivulla + downloading: Lataaminen ... + installing: Asentaminen ... + page: GitHub -julkaisusivu diff --git a/src/apps/update/i18n/translations/fr.yml b/src/apps/update/i18n/translations/fr.yml index 4fba3c30..f91ee973 100644 --- a/src/apps/update/i18n/translations/fr.yml +++ b/src/apps/update/i18n/translations/fr.yml @@ -1,12 +1,12 @@ -update: - title: Mise à jour disponible! - date: Date - version: Version - extra_info: >- - Pour lire le journal des modifications complet, veuillez visiter la page du - journal des modifications - page: Page de publication de GitHub - cancel: Plus tard - download: Mise à jour - downloading: Téléchargement... - installing: Installation... +update: + title: Mise à jour disponible! + date: Date + version: Version + extra_info: >- + Pour lire le journal des modifications complet, veuillez visiter la page du + journal des modifications + page: Page de publication de GitHub + cancel: Plus tard + download: Mise à jour + downloading: Téléchargement... + installing: Installation... diff --git a/src/apps/update/i18n/translations/gu.yml b/src/apps/update/i18n/translations/gu.yml index d8942dc4..f8fffd66 100644 --- a/src/apps/update/i18n/translations/gu.yml +++ b/src/apps/update/i18n/translations/gu.yml @@ -1,10 +1,10 @@ -update: - date: તારીખ - version: સંસ્કરણ - cancel: બાદમાં - extra_info: સંપૂર્ણ ચેન્જલોગ વાંચવા માટે, કૃપા કરીને ચેન્જલોગ પૃષ્ઠની મુલાકાત લો - installing: ઇન્સ્ટોલ કરી રહ્યું છે... - title: અપડેટ ઉપલબ્ધ છે! - downloading: ડાઉનલોડ કરી રહ્યું છે... - page: GitHub પ્રકાશન પૃષ્ઠ - download: અપડેટ અને ઇન્સ્ટોલ કરો +update: + date: તારીખ + version: સંસ્કરણ + cancel: બાદમાં + extra_info: સંપૂર્ણ ચેન્જલોગ વાંચવા માટે, કૃપા કરીને ચેન્જલોગ પૃષ્ઠની મુલાકાત લો + installing: ઇન્સ્ટોલ કરી રહ્યું છે... + title: અપડેટ ઉપલબ્ધ છે! + downloading: ડાઉનલોડ કરી રહ્યું છે... + page: GitHub પ્રકાશન પૃષ્ઠ + download: અપડેટ અને ઇન્સ્ટોલ કરો diff --git a/src/apps/update/i18n/translations/he.yml b/src/apps/update/i18n/translations/he.yml index c57196b9..7ba76e56 100644 --- a/src/apps/update/i18n/translations/he.yml +++ b/src/apps/update/i18n/translations/he.yml @@ -1,10 +1,10 @@ -update: - cancel: יותר מאוחר - title: עדכון זמין! - version: גִרְסָה - date: תַאֲרִיך - downloading: מוריד ... - extra_info: לקריאת ה- ChangeLog המלאה, בקרו בדף ChangeLog - download: עדכן והתקנה - page: דף שחרור GitHub - installing: התקנה ... +update: + cancel: יותר מאוחר + title: עדכון זמין! + version: גִרְסָה + date: תַאֲרִיך + downloading: מוריד ... + extra_info: לקריאת ה- ChangeLog המלאה, בקרו בדף ChangeLog + download: עדכן והתקנה + page: דף שחרור GitHub + installing: התקנה ... diff --git a/src/apps/update/i18n/translations/hi.yml b/src/apps/update/i18n/translations/hi.yml index 220dd479..2151b221 100644 --- a/src/apps/update/i18n/translations/hi.yml +++ b/src/apps/update/i18n/translations/hi.yml @@ -1,10 +1,10 @@ -update: - downloading: डाउनलोड करना ... - extra_info: पूर्ण चांगेलॉग पढ़ने के लिए, कृपया चांगलोग पेज पर जाएं - cancel: बाद में - page: Github रिलीज पेज - installing: स्थापित करना ... - version: संस्करण - title: उपलब्ध अद्यतन! - date: तारीख - download: अद्यतन और स्थापित करें +update: + downloading: डाउनलोड करना ... + extra_info: पूर्ण चांगेलॉग पढ़ने के लिए, कृपया चांगलोग पेज पर जाएं + cancel: बाद में + page: Github रिलीज पेज + installing: स्थापित करना ... + version: संस्करण + title: उपलब्ध अद्यतन! + date: तारीख + download: अद्यतन और स्थापित करें diff --git a/src/apps/update/i18n/translations/hr.yml b/src/apps/update/i18n/translations/hr.yml index acdae16b..0ad5d354 100644 --- a/src/apps/update/i18n/translations/hr.yml +++ b/src/apps/update/i18n/translations/hr.yml @@ -1,10 +1,10 @@ -update: - version: Verzija - cancel: Kasnije - date: Datum - title: Ažuriranje dostupno! - download: Ažurirajte i instalirajte - installing: Instaliranje ... - downloading: Preuzimanje ... - page: GitHub stranica za izdanje - extra_info: Da biste pročitali cijeli Changelog, posjetite stranicu ChangeLog +update: + version: Verzija + cancel: Kasnije + date: Datum + title: Ažuriranje dostupno! + download: Ažurirajte i instalirajte + installing: Instaliranje ... + downloading: Preuzimanje ... + page: GitHub stranica za izdanje + extra_info: Da biste pročitali cijeli Changelog, posjetite stranicu ChangeLog diff --git a/src/apps/update/i18n/translations/hu.yml b/src/apps/update/i18n/translations/hu.yml index 02478acb..f1fb835b 100644 --- a/src/apps/update/i18n/translations/hu.yml +++ b/src/apps/update/i18n/translations/hu.yml @@ -1,12 +1,12 @@ -update: - version: Változat - cancel: A későbbiekben - title: Frissítés elérhető! - date: Dátum - extra_info: >- - A teljes változási mód elolvasásához kérjük, látogasson el a ChangeLog - oldalra - installing: Telepítés ... - downloading: Letöltés ... - download: Frissítés és telepítés - page: GitHub kiadási oldal +update: + version: Változat + cancel: A későbbiekben + title: Frissítés elérhető! + date: Dátum + extra_info: >- + A teljes változási mód elolvasásához kérjük, látogasson el a ChangeLog + oldalra + installing: Telepítés ... + downloading: Letöltés ... + download: Frissítés és telepítés + page: GitHub kiadási oldal diff --git a/src/apps/update/i18n/translations/hy.yml b/src/apps/update/i18n/translations/hy.yml index feaf4f06..80eecdc3 100644 --- a/src/apps/update/i18n/translations/hy.yml +++ b/src/apps/update/i18n/translations/hy.yml @@ -1,12 +1,12 @@ -update: - cancel: Ավելի ուշ - version: Տարբերակ - date: Ամսաթիվ - downloading: Ներբեռնվում է... - title: 'Թարմացումը հասանելի է:' - installing: Տեղադրվում է... - download: Թարմացնել և տեղադրել - page: GitHub-ի թողարկման էջ - extra_info: >- - Փոփոխությունների ամբողջական տեղեկագիրը կարդալու համար այցելեք փոփոխության - մատյան էջ +update: + cancel: Ավելի ուշ + version: Տարբերակ + date: Ամսաթիվ + downloading: Ներբեռնվում է... + title: 'Թարմացումը հասանելի է:' + installing: Տեղադրվում է... + download: Թարմացնել և տեղադրել + page: GitHub-ի թողարկման էջ + extra_info: >- + Փոփոխությունների ամբողջական տեղեկագիրը կարդալու համար այցելեք փոփոխության + մատյան էջ diff --git a/src/apps/update/i18n/translations/id.yml b/src/apps/update/i18n/translations/id.yml index 53865cfc..70a5a020 100644 --- a/src/apps/update/i18n/translations/id.yml +++ b/src/apps/update/i18n/translations/id.yml @@ -1,10 +1,10 @@ -update: - title: Pembaruan tersedia! - version: 'Versi: kapan' - date: Tanggal - cancel: Nanti - downloading: Mengunduh ... - download: Perbarui & Instal - extra_info: Untuk membaca changelog lengkap, silakan kunjungi halaman Changelog - installing: Menginstal ... - page: Halaman rilis GitHub +update: + title: Pembaruan tersedia! + version: 'Versi: kapan' + date: Tanggal + cancel: Nanti + downloading: Mengunduh ... + download: Perbarui & Instal + extra_info: Untuk membaca changelog lengkap, silakan kunjungi halaman Changelog + installing: Menginstal ... + page: Halaman rilis GitHub diff --git a/src/apps/update/i18n/translations/is.yml b/src/apps/update/i18n/translations/is.yml index 6ba5a68f..1f9e4c93 100644 --- a/src/apps/update/i18n/translations/is.yml +++ b/src/apps/update/i18n/translations/is.yml @@ -1,10 +1,10 @@ -update: - cancel: Seinna - installing: Setur upp... - title: Uppfærsla í boði! - date: Dagsetning - version: Útgáfa - download: Uppfærðu og settu upp - downloading: Sækir... - page: GitHub útgáfusíða - extra_info: Til að lesa breytingaskrána í heild sinni skaltu fara á breytingaskrársíðuna +update: + cancel: Seinna + installing: Setur upp... + title: Uppfærsla í boði! + date: Dagsetning + version: Útgáfa + download: Uppfærðu og settu upp + downloading: Sækir... + page: GitHub útgáfusíða + extra_info: Til að lesa breytingaskrána í heild sinni skaltu fara á breytingaskrársíðuna diff --git a/src/apps/update/i18n/translations/it.yml b/src/apps/update/i18n/translations/it.yml index 6bcc5ed2..01d13ecb 100644 --- a/src/apps/update/i18n/translations/it.yml +++ b/src/apps/update/i18n/translations/it.yml @@ -1,10 +1,10 @@ -update: - cancel: Dopo - version: Versione - title: Aggiornamento disponibile! - date: Data - extra_info: Per leggere l'intero Changelog, visitare la pagina Changelog - downloading: Download ... - page: Pagina di rilascio di GitHub - download: Aggiornamento e installazione - installing: Installazione ... +update: + cancel: Dopo + version: Versione + title: Aggiornamento disponibile! + date: Data + extra_info: Per leggere l'intero Changelog, visitare la pagina Changelog + downloading: Download ... + page: Pagina di rilascio di GitHub + download: Aggiornamento e installazione + installing: Installazione ... diff --git a/src/apps/update/i18n/translations/ja.yml b/src/apps/update/i18n/translations/ja.yml index 254ce003..000725d5 100644 --- a/src/apps/update/i18n/translations/ja.yml +++ b/src/apps/update/i18n/translations/ja.yml @@ -1,10 +1,10 @@ -update: - cancel: キャンセル - version: バージョン - date: 日付 - title: 更新が利用可能です! - page: GitHubリリースページ - installing: インストール中... - extra_info: 完全なChangelogを読むには、Changelogページにアクセスしてください - download: ダウンロード - downloading: ダウンロード中... +update: + cancel: キャンセル + version: バージョン + date: 日付 + title: 更新が利用可能です! + page: GitHubリリースページ + installing: インストール中... + extra_info: 完全なChangelogを読むには、Changelogページにアクセスしてください + download: ダウンロード + downloading: ダウンロード中... diff --git a/src/apps/update/i18n/translations/ka.yml b/src/apps/update/i18n/translations/ka.yml index a307c545..8b30a12a 100644 --- a/src/apps/update/i18n/translations/ka.yml +++ b/src/apps/update/i18n/translations/ka.yml @@ -1,12 +1,12 @@ -update: - downloading: მიმდინარეობს ჩამოტვირთვა... - title: Განახლება შესაძლებელია! - cancel: მოგვიანებით - installing: მიმდინარეობს ინსტალაცია... - date: თარიღი - version: ვერსია - extra_info: >- - ცვლილებების სრული ჟურნალის წასაკითხად, გთხოვთ, ეწვიოთ ცვლილებების ჟურნალის - გვერდს - download: განახლება და ინსტალაცია - page: GitHub გამოშვების გვერდი +update: + downloading: მიმდინარეობს ჩამოტვირთვა... + title: Განახლება შესაძლებელია! + cancel: მოგვიანებით + installing: მიმდინარეობს ინსტალაცია... + date: თარიღი + version: ვერსია + extra_info: >- + ცვლილებების სრული ჟურნალის წასაკითხად, გთხოვთ, ეწვიოთ ცვლილებების ჟურნალის + გვერდს + download: განახლება და ინსტალაცია + page: GitHub გამოშვების გვერდი diff --git a/src/apps/update/i18n/translations/km.yml b/src/apps/update/i18n/translations/km.yml index 077ff46c..f0656962 100644 --- a/src/apps/update/i18n/translations/km.yml +++ b/src/apps/update/i18n/translations/km.yml @@ -1,10 +1,10 @@ -update: - downloading: កំពុងទាញយក... - date: កាលបរិច្ឆេទ - cancel: ពេលក្រោយ - version: កំណែ - title: អាប់ដេតមានហើយ! - page: ទំព័រចេញផ្សាយ GitHub - download: ធ្វើបច្ចុប្បន្នភាព និងដំឡើង - extra_info: ដើម្បីអានកំណត់ហេតុផ្លាស់ប្តូរពេញលេញ សូមចូលទៅកាន់ទំព័រផ្លាស់ប្តូរកំណត់ហេតុ - installing: កំពុងដំឡើង... +update: + downloading: កំពុងទាញយក... + date: កាលបរិច្ឆេទ + cancel: ពេលក្រោយ + version: កំណែ + title: អាប់ដេតមានហើយ! + page: ទំព័រចេញផ្សាយ GitHub + download: ធ្វើបច្ចុប្បន្នភាព និងដំឡើង + extra_info: ដើម្បីអានកំណត់ហេតុផ្លាស់ប្តូរពេញលេញ សូមចូលទៅកាន់ទំព័រផ្លាស់ប្តូរកំណត់ហេតុ + installing: កំពុងដំឡើង... diff --git a/src/apps/update/i18n/translations/ko.yml b/src/apps/update/i18n/translations/ko.yml index f7406beb..47a2d3fc 100644 --- a/src/apps/update/i18n/translations/ko.yml +++ b/src/apps/update/i18n/translations/ko.yml @@ -1,10 +1,10 @@ -update: - title: 업데이트가 있습니다! - date: 날짜 - version: 버전 - extra_info: 전체 변경 로그를 읽으려면 변경 로그 페이지를 방문하세요 - page: GitHub 릴리스 페이지 - cancel: 나중에 - download: 업데이트 및 설치 - downloading: 다운로드 중... - installing: 설치 중... +update: + title: 업데이트가 있습니다! + date: 날짜 + version: 버전 + extra_info: 전체 변경 로그를 읽으려면 변경 로그 페이지를 방문하세요 + page: GitHub 릴리스 페이지 + cancel: 나중에 + download: 업데이트 및 설치 + downloading: 다운로드 중... + installing: 설치 중... diff --git a/src/apps/update/i18n/translations/ku.yml b/src/apps/update/i18n/translations/ku.yml index c4c4de11..635a90a0 100644 --- a/src/apps/update/i18n/translations/ku.yml +++ b/src/apps/update/i18n/translations/ku.yml @@ -1,10 +1,10 @@ -update: - date: Rojek - cancel: Paşan - version: Awa - download: Nûvekirin & Sazkirin - extra_info: Ji bo xwendina guhertoya tevahî, ji kerema xwe biçin rûpela guhartinê - title: Nûvekirin heye! - downloading: Daxistin... - installing: Sazkirin... - page: Rûpelê Weşandina GitHub +update: + date: Rojek + cancel: Paşan + version: Awa + download: Nûvekirin & Sazkirin + extra_info: Ji bo xwendina guhertoya tevahî, ji kerema xwe biçin rûpela guhartinê + title: Nûvekirin heye! + downloading: Daxistin... + installing: Sazkirin... + page: Rûpelê Weşandina GitHub diff --git a/src/apps/update/i18n/translations/lb.yml b/src/apps/update/i18n/translations/lb.yml index f07851be..b16e731a 100644 --- a/src/apps/update/i18n/translations/lb.yml +++ b/src/apps/update/i18n/translations/lb.yml @@ -1,10 +1,10 @@ -update: - date: Datum - version: Versioun - cancel: Méi spéit - title: Update verfügbar! - downloading: Eroflueden... - page: GitHub Release Säit - download: Update & Installéieren - extra_info: Fir de komplette Changelog ze liesen, besicht w.e.g. d'changelog Säit - installing: Installéiert ... +update: + date: Datum + version: Versioun + cancel: Méi spéit + title: Update verfügbar! + downloading: Eroflueden... + page: GitHub Release Säit + download: Update & Installéieren + extra_info: Fir de komplette Changelog ze liesen, besicht w.e.g. d'changelog Säit + installing: Installéiert ... diff --git a/src/apps/update/i18n/translations/lo.yml b/src/apps/update/i18n/translations/lo.yml index e51c3749..04cb01ba 100644 --- a/src/apps/update/i18n/translations/lo.yml +++ b/src/apps/update/i18n/translations/lo.yml @@ -1,10 +1,10 @@ -update: - cancel: ຕໍ່ມາ - version: ຮຸ່ນ - date: ວັນທີ - title: ມີອັບເດດແລ້ວ! - downloading: ກຳລັງດາວໂຫຼດ... - download: ອັບເດດ ແລະຕິດຕັ້ງ - page: ຫນ້າປ່ອຍ GitHub - installing: ກຳລັງຕິດຕັ້ງ... - extra_info: ເພື່ອອ່ານບັນທຶກການປ່ຽນແປງເຕັມ, ກະລຸນາເຂົ້າໄປທີ່ໜ້າ changelog +update: + cancel: ຕໍ່ມາ + version: ຮຸ່ນ + date: ວັນທີ + title: ມີອັບເດດແລ້ວ! + downloading: ກຳລັງດາວໂຫຼດ... + download: ອັບເດດ ແລະຕິດຕັ້ງ + page: ຫນ້າປ່ອຍ GitHub + installing: ກຳລັງຕິດຕັ້ງ... + extra_info: ເພື່ອອ່ານບັນທຶກການປ່ຽນແປງເຕັມ, ກະລຸນາເຂົ້າໄປທີ່ໜ້າ changelog diff --git a/src/apps/update/i18n/translations/lt.yml b/src/apps/update/i18n/translations/lt.yml index 3e4fc9c0..3a4c1487 100644 --- a/src/apps/update/i18n/translations/lt.yml +++ b/src/apps/update/i18n/translations/lt.yml @@ -1,10 +1,10 @@ -update: - version: Versija - date: Data - title: Galimas atnaujinimas! - extra_info: Norėdami perskaityti visą „Changelog“, apsilankykite „Changelog“ puslapyje - downloading: Atsisiuntimas ... - cancel: Vėliau - installing: Diegimas ... - page: „GitHub“ išleidimo puslapis - download: Atnaujinkite ir įdiekite +update: + version: Versija + date: Data + title: Galimas atnaujinimas! + extra_info: Norėdami perskaityti visą „Changelog“, apsilankykite „Changelog“ puslapyje + downloading: Atsisiuntimas ... + cancel: Vėliau + installing: Diegimas ... + page: „GitHub“ išleidimo puslapis + download: Atnaujinkite ir įdiekite diff --git a/src/apps/update/i18n/translations/lv.yml b/src/apps/update/i18n/translations/lv.yml index 755c719f..efa73127 100644 --- a/src/apps/update/i18n/translations/lv.yml +++ b/src/apps/update/i18n/translations/lv.yml @@ -1,10 +1,10 @@ -update: - date: Datums - version: Versija - extra_info: Lai izlasītu pilnu maiņu, lūdzu, apmeklējiet vietni Changelog - download: Atjaunināt un instalēt - downloading: Lejupielāde ... - cancel: Vēlāk - title: Pieejams atjauninājums! - installing: Instalēšana ... - page: GitHub izlaišanas lapa +update: + date: Datums + version: Versija + extra_info: Lai izlasītu pilnu maiņu, lūdzu, apmeklējiet vietni Changelog + download: Atjaunināt un instalēt + downloading: Lejupielāde ... + cancel: Vēlāk + title: Pieejams atjauninājums! + installing: Instalēšana ... + page: GitHub izlaišanas lapa diff --git a/src/apps/update/i18n/translations/mk.yml b/src/apps/update/i18n/translations/mk.yml index 75f9badb..d74384ce 100644 --- a/src/apps/update/i18n/translations/mk.yml +++ b/src/apps/update/i18n/translations/mk.yml @@ -1,12 +1,12 @@ -update: - date: Датум - version: Верзија - cancel: Подоцна - extra_info: >- - За да го прочитате целосниот дневник за промени, посетете ја страницата за - дневник на промени - download: Ажурирај и инсталирај - title: Достапно е ажурирање! - downloading: Се презема... - installing: Се инсталира... - page: Страница за издавање на GitHub +update: + date: Датум + version: Верзија + cancel: Подоцна + extra_info: >- + За да го прочитате целосниот дневник за промени, посетете ја страницата за + дневник на промени + download: Ажурирај и инсталирај + title: Достапно е ажурирање! + downloading: Се презема... + installing: Се инсталира... + page: Страница за издавање на GitHub diff --git a/src/apps/update/i18n/translations/mn.yml b/src/apps/update/i18n/translations/mn.yml index 9698e05e..041f5005 100644 --- a/src/apps/update/i18n/translations/mn.yml +++ b/src/apps/update/i18n/translations/mn.yml @@ -1,12 +1,12 @@ -update: - title: Шинэчлэх боломжтой! - version: Хувилбар - cancel: Дараа нь - date: Огноо - extra_info: >- - Өөрчлөлтийн бүртгэлийг бүрэн эхээр нь уншихыг хүсвэл өөрчлөлтийн бүртгэлийн - хуудсанд зочилно уу - installing: Суулгаж байна... - page: GitHub хувилбарын хуудас - downloading: Татаж авч байна... - download: Шинэчлэх & Суулгах +update: + title: Шинэчлэх боломжтой! + version: Хувилбар + cancel: Дараа нь + date: Огноо + extra_info: >- + Өөрчлөлтийн бүртгэлийг бүрэн эхээр нь уншихыг хүсвэл өөрчлөлтийн бүртгэлийн + хуудсанд зочилно уу + installing: Суулгаж байна... + page: GitHub хувилбарын хуудас + downloading: Татаж авч байна... + download: Шинэчлэх & Суулгах diff --git a/src/apps/update/i18n/translations/ms.yml b/src/apps/update/i18n/translations/ms.yml index 1466126f..fdad20e8 100644 --- a/src/apps/update/i18n/translations/ms.yml +++ b/src/apps/update/i18n/translations/ms.yml @@ -1,10 +1,10 @@ -update: - version: Versi - page: Halaman pelepasan GitHub - title: Kemaskini ada! - date: Tarikh - downloading: Memuat turun ... - extra_info: Untuk membaca changelog penuh, sila lawati halaman Changelog - cancel: Kemudian - installing: Memasang ... - download: Kemas kini & Pasang +update: + version: Versi + page: Halaman pelepasan GitHub + title: Kemaskini ada! + date: Tarikh + downloading: Memuat turun ... + extra_info: Untuk membaca changelog penuh, sila lawati halaman Changelog + cancel: Kemudian + installing: Memasang ... + download: Kemas kini & Pasang diff --git a/src/apps/update/i18n/translations/mt.yml b/src/apps/update/i18n/translations/mt.yml index f0f1562d..65ca9f97 100644 --- a/src/apps/update/i18n/translations/mt.yml +++ b/src/apps/update/i18n/translations/mt.yml @@ -1,10 +1,10 @@ -update: - date: Data - cancel: Aktar tard - download: Aġġorna u Installa - title: Aġġornament disponibbli! - page: Paġna ta' Rilaxx ta' GitHub - version: Verżjoni - downloading: Niżżel... - installing: Installazzjoni... - extra_info: Biex taqra l-changelog sħiħ, jekk jogħġbok żur il-paġna changelog +update: + date: Data + cancel: Aktar tard + download: Aġġorna u Installa + title: Aġġornament disponibbli! + page: Paġna ta' Rilaxx ta' GitHub + version: Verżjoni + downloading: Niżżel... + installing: Installazzjoni... + extra_info: Biex taqra l-changelog sħiħ, jekk jogħġbok żur il-paġna changelog diff --git a/src/apps/update/i18n/translations/ne.yml b/src/apps/update/i18n/translations/ne.yml index e58d0232..7fe5175a 100644 --- a/src/apps/update/i18n/translations/ne.yml +++ b/src/apps/update/i18n/translations/ne.yml @@ -1,10 +1,10 @@ -update: - title: अपडेट उपलब्ध छ! - download: अपडेट र स्थापना गर्नुहोस् - date: मिति - cancel: पछि - downloading: डाउनलोड गर्दै... - version: संस्करण - page: GitHub रिलीज पृष्ठ - installing: स्थापना गर्दै... - extra_info: पूरा चेन्जलग पढ्नको लागि, कृपया चेन्जलग पृष्ठमा जानुहोस् +update: + title: अपडेट उपलब्ध छ! + download: अपडेट र स्थापना गर्नुहोस् + date: मिति + cancel: पछि + downloading: डाउनलोड गर्दै... + version: संस्करण + page: GitHub रिलीज पृष्ठ + installing: स्थापना गर्दै... + extra_info: पूरा चेन्जलग पढ्नको लागि, कृपया चेन्जलग पृष्ठमा जानुहोस् diff --git a/src/apps/update/i18n/translations/nl.yml b/src/apps/update/i18n/translations/nl.yml index 8a8b13b9..52c2388d 100644 --- a/src/apps/update/i18n/translations/nl.yml +++ b/src/apps/update/i18n/translations/nl.yml @@ -1,10 +1,10 @@ -update: - cancel: Later - version: Versie - title: Update beschikbaar! - date: Datum - extra_info: Ga naar de Changelog -pagina om de volledige changelog te lezen - installing: Installeren ... - page: GitHub release pagina - downloading: Downloaden ... - download: Update & installeren +update: + cancel: Later + version: Versie + title: Update beschikbaar! + date: Datum + extra_info: Ga naar de Changelog -pagina om de volledige changelog te lezen + installing: Installeren ... + page: GitHub release pagina + downloading: Downloaden ... + download: Update & installeren diff --git a/src/apps/update/i18n/translations/no.yml b/src/apps/update/i18n/translations/no.yml index fe8d05fb..3442f888 100644 --- a/src/apps/update/i18n/translations/no.yml +++ b/src/apps/update/i18n/translations/no.yml @@ -1,10 +1,10 @@ -update: - title: Oppdatering tilgjengelig! - version: Versjon - cancel: Seinere - date: Dato - download: Oppdater og installer - installing: Installere ... - extra_info: For å lese hele Changelog, besøk Changelog -siden - downloading: Last ned ... - page: GitHub Release Page +update: + title: Oppdatering tilgjengelig! + version: Versjon + cancel: Seinere + date: Dato + download: Oppdater og installer + installing: Installere ... + extra_info: For å lese hele Changelog, besøk Changelog -siden + downloading: Last ned ... + page: GitHub Release Page diff --git a/src/apps/update/i18n/translations/pa.yml b/src/apps/update/i18n/translations/pa.yml index 19aba255..af3f08e2 100644 --- a/src/apps/update/i18n/translations/pa.yml +++ b/src/apps/update/i18n/translations/pa.yml @@ -1,10 +1,10 @@ -update: - version: ਸੰਸਕਰਣ - cancel: ਬਾਅਦ ਵਿੱਚ - date: ਤਾਰੀਖ਼ - downloading: ਡਾਊਨਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ... - title: ਅੱਪਡੇਟ ਉਪਲਬਧ ਹੈ! - extra_info: ਪੂਰਾ ਚੇਂਜਲੌਗ ਪੜ੍ਹਨ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਚੇਂਜਲੌਗ ਪੰਨੇ 'ਤੇ ਜਾਓ - page: GitHub ਰੀਲੀਜ਼ ਪੰਨਾ - download: ਅੱਪਡੇਟ ਅਤੇ ਸਥਾਪਿਤ ਕਰੋ - installing: ਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ... +update: + version: ਸੰਸਕਰਣ + cancel: ਬਾਅਦ ਵਿੱਚ + date: ਤਾਰੀਖ਼ + downloading: ਡਾਊਨਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ... + title: ਅੱਪਡੇਟ ਉਪਲਬਧ ਹੈ! + extra_info: ਪੂਰਾ ਚੇਂਜਲੌਗ ਪੜ੍ਹਨ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਚੇਂਜਲੌਗ ਪੰਨੇ 'ਤੇ ਜਾਓ + page: GitHub ਰੀਲੀਜ਼ ਪੰਨਾ + download: ਅੱਪਡੇਟ ਅਤੇ ਸਥਾਪਿਤ ਕਰੋ + installing: ਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ... diff --git a/src/apps/update/i18n/translations/pl.yml b/src/apps/update/i18n/translations/pl.yml index f7b568d2..2a0924c1 100644 --- a/src/apps/update/i18n/translations/pl.yml +++ b/src/apps/update/i18n/translations/pl.yml @@ -1,10 +1,10 @@ -update: - version: Wersja - cancel: Później - date: Data - title: Dostępna aktualizacja! - downloading: Ściąganie... - download: Zaktualizuj i zainstaluj - extra_info: Aby przeczytać pełny Changelog, odwiedź stronę Changelog - page: Strona wydania Github - installing: Instalowanie ... +update: + version: Wersja + cancel: Później + date: Data + title: Dostępna aktualizacja! + downloading: Ściąganie... + download: Zaktualizuj i zainstaluj + extra_info: Aby przeczytać pełny Changelog, odwiedź stronę Changelog + page: Strona wydania Github + installing: Instalowanie ... diff --git a/src/apps/update/i18n/translations/ps.yml b/src/apps/update/i18n/translations/ps.yml index 5bf64d1a..9739a043 100644 --- a/src/apps/update/i18n/translations/ps.yml +++ b/src/apps/update/i18n/translations/ps.yml @@ -1,10 +1,10 @@ -update: - date: نیټه - version: نسخه - installing: نصب کول... - title: تازه معلومات شتون لري! - download: تازه کول او نصب کول - extra_info: د بشپړ بدلون لاګ لوستلو لپاره ، مهرباني وکړئ د چینج لاګ پا pageې ته لاړشئ - page: د GitHub خوشې پاڼه - cancel: وروسته - downloading: کښته کول... +update: + date: نیټه + version: نسخه + installing: نصب کول... + title: تازه معلومات شتون لري! + download: تازه کول او نصب کول + extra_info: د بشپړ بدلون لاګ لوستلو لپاره ، مهرباني وکړئ د چینج لاګ پا pageې ته لاړشئ + page: د GitHub خوشې پاڼه + cancel: وروسته + downloading: کښته کول... diff --git a/src/apps/update/i18n/translations/pt.yml b/src/apps/update/i18n/translations/pt.yml index 018624e6..351f6a4e 100644 --- a/src/apps/update/i18n/translations/pt.yml +++ b/src/apps/update/i18n/translations/pt.yml @@ -1,10 +1,10 @@ -update: - title: Atualização disponível! - date: Data - version: Versão - extra_info: Para ler o changelog completo, visite a página changelog - page: Página de lançamento do GitHub - cancel: Mais tarde - download: Atualizar - downloading: Baixando... - installing: Instalando... +update: + title: Atualização disponível! + date: Data + version: Versão + extra_info: Para ler o changelog completo, visite a página changelog + page: Página de lançamento do GitHub + cancel: Mais tarde + download: Atualizar + downloading: Baixando... + installing: Instalando... diff --git a/src/apps/update/i18n/translations/ro.yml b/src/apps/update/i18n/translations/ro.yml index a6067352..3bcfb50d 100644 --- a/src/apps/update/i18n/translations/ro.yml +++ b/src/apps/update/i18n/translations/ro.yml @@ -1,10 +1,10 @@ -update: - version: Versiune - cancel: Mai tarziu - downloading: Descărcarea... - title: Actualizare disponibila! - date: Data - extra_info: Pentru a citi ChangeLog complet, vă rugăm să vizitați pagina ChangeLog - installing: Instalare ... - page: Pagina de eliberare Github - download: Actualizați și instalați +update: + version: Versiune + cancel: Mai tarziu + downloading: Descărcarea... + title: Actualizare disponibila! + date: Data + extra_info: Pentru a citi ChangeLog complet, vă rugăm să vizitați pagina ChangeLog + installing: Instalare ... + page: Pagina de eliberare Github + download: Actualizați și instalați diff --git a/src/apps/update/i18n/translations/ru.yml b/src/apps/update/i18n/translations/ru.yml index 98e9184c..a84c1dcf 100644 --- a/src/apps/update/i18n/translations/ru.yml +++ b/src/apps/update/i18n/translations/ru.yml @@ -1,12 +1,12 @@ -update: - title: Доступно обновление! - date: Дата - version: Версия - extra_info: >- - Чтобы прочитать полный список изменений, посетите страницу журнала - изменений. - page: Страница выпуска GitHub - cancel: Позже - download: Обновить и установить - downloading: Загрузка... - installing: Установка... +update: + title: Доступно обновление! + date: Дата + version: Версия + extra_info: >- + Чтобы прочитать полный список изменений, посетите страницу журнала + изменений. + page: Страница выпуска GitHub + cancel: Позже + download: Обновить и установить + downloading: Загрузка... + installing: Установка... diff --git a/src/apps/update/i18n/translations/si.yml b/src/apps/update/i18n/translations/si.yml index 757f48ea..25284bae 100644 --- a/src/apps/update/i18n/translations/si.yml +++ b/src/apps/update/i18n/translations/si.yml @@ -1,10 +1,10 @@ -update: - version: පිටපත - installing: ස්ථාපනය කරමින්... - cancel: පසු - date: දිනය - title: යාවත්කාලීන ලබා ගත හැක! - downloading: බාගනිමින්... - download: යාවත්කාලීන කිරීම සහ ස්ථාපනය කිරීම - page: GitHub නිකුතු පිටුව - extra_info: සම්පූර්ණ චේන්ජ්ලොග් කියවීමට, කරුණාකර චේන්ජ්ලොග් පිටුවට පිවිසෙන්න +update: + version: පිටපත + installing: ස්ථාපනය කරමින්... + cancel: පසු + date: දිනය + title: යාවත්කාලීන ලබා ගත හැක! + downloading: බාගනිමින්... + download: යාවත්කාලීන කිරීම සහ ස්ථාපනය කිරීම + page: GitHub නිකුතු පිටුව + extra_info: සම්පූර්ණ චේන්ජ්ලොග් කියවීමට, කරුණාකර චේන්ජ්ලොග් පිටුවට පිවිසෙන්න diff --git a/src/apps/update/i18n/translations/sk.yml b/src/apps/update/i18n/translations/sk.yml index 271a347f..ab3fdb65 100644 --- a/src/apps/update/i18n/translations/sk.yml +++ b/src/apps/update/i18n/translations/sk.yml @@ -1,10 +1,10 @@ -update: - version: Verzia - title: Aktualizácia je dostupná! - date: Dátum - download: Aktualizovať a inštalovať - installing: Inštalácia ... - extra_info: Ak si chcete prečítať úplný Changelog, navštívte stránku Changelog - downloading: Sťahovanie ... - cancel: Neskôr - page: Stránka vydania GitHub +update: + version: Verzia + title: Aktualizácia je dostupná! + date: Dátum + download: Aktualizovať a inštalovať + installing: Inštalácia ... + extra_info: Ak si chcete prečítať úplný Changelog, navštívte stránku Changelog + downloading: Sťahovanie ... + cancel: Neskôr + page: Stránka vydania GitHub diff --git a/src/apps/update/i18n/translations/so.yml b/src/apps/update/i18n/translations/so.yml index 1563f454..d8f73a88 100644 --- a/src/apps/update/i18n/translations/so.yml +++ b/src/apps/update/i18n/translations/so.yml @@ -1,10 +1,10 @@ -update: - cancel: Ka dib - downloading: Soo dejinaya... - date: Taariikhda - download: Cusbooneysii & Ku rakib - title: Cusbooneysii waa la heli karaa! - installing: Rakibaya... - version: Nooca - page: Bogga Siideynta GitHub - extra_info: Si aad u akhrido qoraalka buuxa, fadlan booqo bogga beddelka +update: + cancel: Ka dib + downloading: Soo dejinaya... + date: Taariikhda + download: Cusbooneysii & Ku rakib + title: Cusbooneysii waa la heli karaa! + installing: Rakibaya... + version: Nooca + page: Bogga Siideynta GitHub + extra_info: Si aad u akhrido qoraalka buuxa, fadlan booqo bogga beddelka diff --git a/src/apps/update/i18n/translations/sr.yml b/src/apps/update/i18n/translations/sr.yml index 8dc6cd01..dd651b42 100644 --- a/src/apps/update/i18n/translations/sr.yml +++ b/src/apps/update/i18n/translations/sr.yml @@ -1,10 +1,10 @@ -update: - title: Располагању новија верзија! - cancel: Касније - date: Датум - download: Ажурирајте и инсталирајте - version: Верзија - installing: Инсталирање... - extra_info: Да бисте прочитали цео дневник промена, посетите страницу дневника промена - page: Страница издања ГитХуб-а - downloading: Преузимање... +update: + title: Располагању новија верзија! + cancel: Касније + date: Датум + download: Ажурирајте и инсталирајте + version: Верзија + installing: Инсталирање... + extra_info: Да бисте прочитали цео дневник промена, посетите страницу дневника промена + page: Страница издања ГитХуб-а + downloading: Преузимање... diff --git a/src/apps/update/i18n/translations/sv.yml b/src/apps/update/i18n/translations/sv.yml index ac5db693..82bb731a 100644 --- a/src/apps/update/i18n/translations/sv.yml +++ b/src/apps/update/i18n/translations/sv.yml @@ -1,10 +1,10 @@ -update: - title: Uppdatering tillgänglig! - cancel: Senare - downloading: Laddar ner... - date: Datum - version: Version - page: Github släppsida - extra_info: För att läsa hela ChangeLog, besök Changelog -sidan - download: Uppdatering och installation - installing: Installera ... +update: + title: Uppdatering tillgänglig! + cancel: Senare + downloading: Laddar ner... + date: Datum + version: Version + page: Github släppsida + extra_info: För att läsa hela ChangeLog, besök Changelog -sidan + download: Uppdatering och installation + installing: Installera ... diff --git a/src/apps/update/i18n/translations/sw.yml b/src/apps/update/i18n/translations/sw.yml index 0434bf02..2b393577 100644 --- a/src/apps/update/i18n/translations/sw.yml +++ b/src/apps/update/i18n/translations/sw.yml @@ -1,12 +1,12 @@ -update: - cancel: Baadae - date: Tarehe - downloading: Inapakua... - title: Sasisho linapatikana! - download: Sasisha na Usakinishe - installing: Inasakinisha... - page: Ukurasa wa Kutolewa wa GitHub - version: Toleo - extra_info: >- - Ili kusoma logi kamili ya mabadiliko, tafadhali tembelea ukurasa wa - mabadiliko +update: + cancel: Baadae + date: Tarehe + downloading: Inapakua... + title: Sasisho linapatikana! + download: Sasisha na Usakinishe + installing: Inasakinisha... + page: Ukurasa wa Kutolewa wa GitHub + version: Toleo + extra_info: >- + Ili kusoma logi kamili ya mabadiliko, tafadhali tembelea ukurasa wa + mabadiliko diff --git a/src/apps/update/i18n/translations/ta.yml b/src/apps/update/i18n/translations/ta.yml index 3ff3f103..dcb0c6ee 100644 --- a/src/apps/update/i18n/translations/ta.yml +++ b/src/apps/update/i18n/translations/ta.yml @@ -1,10 +1,10 @@ -update: - date: தேதி - version: பதிப்பு - cancel: பின்னர் - installing: நிறுவுகிறது... - extra_info: முழு சேஞ்ச்லாக் படிக்க, சேஞ்ச்லாக் பக்கத்தைப் பார்வையிடவும் - title: புதுப்பிப்பு கிடைக்கிறது! - download: புதுப்பித்து நிறுவவும் - page: GitHub வெளியீட்டு பக்கம் - downloading: பதிவிறக்குகிறது... +update: + date: தேதி + version: பதிப்பு + cancel: பின்னர் + installing: நிறுவுகிறது... + extra_info: முழு சேஞ்ச்லாக் படிக்க, சேஞ்ச்லாக் பக்கத்தைப் பார்வையிடவும் + title: புதுப்பிப்பு கிடைக்கிறது! + download: புதுப்பித்து நிறுவவும் + page: GitHub வெளியீட்டு பக்கம் + downloading: பதிவிறக்குகிறது... diff --git a/src/apps/update/i18n/translations/te.yml b/src/apps/update/i18n/translations/te.yml index 3359022d..90dfbf21 100644 --- a/src/apps/update/i18n/translations/te.yml +++ b/src/apps/update/i18n/translations/te.yml @@ -1,10 +1,10 @@ -update: - version: 'సంస్కరణ: Telugu' - date: తేదీ - downloading: డౌన్‌లోడ్ చేస్తోంది... - cancel: తరువాత - extra_info: పూర్తి చేంజ్లాగ్ చదవడానికి, దయచేసి చేంజ్లాగ్ పేజీని సందర్శించండి - title: అందుబాటులో నవీకరణ! - download: అప్‌డేట్ & ఇన్‌స్టాల్ చేయండి - installing: ఇన్‌స్టాల్ చేస్తోంది... - page: GitHub విడుదల పేజీ +update: + version: 'సంస్కరణ: Telugu' + date: తేదీ + downloading: డౌన్‌లోడ్ చేస్తోంది... + cancel: తరువాత + extra_info: పూర్తి చేంజ్లాగ్ చదవడానికి, దయచేసి చేంజ్లాగ్ పేజీని సందర్శించండి + title: అందుబాటులో నవీకరణ! + download: అప్‌డేట్ & ఇన్‌స్టాల్ చేయండి + installing: ఇన్‌స్టాల్ చేస్తోంది... + page: GitHub విడుదల పేజీ diff --git a/src/apps/update/i18n/translations/tg.yml b/src/apps/update/i18n/translations/tg.yml index 9610ecf8..b2b4b8db 100644 --- a/src/apps/update/i18n/translations/tg.yml +++ b/src/apps/update/i18n/translations/tg.yml @@ -1,10 +1,10 @@ -update: - version: Версия - cancel: Баъдтар - date: Сана - title: Навсозии дастрас! - downloading: Зеркашӣ карда мешавад... - download: Навсозӣ ва насб - installing: Насб карда мешавад... - page: Саҳифаи нашри GitHub - extra_info: Барои хондани гузориши пурраи тағирот, лутфан ба саҳифаи тағирот ворид шавед +update: + version: Версия + cancel: Баъдтар + date: Сана + title: Навсозии дастрас! + downloading: Зеркашӣ карда мешавад... + download: Навсозӣ ва насб + installing: Насб карда мешавад... + page: Саҳифаи нашри GitHub + extra_info: Барои хондани гузориши пурраи тағирот, лутфан ба саҳифаи тағирот ворид шавед diff --git a/src/apps/update/i18n/translations/th.yml b/src/apps/update/i18n/translations/th.yml index 2253e8c8..ca0ee753 100644 --- a/src/apps/update/i18n/translations/th.yml +++ b/src/apps/update/i18n/translations/th.yml @@ -1,10 +1,10 @@ -update: - date: วันที่ - version: รุ่น - cancel: ภายหลัง - title: อัปเดตพร้อมใช้งาน! - download: อัปเดตและติดตั้ง - extra_info: หากต้องการอ่านการเปลี่ยนแปลงเต็มรูปแบบโปรดไปที่หน้า Changelog - page: หน้าปล่อย GitHub - downloading: ดาวน์โหลด ... - installing: การติดตั้ง ... +update: + date: วันที่ + version: รุ่น + cancel: ภายหลัง + title: อัปเดตพร้อมใช้งาน! + download: อัปเดตและติดตั้ง + extra_info: หากต้องการอ่านการเปลี่ยนแปลงเต็มรูปแบบโปรดไปที่หน้า Changelog + page: หน้าปล่อย GitHub + downloading: ดาวน์โหลด ... + installing: การติดตั้ง ... diff --git a/src/apps/update/i18n/translations/tl.yml b/src/apps/update/i18n/translations/tl.yml index bab0522b..4c208206 100644 --- a/src/apps/update/i18n/translations/tl.yml +++ b/src/apps/update/i18n/translations/tl.yml @@ -1,12 +1,12 @@ -update: - version: Bersyon - extra_info: >- - Upang mabasa ang buong Changelog, mangyaring bisitahin ang pahina ng - Changelog - cancel: Kalaunan - download: I -update at i -install - title: Mag -update Magagamit! - downloading: Pag -download ... - page: Pahina ng paglabas ng Github - date: Petsa - installing: Pag -install ... +update: + version: Bersyon + extra_info: >- + Upang mabasa ang buong Changelog, mangyaring bisitahin ang pahina ng + Changelog + cancel: Kalaunan + download: I -update at i -install + title: Mag -update Magagamit! + downloading: Pag -download ... + page: Pahina ng paglabas ng Github + date: Petsa + installing: Pag -install ... diff --git a/src/apps/update/i18n/translations/tr.yml b/src/apps/update/i18n/translations/tr.yml index c36473bf..3ae16889 100644 --- a/src/apps/update/i18n/translations/tr.yml +++ b/src/apps/update/i18n/translations/tr.yml @@ -1,10 +1,10 @@ -update: - cancel: Daha sonra - version: Versiyon - title: Güncelleme uygun! - date: Tarih - extra_info: Değişikliğin tamamını okumak için lütfen ChangeLog sayfasını ziyaret edin - page: Github Sürüm Sayfası - downloading: İndirme ... - download: Güncelleme ve Kurulum - installing: Yükleme ... +update: + cancel: Daha sonra + version: Versiyon + title: Güncelleme uygun! + date: Tarih + extra_info: Değişikliğin tamamını okumak için lütfen ChangeLog sayfasını ziyaret edin + page: Github Sürüm Sayfası + downloading: İndirme ... + download: Güncelleme ve Kurulum + installing: Yükleme ... diff --git a/src/apps/update/i18n/translations/uk.yml b/src/apps/update/i18n/translations/uk.yml index 94681406..eba5adcc 100644 --- a/src/apps/update/i18n/translations/uk.yml +++ b/src/apps/update/i18n/translations/uk.yml @@ -1,10 +1,10 @@ -update: - version: Версія - date: Дата - downloading: Завантаження ... - download: Оновлення та встановлення - extra_info: Щоб прочитати повний Changelog, відвідайте сторінку Changelog - page: Сторінка випуску Github - cancel: Пізніше - installing: Встановлення ... - title: Оновлення доступне! +update: + version: Версія + date: Дата + downloading: Завантаження ... + download: Оновлення та встановлення + extra_info: Щоб прочитати повний Changelog, відвідайте сторінку Changelog + page: Сторінка випуску Github + cancel: Пізніше + installing: Встановлення ... + title: Оновлення доступне! diff --git a/src/apps/update/i18n/translations/ur.yml b/src/apps/update/i18n/translations/ur.yml index a420bd23..3274a62d 100644 --- a/src/apps/update/i18n/translations/ur.yml +++ b/src/apps/update/i18n/translations/ur.yml @@ -1,10 +1,10 @@ -update: - version: ورژن - downloading: ڈاؤن لوڈ ہو رہا ہے... - cancel: بعد میں - date: تاریخ - installing: انسٹال ہو رہا ہے... - download: اپ ڈیٹ اور انسٹال کریں۔ - page: GitHub ریلیز صفحہ - title: اپ ڈیٹ دستیاب ہے! - extra_info: مکمل چینج لاگ پڑھنے کے لیے، براہ کرم چینج لاگ کا صفحہ دیکھیں +update: + version: ورژن + downloading: ڈاؤن لوڈ ہو رہا ہے... + cancel: بعد میں + date: تاریخ + installing: انسٹال ہو رہا ہے... + download: اپ ڈیٹ اور انسٹال کریں۔ + page: GitHub ریلیز صفحہ + title: اپ ڈیٹ دستیاب ہے! + extra_info: مکمل چینج لاگ پڑھنے کے لیے، براہ کرم چینج لاگ کا صفحہ دیکھیں diff --git a/src/apps/update/i18n/translations/uz.yml b/src/apps/update/i18n/translations/uz.yml index bf682083..4dc26259 100644 --- a/src/apps/update/i18n/translations/uz.yml +++ b/src/apps/update/i18n/translations/uz.yml @@ -1,12 +1,12 @@ -update: - downloading: Yuklab olinmoqda... - date: Sana - installing: Oʻrnatilmoqda... - cancel: Keyinchalik - version: Versiya - title: Yangilanish mavjud! - download: Yangilash va oʻrnatish - page: GitHub nashr sahifasi - extra_info: >- - Toʻliq oʻzgarishlar jurnalini oʻqish uchun oʻzgarishlar jurnali sahifasiga - tashrif buyuring +update: + downloading: Yuklab olinmoqda... + date: Sana + installing: Oʻrnatilmoqda... + cancel: Keyinchalik + version: Versiya + title: Yangilanish mavjud! + download: Yangilash va oʻrnatish + page: GitHub nashr sahifasi + extra_info: >- + Toʻliq oʻzgarishlar jurnalini oʻqish uchun oʻzgarishlar jurnali sahifasiga + tashrif buyuring diff --git a/src/apps/update/i18n/translations/vi.yml b/src/apps/update/i18n/translations/vi.yml index f15a8ffa..b6994e59 100644 --- a/src/apps/update/i18n/translations/vi.yml +++ b/src/apps/update/i18n/translations/vi.yml @@ -1,10 +1,10 @@ -update: - date: Ngày - version: Phiên bản - cancel: Sau đó - title: Cập nhật có sẵn! - downloading: Tải xuống ... - download: Cập nhật & Cài đặt - page: Trang phát hành GitHub - installing: Cài đặt ... - extra_info: Để đọc toàn bộ Changelog, vui lòng truy cập trang Changelog +update: + date: Ngày + version: Phiên bản + cancel: Sau đó + title: Cập nhật có sẵn! + downloading: Tải xuống ... + download: Cập nhật & Cài đặt + page: Trang phát hành GitHub + installing: Cài đặt ... + extra_info: Để đọc toàn bộ Changelog, vui lòng truy cập trang Changelog diff --git a/src/apps/update/i18n/translations/yo.yml b/src/apps/update/i18n/translations/yo.yml index acd9bc84..5579574d 100644 --- a/src/apps/update/i18n/translations/yo.yml +++ b/src/apps/update/i18n/translations/yo.yml @@ -1,10 +1,10 @@ -update: - cancel: Nigbamii - date: Ọjọ - extra_info: Lati ka iwe iyipada ni kikun, jọwọ ṣabẹwo si oju-iwe changelog - download: Imudojuiwọn & Fi sori ẹrọ - title: Imudojuiwọn wa! - version: Ẹya - downloading: Gbigbasilẹ... - page: Oju-iwe Tu GitHub - installing: Nfi sori ẹrọ... +update: + cancel: Nigbamii + date: Ọjọ + extra_info: Lati ka iwe iyipada ni kikun, jọwọ ṣabẹwo si oju-iwe changelog + download: Imudojuiwọn & Fi sori ẹrọ + title: Imudojuiwọn wa! + version: Ẹya + downloading: Gbigbasilẹ... + page: Oju-iwe Tu GitHub + installing: Nfi sori ẹrọ... diff --git a/src/apps/update/i18n/translations/zh.yml b/src/apps/update/i18n/translations/zh.yml index 651615aa..77e0012f 100644 --- a/src/apps/update/i18n/translations/zh.yml +++ b/src/apps/update/i18n/translations/zh.yml @@ -1,10 +1,10 @@ -update: - title: 有更新可用! - date: 日期 - version: 版本 - extra_info: 要阅读完整的更新日志,请访问更新日志页面 - page: GitHub发布页面 - cancel: 稍后 - download: 更新并安装 - downloading: 下载中... - installing: 安装中... +update: + title: 有更新可用! + date: 日期 + version: 版本 + extra_info: 要阅读完整的更新日志,请访问更新日志页面 + page: GitHub发布页面 + cancel: 稍后 + download: 更新并安装 + downloading: 下载中... + installing: 安装中... diff --git a/src/apps/update/i18n/translations/zu.yml b/src/apps/update/i18n/translations/zu.yml index b9058797..5e17de73 100644 --- a/src/apps/update/i18n/translations/zu.yml +++ b/src/apps/update/i18n/translations/zu.yml @@ -1,10 +1,10 @@ -update: - cancel: Kamuva - version: Inguqulo - date: Usuku - title: Isibuyekezo siyatholakala! - extra_info: Ukuze ufunde ukuguqulwa okuphelele, sicela uvakashele ikhasi lelogi - download: Buyekeza futhi ufake - downloading: Iyalanda... - installing: Iyafaka... - page: Ikhasi lokukhishwa kwe-GitHub +update: + cancel: Kamuva + version: Inguqulo + date: Usuku + title: Isibuyekezo siyatholakala! + extra_info: Ukuze ufunde ukuguqulwa okuphelele, sicela uvakashele ikhasi lelogi + download: Buyekeza futhi ufake + downloading: Iyalanda... + installing: Iyafaka... + page: Ikhasi lokukhishwa kwe-GitHub diff --git a/src/apps/update/index.html b/src/apps/update/index.html index 6320f197..c57e235f 100644 --- a/src/apps/update/index.html +++ b/src/apps/update/index.html @@ -1,13 +1,13 @@ - - - - - - - - - - -
- - + + + + + + + + + + +
+ + diff --git a/src/apps/update/index.tsx b/src/apps/update/index.tsx index 4c10e30a..04dc43e6 100644 --- a/src/apps/update/index.tsx +++ b/src/apps/update/index.tsx @@ -1,29 +1,29 @@ -import { UserSettingsLoader } from '../settings/modules/shared/store/storeApi'; -import { getRootContainer } from '../shared'; -import { wrapConsole } from '../shared/ConsoleWrapper'; -import i18n, { loadTranslations } from './i18n'; -import { createRoot } from 'react-dom/client'; -import { I18nextProvider } from 'react-i18next'; - -import { App } from './app'; - -import './styles/colors.css'; -import './styles/reset.css'; -import './styles/global.css'; - -async function main() { - const container = getRootContainer(); - wrapConsole(); - - let { jsonSettings } = await new UserSettingsLoader().withThemes(false).load(); - await loadTranslations(); - i18n.changeLanguage(jsonSettings.language); - - createRoot(container).render( - - - , - ); -} - +import { UserSettingsLoader } from '../settings/modules/shared/store/storeApi'; +import { getRootContainer } from '../shared'; +import { wrapConsole } from '../shared/ConsoleWrapper'; +import i18n, { loadTranslations } from './i18n'; +import { createRoot } from 'react-dom/client'; +import { I18nextProvider } from 'react-i18next'; + +import { App } from './app'; + +import './styles/colors.css'; +import './styles/reset.css'; +import './styles/global.css'; + +async function main() { + const container = getRootContainer(); + wrapConsole(); + + let { jsonSettings } = await new UserSettingsLoader().withThemes(false).load(); + await loadTranslations(); + i18n.changeLanguage(jsonSettings.language); + + createRoot(container).render( + + + , + ); +} + main(); \ No newline at end of file diff --git a/src/apps/update/styles/colors.css b/src/apps/update/styles/colors.css index ec8ed844..f12ab260 100644 --- a/src/apps/update/styles/colors.css +++ b/src/apps/update/styles/colors.css @@ -1,599 +1,599 @@ -:root { - /* Persisted colors variables (not changed on dark mode) */ - --color-persist-white: #ffffff; - --color-persist-gray-50: #fdfdfd; - --color-persist-gray-100: #f8f8f8; - --color-persist-gray-200: #e6e6e6; - --color-persist-gray-300: #d5d5d5; - --color-persist-gray-400: #b1b1b1; - --color-persist-gray-500: #909090; - --color-persist-gray-600: #6d6d6d; - --color-persist-gray-700: #464646; - --color-persist-gray-800: #222222; - --color-persist-gray-900: #151515; - --color-persist-black: #000000; - - --color-persist-blue-100: #e0f2ff; - --color-persist-blue-200: #cae8ff; - --color-persist-blue-300: #b5deff; - --color-persist-blue-400: #96cefd; - --color-persist-blue-500: #78bbfa; - --color-persist-blue-600: #59a7f6; - --color-persist-blue-700: #3892f3; - --color-persist-blue-800: #147af3; - --color-persist-blue-900: #0265dc; - --color-persist-blue-1000: #0054b6; - --color-persist-blue-1100: #004491; - --color-persist-blue-1200: #003571; - --color-persist-blue-1300: #002754; - - --color-persist-green-100: #cef8e0; - --color-persist-green-200: #adf4ce; - --color-persist-green-300: #89ecbc; - --color-persist-green-400: #67dea8; - --color-persist-green-500: #49cc93; - --color-persist-green-600: #2fb880; - --color-persist-green-700: #15a46e; - --color-persist-green-800: #008f5d; - --color-persist-green-900: #007a4d; - --color-persist-green-1000: #00653e; - --color-persist-green-1100: #005132; - --color-persist-green-1200: #053f27; - --color-persist-green-1300: #0a2e1d; - - --color-persist-orange-100: #ffeccc; - --color-persist-orange-200: #ffdfad; - --color-persist-orange-300: #fdd291; - --color-persist-orange-400: #ffbb63; - --color-persist-orange-500: #ffa037; - --color-persist-orange-600: #f68511; - --color-persist-orange-700: #e46f00; - --color-persist-orange-800: #cb5d00; - --color-persist-orange-900: #b14c00; - --color-persist-orange-1000: #953d00; - --color-persist-orange-1100: #7a2f00; - --color-persist-orange-1200: #612300; - --color-persist-orange-1300: #491901; - - --color-persist-red-100: #ffebe7; - --color-persist-red-200: #ffddd6; - --color-persist-red-300: #ffcdc3; - --color-persist-red-400: #ffb7a9; - --color-persist-red-500: #ff9b88; - --color-persist-red-600: #ff7c65; - --color-persist-red-700: #f75c46; - --color-persist-red-800: #ea3829; - --color-persist-red-900: #d31510; - --color-persist-red-1000: #b40000; - --color-persist-red-1100: #930000; - --color-persist-red-1200: #740000; - --color-persist-red-1300: #590000; - - --color-persist-celery-100: #cdfcbf; - --color-persist-celery-200: #aef69d; - --color-persist-celery-300: #96ee85; - --color-persist-celery-400: #72e06a; - --color-persist-celery-500: #4ecf50; - --color-persist-celery-600: #27bb36; - --color-persist-celery-700: #07a721; - --color-persist-celery-800: #009112; - --color-persist-celery-900: #007c0f; - --color-persist-celery-1000: #00670f; - --color-persist-celery-1100: #00530d; - --color-persist-celery-1200: #00400a; - --color-persist-celery-1300: #003007; - - --color-persist-chartreuse-100: #dbfc6e; - --color-persist-chartreuse-200: #cbf443; - --color-persist-chartreuse-300: #bce92a; - --color-persist-chartreuse-400: #aad816; - --color-persist-chartreuse-500: #98c50a; - --color-persist-chartreuse-600: #87b103; - --color-persist-chartreuse-700: #769c00; - --color-persist-chartreuse-800: #678800; - --color-persist-chartreuse-900: #577400; - --color-persist-chartreuse-1000: #486000; - --color-persist-chartreuse-1100: #3a4d00; - --color-persist-chartreuse-1200: #2c3b00; - --color-persist-chartreuse-1300: #212c00; - - --color-persist-cyan-100: #c5f8ff; - --color-persist-cyan-200: #a4f0ff; - --color-persist-cyan-300: #88e7fa; - --color-persist-cyan-400: #60d8f3; - --color-persist-cyan-500: #33c5e8; - --color-persist-cyan-600: #12b0da; - --color-persist-cyan-700: #019cc8; - --color-persist-cyan-800: #0086b4; - --color-persist-cyan-900: #00719f; - --color-persist-cyan-1000: #005d89; - --color-persist-cyan-1100: #004a73; - --color-persist-cyan-1200: #00395d; - --color-persist-cyan-1300: #002a46; - - --color-persist-fuchsia-100: #ffe9fc; - --color-persist-fuchsia-200: #ffdafa; - --color-persist-fuchsia-300: #fec7f8; - --color-persist-fuchsia-400: #fbaef6; - --color-persist-fuchsia-500: #f592f3; - --color-persist-fuchsia-600: #ed74ed; - --color-persist-fuchsia-700: #e055e2; - --color-persist-fuchsia-800: #cd3ace; - --color-persist-fuchsia-900: #b622b7; - --color-persist-fuchsia-1000: #9d039e; - --color-persist-fuchsia-1100: #800081; - --color-persist-fuchsia-1200: #640664; - --color-persist-fuchsia-1300: #470e46; - - --color-persist-indigo-100: #edeeff; - --color-persist-indigo-200: #e0e2ff; - --color-persist-indigo-300: #d3d5ff; - --color-persist-indigo-400: #c1c4ff; - --color-persist-indigo-500: #acafff; - --color-persist-indigo-600: #9599ff; - --color-persist-indigo-700: #7e84fc; - --color-persist-indigo-800: #686df4; - --color-persist-indigo-900: #5258e4; - --color-persist-indigo-1000: #4046ca; - --color-persist-indigo-1100: #3236a8; - --color-persist-indigo-1200: #262986; - --color-persist-indigo-1300: #1b1e64; - - --color-persist-magenta-100: #ffeaf1; - --color-persist-magenta-200: #ffdce8; - --color-persist-magenta-300: #ffcadd; - --color-persist-magenta-400: #ffb2ce; - --color-persist-magenta-500: #ff95bd; - --color-persist-magenta-600: #fa77aa; - --color-persist-magenta-700: #ef5a98; - --color-persist-magenta-800: #de3d82; - --color-persist-magenta-900: #c82269; - --color-persist-magenta-1000: #ad0955; - --color-persist-magenta-1100: #8e0045; - --color-persist-magenta-1200: #700037; - --color-persist-magenta-1300: #54032a; - - --color-persist-purple-100: #f6ebff; - --color-persist-purple-200: #eeddff; - --color-persist-purple-300: #e6d0ff; - --color-persist-purple-400: #dbbbfe; - --color-persist-purple-500: #cca4fd; - --color-persist-purple-600: #bd8bfc; - --color-persist-purple-700: #ae72f9; - --color-persist-purple-800: #9d57f4; - --color-persist-purple-900: #893de7; - --color-persist-purple-1000: #7326d3; - --color-persist-purple-1100: #5d13b7; - --color-persist-purple-1200: #470c94; - --color-persist-purple-1300: #33106a; - - --color-persist-seafoam-100: #cef7f3; - --color-persist-seafoam-200: #aaf1ea; - --color-persist-seafoam-300: #8ce9e2; - --color-persist-seafoam-400: #65dad2; - --color-persist-seafoam-500: #3fc9c1; - --color-persist-seafoam-600: #0fb5ae; - --color-persist-seafoam-700: #00a19a; - --color-persist-seafoam-800: #008c87; - --color-persist-seafoam-900: #007772; - --color-persist-seafoam-1000: #00635f; - --color-persist-seafoam-1100: #0c4f4c; - --color-persist-seafoam-1200: #123c3a; - --color-persist-seafoam-1300: #122c2b; - - --color-persist-yellow-100: #fbf198; - --color-persist-yellow-200: #f8e750; - --color-persist-yellow-300: #f8d904; - --color-persist-yellow-400: #e8c600; - --color-persist-yellow-500: #d7b300; - --color-persist-yellow-600: #c49f00; - --color-persist-yellow-700: #b08c00; - --color-persist-yellow-800: #9b7800; - --color-persist-yellow-900: #856600; - --color-persist-yellow-1000: #705300; - --color-persist-yellow-1100: #5b4300; - --color-persist-yellow-1200: #483300; - --color-persist-yellow-1300: #362500; -} - -@media (prefers-color-scheme: dark) { - :root { - --color-white: #000000; - - --color-gray-50: #151515; - --color-gray-100: #222222; - --color-gray-200: #464646; - --color-gray-300: #6d6d6d; - --color-gray-400: #909090; - --color-gray-500: #b1b1b1; - --color-gray-600: #d5d5d5; - --color-gray-700: #e6e6e6; - --color-gray-800: #f8f8f8; - --color-gray-900: #fdfdfd; - - --color-black: #ffffff; - - --color-blue-100: #003877; - --color-blue-200: #00418a; - --color-blue-300: #004da3; - --color-blue-400: #0059c2; - --color-blue-500: #0367e0; - --color-blue-600: #1379f3; - --color-blue-700: #348ff4; - --color-blue-800: #54a3f6; - --color-blue-900: #72b7f9; - --color-blue-1000: #8fcafc; - --color-blue-1100: #aedbfe; - --color-blue-1200: #cce9ff; - --color-blue-1300: #e8f6ff; - - --color-green-100: #044329; - --color-green-200: #004e2f; - --color-green-300: #005c38; - --color-green-400: #006c43; - --color-green-500: #007d4e; - --color-green-600: #008f5d; - --color-green-700: #12a26c; - --color-green-800: #2bb47d; - --color-green-900: #43c78f; - --color-green-1000: #5ed9a2; - --color-green-1100: #81e9b8; - --color-green-1200: #b1f4d1; - --color-green-1300: #dffaea; - - --color-orange-100: #662500; - --color-orange-200: #752d00; - --color-orange-300: #893700; - --color-orange-400: #9e4200; - --color-orange-500: #b44e00; - --color-orange-600: #ca5d00; - --color-orange-700: #e16d00; - --color-orange-800: #f4810c; - --color-orange-900: #fe9a2e; - --color-orange-1000: #ffb558; - --color-orange-1100: #fdce88; - --color-orange-1200: #ffe1b3; - --color-orange-1300: #fff2dd; - - --color-red-100: #7b0000; - --color-red-200: #8d0000; - --color-red-300: #a50000; - --color-red-400: #be0403; - --color-red-500: #d71913; - --color-red-600: #ea3829; - --color-red-700: #f65843; - --color-red-800: #ff755e; - --color-red-900: #ff9581; - --color-red-1000: #ffb0a1; - --color-red-1100: #ffc9bd; - --color-red-1200: #ffded8; - --color-red-1300: #fff1ee; - - --color-celery-100: #00450a; - --color-celery-200: #00500c; - --color-celery-300: #005e0e; - --color-celery-400: #006d0f; - --color-celery-500: #007f0f; - --color-celery-600: #009112; - --color-celery-700: #04a51e; - --color-celery-800: #22b833; - --color-celery-900: #44ca49; - --color-celery-1000: #69dc63; - --color-celery-1100: #8eeb7f; - --color-celery-1200: #b4f7a2; - --color-celery-1300: #ddfdd3; - - --color-chartreuse-100: #304000; - --color-chartreuse-200: #374a00; - --color-chartreuse-300: #415700; - --color-chartreuse-400: #4c6600; - --color-chartreuse-500: #597600; - --color-chartreuse-600: #668800; - --color-chartreuse-700: #759a00; - --color-chartreuse-800: #84ad01; - --color-chartreuse-900: #94c008; - --color-chartreuse-1000: #a6d312; - --color-chartreuse-1100: #b8e525; - --color-chartreuse-1200: #cdf547; - --color-chartreuse-1300: #e7fe9a; - - --color-cyan-100: #003d62; - --color-cyan-200: #00476f; - --color-cyan-300: #00557f; - --color-cyan-400: #006491; - --color-cyan-500: #0074a2; - --color-cyan-600: #0086b4; - --color-cyan-700: #0099c6; - --color-cyan-800: #0eadd7; - --color-cyan-900: #2cc1e6; - --color-cyan-1000: #54d3f1; - --color-cyan-1100: #7fe4f9; - --color-cyan-1200: #a7f1ff; - --color-cyan-1300: #d7faff; - - --color-fuchsia-100: #6b036a; - --color-fuchsia-200: #7b007b; - --color-fuchsia-300: #900091; - --color-fuchsia-400: #a50da6; - --color-fuchsia-500: #b925b9; - --color-fuchsia-600: #cd39ce; - --color-fuchsia-700: #df51e0; - --color-fuchsia-800: #eb6eec; - --color-fuchsia-900: #f48cf2; - --color-fuchsia-1000: #faa8f5; - --color-fuchsia-1100: #fec2f8; - --color-fuchsia-1200: #ffdbfa; - --color-fuchsia-1300: #ffeffc; - - --color-indigo-100: #282c8c; - --color-indigo-200: #2f34a3; - --color-indigo-300: #393fbb; - --color-indigo-400: #464bd3; - --color-indigo-500: #555be7; - --color-indigo-600: #686df4; - --color-indigo-700: #7c81fb; - --color-indigo-800: #9195ff; - --color-indigo-900: #a7aaff; - --color-indigo-1000: #bcbeff; - --color-indigo-1100: #d0d2ff; - --color-indigo-1200: #e2e4ff; - --color-indigo-1300: #f3f3fe; - - --color-magenta-100: #76003a; - --color-magenta-200: #890042; - --color-magenta-300: #a0004d; - --color-magenta-400: #b6125a; - --color-magenta-500: #cb266d; - --color-magenta-600: #de3d82; - --color-magenta-700: #ed5795; - --color-magenta-800: #f972a7; - --color-magenta-900: #ff8fb9; - --color-magenta-1000: #ffacca; - --color-magenta-1100: #ffc6da; - --color-magenta-1200: #ffdde9; - --color-magenta-1300: #fff0f5; - - --color-purple-100: #4c0d9d; - --color-purple-200: #5911b1; - --color-purple-300: #691cc8; - --color-purple-400: #7a2dda; - --color-purple-500: #8c41e9; - --color-purple-600: #9d57f3; - --color-purple-700: #ac6ff9; - --color-purple-800: #bb87fb; - --color-purple-900: #ca9ffc; - --color-purple-1000: #d7b6fe; - --color-purple-1100: #e4ccfe; - --color-purple-1200: #efdfff; - --color-purple-1300: #f9f0ff; - - --color-seafoam-100: #12413f; - --color-seafoam-200: #0e4c49; - --color-seafoam-300: #045a57; - --color-seafoam-400: #006965; - --color-seafoam-500: #007a75; - --color-seafoam-600: #008c87; - --color-seafoam-700: #009e98; - --color-seafoam-800: #03b2ab; - --color-seafoam-900: #36c5bd; - --color-seafoam-1000: #5dd6cf; - --color-seafoam-1100: #84e6df; - --color-seafoam-1200: #b0f2ec; - --color-seafoam-1300: #dff9f6; - - --color-yellow-100: #4c3600; - --color-yellow-200: #584000; - --color-yellow-300: #674c00; - --color-yellow-400: #775900; - --color-yellow-500: #886800; - --color-yellow-600: #9b7800; - --color-yellow-700: #ae8900; - --color-yellow-800: #c09c00; - --color-yellow-900: #d3ae00; - --color-yellow-1000: #e4c200; - --color-yellow-1100: #f4d500; - --color-yellow-1200: #f9e85c; - --color-yellow-1300: #fcf6bb; - } -} - -@media (prefers-color-scheme: light) { - :root { - --color-white: #ffffff; - - --color-gray-50: #fdfdfd; - --color-gray-100: #f8f8f8; - --color-gray-200: #e6e6e6; - --color-gray-300: #d5d5d5; - --color-gray-400: #b1b1b1; - --color-gray-500: #909090; - --color-gray-600: #6d6d6d; - --color-gray-700: #464646; - --color-gray-800: #222222; - --color-gray-900: #151515; - - --color-black: #000000; - - --color-blue-100: #e0f2ff; - --color-blue-200: #cae8ff; - --color-blue-300: #b5deff; - --color-blue-400: #96cefd; - --color-blue-500: #78bbfa; - --color-blue-600: #59a7f6; - --color-blue-700: #3892f3; - --color-blue-800: #147af3; - --color-blue-900: #0265dc; - --color-blue-1000: #0054b6; - --color-blue-1100: #004491; - --color-blue-1200: #003571; - --color-blue-1300: #002754; - - --color-green-100: #cef8e0; - --color-green-200: #adf4ce; - --color-green-300: #89ecbc; - --color-green-400: #67dea8; - --color-green-500: #49cc93; - --color-green-600: #2fb880; - --color-green-700: #15a46e; - --color-green-800: #008f5d; - --color-green-900: #007a4d; - --color-green-1000: #00653e; - --color-green-1100: #005132; - --color-green-1200: #053f27; - --color-green-1300: #0a2e1d; - - --color-orange-100: #ffeccc; - --color-orange-200: #ffdfad; - --color-orange-300: #fdd291; - --color-orange-400: #ffbb63; - --color-orange-500: #ffa037; - --color-orange-600: #f68511; - --color-orange-700: #e46f00; - --color-orange-800: #cb5d00; - --color-orange-900: #b14c00; - --color-orange-1000: #953d00; - --color-orange-1100: #7a2f00; - --color-orange-1200: #612300; - --color-orange-1300: #491901; - - --color-red-100: #ffebe7; - --color-red-200: #ffddd6; - --color-red-300: #ffcdc3; - --color-red-400: #ffb7a9; - --color-red-500: #ff9b88; - --color-red-600: #ff7c65; - --color-red-700: #f75c46; - --color-red-800: #ea3829; - --color-red-900: #d31510; - --color-red-1000: #b40000; - --color-red-1100: #930000; - --color-red-1200: #740000; - --color-red-1300: #590000; - - --color-celery-100: #cdfcbf; - --color-celery-200: #aef69d; - --color-celery-300: #96ee85; - --color-celery-400: #72e06a; - --color-celery-500: #4ecf50; - --color-celery-600: #27bb36; - --color-celery-700: #07a721; - --color-celery-800: #009112; - --color-celery-900: #007c0f; - --color-celery-1000: #00670f; - --color-celery-1100: #00530d; - --color-celery-1200: #00400a; - --color-celery-1300: #003007; - - --color-chartreuse-100: #dbfc6e; - --color-chartreuse-200: #cbf443; - --color-chartreuse-300: #bce92a; - --color-chartreuse-400: #aad816; - --color-chartreuse-500: #98c50a; - --color-chartreuse-600: #87b103; - --color-chartreuse-700: #769c00; - --color-chartreuse-800: #678800; - --color-chartreuse-900: #577400; - --color-chartreuse-1000: #486000; - --color-chartreuse-1100: #3a4d00; - --color-chartreuse-1200: #2c3b00; - --color-chartreuse-1300: #212c00; - - --color-cyan-100: #c5f8ff; - --color-cyan-200: #a4f0ff; - --color-cyan-300: #88e7fa; - --color-cyan-400: #60d8f3; - --color-cyan-500: #33c5e8; - --color-cyan-600: #12b0da; - --color-cyan-700: #019cc8; - --color-cyan-800: #0086b4; - --color-cyan-900: #00719f; - --color-cyan-1000: #005d89; - --color-cyan-1100: #004a73; - --color-cyan-1200: #00395d; - --color-cyan-1300: #002a46; - - --color-fuchsia-100: #ffe9fc; - --color-fuchsia-200: #ffdafa; - --color-fuchsia-300: #fec7f8; - --color-fuchsia-400: #fbaef6; - --color-fuchsia-500: #f592f3; - --color-fuchsia-600: #ed74ed; - --color-fuchsia-700: #e055e2; - --color-fuchsia-800: #cd3ace; - --color-fuchsia-900: #b622b7; - --color-fuchsia-1000: #9d039e; - --color-fuchsia-1100: #800081; - --color-fuchsia-1200: #640664; - --color-fuchsia-1300: #470e46; - - --color-indigo-100: #edeeff; - --color-indigo-200: #e0e2ff; - --color-indigo-300: #d3d5ff; - --color-indigo-400: #c1c4ff; - --color-indigo-500: #acafff; - --color-indigo-600: #9599ff; - --color-indigo-700: #7e84fc; - --color-indigo-800: #686df4; - --color-indigo-900: #5258e4; - --color-indigo-1000: #4046ca; - --color-indigo-1100: #3236a8; - --color-indigo-1200: #262986; - --color-indigo-1300: #1b1e64; - - --color-magenta-100: #ffeaf1; - --color-magenta-200: #ffdce8; - --color-magenta-300: #ffcadd; - --color-magenta-400: #ffb2ce; - --color-magenta-500: #ff95bd; - --color-magenta-600: #fa77aa; - --color-magenta-700: #ef5a98; - --color-magenta-800: #de3d82; - --color-magenta-900: #c82269; - --color-magenta-1000: #ad0955; - --color-magenta-1100: #8e0045; - --color-magenta-1200: #700037; - --color-magenta-1300: #54032a; - - --color-purple-100: #f6ebff; - --color-purple-200: #eeddff; - --color-purple-300: #e6d0ff; - --color-purple-400: #dbbbfe; - --color-purple-500: #cca4fd; - --color-purple-600: #bd8bfc; - --color-purple-700: #ae72f9; - --color-purple-800: #9d57f4; - --color-purple-900: #893de7; - --color-purple-1000: #7326d3; - --color-purple-1100: #5d13b7; - --color-purple-1200: #470c94; - --color-purple-1300: #33106a; - - --color-seafoam-100: #cef7f3; - --color-seafoam-200: #aaf1ea; - --color-seafoam-300: #8ce9e2; - --color-seafoam-400: #65dad2; - --color-seafoam-500: #3fc9c1; - --color-seafoam-600: #0fb5ae; - --color-seafoam-700: #00a19a; - --color-seafoam-800: #008c87; - --color-seafoam-900: #007772; - --color-seafoam-1000: #00635f; - --color-seafoam-1100: #0c4f4c; - --color-seafoam-1200: #123c3a; - --color-seafoam-1300: #122c2b; - - --color-yellow-100: #fbf198; - --color-yellow-200: #f8e750; - --color-yellow-300: #f8d904; - --color-yellow-400: #e8c600; - --color-yellow-500: #d7b300; - --color-yellow-600: #c49f00; - --color-yellow-700: #b08c00; - --color-yellow-800: #9b7800; - --color-yellow-900: #856600; - --color-yellow-1000: #705300; - --color-yellow-1100: #5b4300; - --color-yellow-1200: #483300; - --color-yellow-1300: #362500; - } -} +:root { + /* Persisted colors variables (not changed on dark mode) */ + --color-persist-white: #ffffff; + --color-persist-gray-50: #fdfdfd; + --color-persist-gray-100: #f8f8f8; + --color-persist-gray-200: #e6e6e6; + --color-persist-gray-300: #d5d5d5; + --color-persist-gray-400: #b1b1b1; + --color-persist-gray-500: #909090; + --color-persist-gray-600: #6d6d6d; + --color-persist-gray-700: #464646; + --color-persist-gray-800: #222222; + --color-persist-gray-900: #151515; + --color-persist-black: #000000; + + --color-persist-blue-100: #e0f2ff; + --color-persist-blue-200: #cae8ff; + --color-persist-blue-300: #b5deff; + --color-persist-blue-400: #96cefd; + --color-persist-blue-500: #78bbfa; + --color-persist-blue-600: #59a7f6; + --color-persist-blue-700: #3892f3; + --color-persist-blue-800: #147af3; + --color-persist-blue-900: #0265dc; + --color-persist-blue-1000: #0054b6; + --color-persist-blue-1100: #004491; + --color-persist-blue-1200: #003571; + --color-persist-blue-1300: #002754; + + --color-persist-green-100: #cef8e0; + --color-persist-green-200: #adf4ce; + --color-persist-green-300: #89ecbc; + --color-persist-green-400: #67dea8; + --color-persist-green-500: #49cc93; + --color-persist-green-600: #2fb880; + --color-persist-green-700: #15a46e; + --color-persist-green-800: #008f5d; + --color-persist-green-900: #007a4d; + --color-persist-green-1000: #00653e; + --color-persist-green-1100: #005132; + --color-persist-green-1200: #053f27; + --color-persist-green-1300: #0a2e1d; + + --color-persist-orange-100: #ffeccc; + --color-persist-orange-200: #ffdfad; + --color-persist-orange-300: #fdd291; + --color-persist-orange-400: #ffbb63; + --color-persist-orange-500: #ffa037; + --color-persist-orange-600: #f68511; + --color-persist-orange-700: #e46f00; + --color-persist-orange-800: #cb5d00; + --color-persist-orange-900: #b14c00; + --color-persist-orange-1000: #953d00; + --color-persist-orange-1100: #7a2f00; + --color-persist-orange-1200: #612300; + --color-persist-orange-1300: #491901; + + --color-persist-red-100: #ffebe7; + --color-persist-red-200: #ffddd6; + --color-persist-red-300: #ffcdc3; + --color-persist-red-400: #ffb7a9; + --color-persist-red-500: #ff9b88; + --color-persist-red-600: #ff7c65; + --color-persist-red-700: #f75c46; + --color-persist-red-800: #ea3829; + --color-persist-red-900: #d31510; + --color-persist-red-1000: #b40000; + --color-persist-red-1100: #930000; + --color-persist-red-1200: #740000; + --color-persist-red-1300: #590000; + + --color-persist-celery-100: #cdfcbf; + --color-persist-celery-200: #aef69d; + --color-persist-celery-300: #96ee85; + --color-persist-celery-400: #72e06a; + --color-persist-celery-500: #4ecf50; + --color-persist-celery-600: #27bb36; + --color-persist-celery-700: #07a721; + --color-persist-celery-800: #009112; + --color-persist-celery-900: #007c0f; + --color-persist-celery-1000: #00670f; + --color-persist-celery-1100: #00530d; + --color-persist-celery-1200: #00400a; + --color-persist-celery-1300: #003007; + + --color-persist-chartreuse-100: #dbfc6e; + --color-persist-chartreuse-200: #cbf443; + --color-persist-chartreuse-300: #bce92a; + --color-persist-chartreuse-400: #aad816; + --color-persist-chartreuse-500: #98c50a; + --color-persist-chartreuse-600: #87b103; + --color-persist-chartreuse-700: #769c00; + --color-persist-chartreuse-800: #678800; + --color-persist-chartreuse-900: #577400; + --color-persist-chartreuse-1000: #486000; + --color-persist-chartreuse-1100: #3a4d00; + --color-persist-chartreuse-1200: #2c3b00; + --color-persist-chartreuse-1300: #212c00; + + --color-persist-cyan-100: #c5f8ff; + --color-persist-cyan-200: #a4f0ff; + --color-persist-cyan-300: #88e7fa; + --color-persist-cyan-400: #60d8f3; + --color-persist-cyan-500: #33c5e8; + --color-persist-cyan-600: #12b0da; + --color-persist-cyan-700: #019cc8; + --color-persist-cyan-800: #0086b4; + --color-persist-cyan-900: #00719f; + --color-persist-cyan-1000: #005d89; + --color-persist-cyan-1100: #004a73; + --color-persist-cyan-1200: #00395d; + --color-persist-cyan-1300: #002a46; + + --color-persist-fuchsia-100: #ffe9fc; + --color-persist-fuchsia-200: #ffdafa; + --color-persist-fuchsia-300: #fec7f8; + --color-persist-fuchsia-400: #fbaef6; + --color-persist-fuchsia-500: #f592f3; + --color-persist-fuchsia-600: #ed74ed; + --color-persist-fuchsia-700: #e055e2; + --color-persist-fuchsia-800: #cd3ace; + --color-persist-fuchsia-900: #b622b7; + --color-persist-fuchsia-1000: #9d039e; + --color-persist-fuchsia-1100: #800081; + --color-persist-fuchsia-1200: #640664; + --color-persist-fuchsia-1300: #470e46; + + --color-persist-indigo-100: #edeeff; + --color-persist-indigo-200: #e0e2ff; + --color-persist-indigo-300: #d3d5ff; + --color-persist-indigo-400: #c1c4ff; + --color-persist-indigo-500: #acafff; + --color-persist-indigo-600: #9599ff; + --color-persist-indigo-700: #7e84fc; + --color-persist-indigo-800: #686df4; + --color-persist-indigo-900: #5258e4; + --color-persist-indigo-1000: #4046ca; + --color-persist-indigo-1100: #3236a8; + --color-persist-indigo-1200: #262986; + --color-persist-indigo-1300: #1b1e64; + + --color-persist-magenta-100: #ffeaf1; + --color-persist-magenta-200: #ffdce8; + --color-persist-magenta-300: #ffcadd; + --color-persist-magenta-400: #ffb2ce; + --color-persist-magenta-500: #ff95bd; + --color-persist-magenta-600: #fa77aa; + --color-persist-magenta-700: #ef5a98; + --color-persist-magenta-800: #de3d82; + --color-persist-magenta-900: #c82269; + --color-persist-magenta-1000: #ad0955; + --color-persist-magenta-1100: #8e0045; + --color-persist-magenta-1200: #700037; + --color-persist-magenta-1300: #54032a; + + --color-persist-purple-100: #f6ebff; + --color-persist-purple-200: #eeddff; + --color-persist-purple-300: #e6d0ff; + --color-persist-purple-400: #dbbbfe; + --color-persist-purple-500: #cca4fd; + --color-persist-purple-600: #bd8bfc; + --color-persist-purple-700: #ae72f9; + --color-persist-purple-800: #9d57f4; + --color-persist-purple-900: #893de7; + --color-persist-purple-1000: #7326d3; + --color-persist-purple-1100: #5d13b7; + --color-persist-purple-1200: #470c94; + --color-persist-purple-1300: #33106a; + + --color-persist-seafoam-100: #cef7f3; + --color-persist-seafoam-200: #aaf1ea; + --color-persist-seafoam-300: #8ce9e2; + --color-persist-seafoam-400: #65dad2; + --color-persist-seafoam-500: #3fc9c1; + --color-persist-seafoam-600: #0fb5ae; + --color-persist-seafoam-700: #00a19a; + --color-persist-seafoam-800: #008c87; + --color-persist-seafoam-900: #007772; + --color-persist-seafoam-1000: #00635f; + --color-persist-seafoam-1100: #0c4f4c; + --color-persist-seafoam-1200: #123c3a; + --color-persist-seafoam-1300: #122c2b; + + --color-persist-yellow-100: #fbf198; + --color-persist-yellow-200: #f8e750; + --color-persist-yellow-300: #f8d904; + --color-persist-yellow-400: #e8c600; + --color-persist-yellow-500: #d7b300; + --color-persist-yellow-600: #c49f00; + --color-persist-yellow-700: #b08c00; + --color-persist-yellow-800: #9b7800; + --color-persist-yellow-900: #856600; + --color-persist-yellow-1000: #705300; + --color-persist-yellow-1100: #5b4300; + --color-persist-yellow-1200: #483300; + --color-persist-yellow-1300: #362500; +} + +@media (prefers-color-scheme: dark) { + :root { + --color-white: #000000; + + --color-gray-50: #151515; + --color-gray-100: #222222; + --color-gray-200: #464646; + --color-gray-300: #6d6d6d; + --color-gray-400: #909090; + --color-gray-500: #b1b1b1; + --color-gray-600: #d5d5d5; + --color-gray-700: #e6e6e6; + --color-gray-800: #f8f8f8; + --color-gray-900: #fdfdfd; + + --color-black: #ffffff; + + --color-blue-100: #003877; + --color-blue-200: #00418a; + --color-blue-300: #004da3; + --color-blue-400: #0059c2; + --color-blue-500: #0367e0; + --color-blue-600: #1379f3; + --color-blue-700: #348ff4; + --color-blue-800: #54a3f6; + --color-blue-900: #72b7f9; + --color-blue-1000: #8fcafc; + --color-blue-1100: #aedbfe; + --color-blue-1200: #cce9ff; + --color-blue-1300: #e8f6ff; + + --color-green-100: #044329; + --color-green-200: #004e2f; + --color-green-300: #005c38; + --color-green-400: #006c43; + --color-green-500: #007d4e; + --color-green-600: #008f5d; + --color-green-700: #12a26c; + --color-green-800: #2bb47d; + --color-green-900: #43c78f; + --color-green-1000: #5ed9a2; + --color-green-1100: #81e9b8; + --color-green-1200: #b1f4d1; + --color-green-1300: #dffaea; + + --color-orange-100: #662500; + --color-orange-200: #752d00; + --color-orange-300: #893700; + --color-orange-400: #9e4200; + --color-orange-500: #b44e00; + --color-orange-600: #ca5d00; + --color-orange-700: #e16d00; + --color-orange-800: #f4810c; + --color-orange-900: #fe9a2e; + --color-orange-1000: #ffb558; + --color-orange-1100: #fdce88; + --color-orange-1200: #ffe1b3; + --color-orange-1300: #fff2dd; + + --color-red-100: #7b0000; + --color-red-200: #8d0000; + --color-red-300: #a50000; + --color-red-400: #be0403; + --color-red-500: #d71913; + --color-red-600: #ea3829; + --color-red-700: #f65843; + --color-red-800: #ff755e; + --color-red-900: #ff9581; + --color-red-1000: #ffb0a1; + --color-red-1100: #ffc9bd; + --color-red-1200: #ffded8; + --color-red-1300: #fff1ee; + + --color-celery-100: #00450a; + --color-celery-200: #00500c; + --color-celery-300: #005e0e; + --color-celery-400: #006d0f; + --color-celery-500: #007f0f; + --color-celery-600: #009112; + --color-celery-700: #04a51e; + --color-celery-800: #22b833; + --color-celery-900: #44ca49; + --color-celery-1000: #69dc63; + --color-celery-1100: #8eeb7f; + --color-celery-1200: #b4f7a2; + --color-celery-1300: #ddfdd3; + + --color-chartreuse-100: #304000; + --color-chartreuse-200: #374a00; + --color-chartreuse-300: #415700; + --color-chartreuse-400: #4c6600; + --color-chartreuse-500: #597600; + --color-chartreuse-600: #668800; + --color-chartreuse-700: #759a00; + --color-chartreuse-800: #84ad01; + --color-chartreuse-900: #94c008; + --color-chartreuse-1000: #a6d312; + --color-chartreuse-1100: #b8e525; + --color-chartreuse-1200: #cdf547; + --color-chartreuse-1300: #e7fe9a; + + --color-cyan-100: #003d62; + --color-cyan-200: #00476f; + --color-cyan-300: #00557f; + --color-cyan-400: #006491; + --color-cyan-500: #0074a2; + --color-cyan-600: #0086b4; + --color-cyan-700: #0099c6; + --color-cyan-800: #0eadd7; + --color-cyan-900: #2cc1e6; + --color-cyan-1000: #54d3f1; + --color-cyan-1100: #7fe4f9; + --color-cyan-1200: #a7f1ff; + --color-cyan-1300: #d7faff; + + --color-fuchsia-100: #6b036a; + --color-fuchsia-200: #7b007b; + --color-fuchsia-300: #900091; + --color-fuchsia-400: #a50da6; + --color-fuchsia-500: #b925b9; + --color-fuchsia-600: #cd39ce; + --color-fuchsia-700: #df51e0; + --color-fuchsia-800: #eb6eec; + --color-fuchsia-900: #f48cf2; + --color-fuchsia-1000: #faa8f5; + --color-fuchsia-1100: #fec2f8; + --color-fuchsia-1200: #ffdbfa; + --color-fuchsia-1300: #ffeffc; + + --color-indigo-100: #282c8c; + --color-indigo-200: #2f34a3; + --color-indigo-300: #393fbb; + --color-indigo-400: #464bd3; + --color-indigo-500: #555be7; + --color-indigo-600: #686df4; + --color-indigo-700: #7c81fb; + --color-indigo-800: #9195ff; + --color-indigo-900: #a7aaff; + --color-indigo-1000: #bcbeff; + --color-indigo-1100: #d0d2ff; + --color-indigo-1200: #e2e4ff; + --color-indigo-1300: #f3f3fe; + + --color-magenta-100: #76003a; + --color-magenta-200: #890042; + --color-magenta-300: #a0004d; + --color-magenta-400: #b6125a; + --color-magenta-500: #cb266d; + --color-magenta-600: #de3d82; + --color-magenta-700: #ed5795; + --color-magenta-800: #f972a7; + --color-magenta-900: #ff8fb9; + --color-magenta-1000: #ffacca; + --color-magenta-1100: #ffc6da; + --color-magenta-1200: #ffdde9; + --color-magenta-1300: #fff0f5; + + --color-purple-100: #4c0d9d; + --color-purple-200: #5911b1; + --color-purple-300: #691cc8; + --color-purple-400: #7a2dda; + --color-purple-500: #8c41e9; + --color-purple-600: #9d57f3; + --color-purple-700: #ac6ff9; + --color-purple-800: #bb87fb; + --color-purple-900: #ca9ffc; + --color-purple-1000: #d7b6fe; + --color-purple-1100: #e4ccfe; + --color-purple-1200: #efdfff; + --color-purple-1300: #f9f0ff; + + --color-seafoam-100: #12413f; + --color-seafoam-200: #0e4c49; + --color-seafoam-300: #045a57; + --color-seafoam-400: #006965; + --color-seafoam-500: #007a75; + --color-seafoam-600: #008c87; + --color-seafoam-700: #009e98; + --color-seafoam-800: #03b2ab; + --color-seafoam-900: #36c5bd; + --color-seafoam-1000: #5dd6cf; + --color-seafoam-1100: #84e6df; + --color-seafoam-1200: #b0f2ec; + --color-seafoam-1300: #dff9f6; + + --color-yellow-100: #4c3600; + --color-yellow-200: #584000; + --color-yellow-300: #674c00; + --color-yellow-400: #775900; + --color-yellow-500: #886800; + --color-yellow-600: #9b7800; + --color-yellow-700: #ae8900; + --color-yellow-800: #c09c00; + --color-yellow-900: #d3ae00; + --color-yellow-1000: #e4c200; + --color-yellow-1100: #f4d500; + --color-yellow-1200: #f9e85c; + --color-yellow-1300: #fcf6bb; + } +} + +@media (prefers-color-scheme: light) { + :root { + --color-white: #ffffff; + + --color-gray-50: #fdfdfd; + --color-gray-100: #f8f8f8; + --color-gray-200: #e6e6e6; + --color-gray-300: #d5d5d5; + --color-gray-400: #b1b1b1; + --color-gray-500: #909090; + --color-gray-600: #6d6d6d; + --color-gray-700: #464646; + --color-gray-800: #222222; + --color-gray-900: #151515; + + --color-black: #000000; + + --color-blue-100: #e0f2ff; + --color-blue-200: #cae8ff; + --color-blue-300: #b5deff; + --color-blue-400: #96cefd; + --color-blue-500: #78bbfa; + --color-blue-600: #59a7f6; + --color-blue-700: #3892f3; + --color-blue-800: #147af3; + --color-blue-900: #0265dc; + --color-blue-1000: #0054b6; + --color-blue-1100: #004491; + --color-blue-1200: #003571; + --color-blue-1300: #002754; + + --color-green-100: #cef8e0; + --color-green-200: #adf4ce; + --color-green-300: #89ecbc; + --color-green-400: #67dea8; + --color-green-500: #49cc93; + --color-green-600: #2fb880; + --color-green-700: #15a46e; + --color-green-800: #008f5d; + --color-green-900: #007a4d; + --color-green-1000: #00653e; + --color-green-1100: #005132; + --color-green-1200: #053f27; + --color-green-1300: #0a2e1d; + + --color-orange-100: #ffeccc; + --color-orange-200: #ffdfad; + --color-orange-300: #fdd291; + --color-orange-400: #ffbb63; + --color-orange-500: #ffa037; + --color-orange-600: #f68511; + --color-orange-700: #e46f00; + --color-orange-800: #cb5d00; + --color-orange-900: #b14c00; + --color-orange-1000: #953d00; + --color-orange-1100: #7a2f00; + --color-orange-1200: #612300; + --color-orange-1300: #491901; + + --color-red-100: #ffebe7; + --color-red-200: #ffddd6; + --color-red-300: #ffcdc3; + --color-red-400: #ffb7a9; + --color-red-500: #ff9b88; + --color-red-600: #ff7c65; + --color-red-700: #f75c46; + --color-red-800: #ea3829; + --color-red-900: #d31510; + --color-red-1000: #b40000; + --color-red-1100: #930000; + --color-red-1200: #740000; + --color-red-1300: #590000; + + --color-celery-100: #cdfcbf; + --color-celery-200: #aef69d; + --color-celery-300: #96ee85; + --color-celery-400: #72e06a; + --color-celery-500: #4ecf50; + --color-celery-600: #27bb36; + --color-celery-700: #07a721; + --color-celery-800: #009112; + --color-celery-900: #007c0f; + --color-celery-1000: #00670f; + --color-celery-1100: #00530d; + --color-celery-1200: #00400a; + --color-celery-1300: #003007; + + --color-chartreuse-100: #dbfc6e; + --color-chartreuse-200: #cbf443; + --color-chartreuse-300: #bce92a; + --color-chartreuse-400: #aad816; + --color-chartreuse-500: #98c50a; + --color-chartreuse-600: #87b103; + --color-chartreuse-700: #769c00; + --color-chartreuse-800: #678800; + --color-chartreuse-900: #577400; + --color-chartreuse-1000: #486000; + --color-chartreuse-1100: #3a4d00; + --color-chartreuse-1200: #2c3b00; + --color-chartreuse-1300: #212c00; + + --color-cyan-100: #c5f8ff; + --color-cyan-200: #a4f0ff; + --color-cyan-300: #88e7fa; + --color-cyan-400: #60d8f3; + --color-cyan-500: #33c5e8; + --color-cyan-600: #12b0da; + --color-cyan-700: #019cc8; + --color-cyan-800: #0086b4; + --color-cyan-900: #00719f; + --color-cyan-1000: #005d89; + --color-cyan-1100: #004a73; + --color-cyan-1200: #00395d; + --color-cyan-1300: #002a46; + + --color-fuchsia-100: #ffe9fc; + --color-fuchsia-200: #ffdafa; + --color-fuchsia-300: #fec7f8; + --color-fuchsia-400: #fbaef6; + --color-fuchsia-500: #f592f3; + --color-fuchsia-600: #ed74ed; + --color-fuchsia-700: #e055e2; + --color-fuchsia-800: #cd3ace; + --color-fuchsia-900: #b622b7; + --color-fuchsia-1000: #9d039e; + --color-fuchsia-1100: #800081; + --color-fuchsia-1200: #640664; + --color-fuchsia-1300: #470e46; + + --color-indigo-100: #edeeff; + --color-indigo-200: #e0e2ff; + --color-indigo-300: #d3d5ff; + --color-indigo-400: #c1c4ff; + --color-indigo-500: #acafff; + --color-indigo-600: #9599ff; + --color-indigo-700: #7e84fc; + --color-indigo-800: #686df4; + --color-indigo-900: #5258e4; + --color-indigo-1000: #4046ca; + --color-indigo-1100: #3236a8; + --color-indigo-1200: #262986; + --color-indigo-1300: #1b1e64; + + --color-magenta-100: #ffeaf1; + --color-magenta-200: #ffdce8; + --color-magenta-300: #ffcadd; + --color-magenta-400: #ffb2ce; + --color-magenta-500: #ff95bd; + --color-magenta-600: #fa77aa; + --color-magenta-700: #ef5a98; + --color-magenta-800: #de3d82; + --color-magenta-900: #c82269; + --color-magenta-1000: #ad0955; + --color-magenta-1100: #8e0045; + --color-magenta-1200: #700037; + --color-magenta-1300: #54032a; + + --color-purple-100: #f6ebff; + --color-purple-200: #eeddff; + --color-purple-300: #e6d0ff; + --color-purple-400: #dbbbfe; + --color-purple-500: #cca4fd; + --color-purple-600: #bd8bfc; + --color-purple-700: #ae72f9; + --color-purple-800: #9d57f4; + --color-purple-900: #893de7; + --color-purple-1000: #7326d3; + --color-purple-1100: #5d13b7; + --color-purple-1200: #470c94; + --color-purple-1300: #33106a; + + --color-seafoam-100: #cef7f3; + --color-seafoam-200: #aaf1ea; + --color-seafoam-300: #8ce9e2; + --color-seafoam-400: #65dad2; + --color-seafoam-500: #3fc9c1; + --color-seafoam-600: #0fb5ae; + --color-seafoam-700: #00a19a; + --color-seafoam-800: #008c87; + --color-seafoam-900: #007772; + --color-seafoam-1000: #00635f; + --color-seafoam-1100: #0c4f4c; + --color-seafoam-1200: #123c3a; + --color-seafoam-1300: #122c2b; + + --color-yellow-100: #fbf198; + --color-yellow-200: #f8e750; + --color-yellow-300: #f8d904; + --color-yellow-400: #e8c600; + --color-yellow-500: #d7b300; + --color-yellow-600: #c49f00; + --color-yellow-700: #b08c00; + --color-yellow-800: #9b7800; + --color-yellow-900: #856600; + --color-yellow-1000: #705300; + --color-yellow-1100: #5b4300; + --color-yellow-1200: #483300; + --color-yellow-1300: #362500; + } +} diff --git a/src/apps/update/styles/global.css b/src/apps/update/styles/global.css index 714e5380..484eb350 100644 --- a/src/apps/update/styles/global.css +++ b/src/apps/update/styles/global.css @@ -1,82 +1,82 @@ -body { - overflow: hidden; - cursor: default; - background: transparent; - - :not(input):not(textarea), - :not(input):not(textarea)::after, - :not(input):not(textarea)::before { - -webkit-user-select: none; - user-select: none; - } -} - -::-webkit-scrollbar { - width: 8px; - height: 8px; -} - -::-webkit-scrollbar-track { - background-color: transparent; -} - -::-webkit-scrollbar-thumb { - background-color: var(--color-gray-500); - border-radius: 6px; -} - -::-webkit-scrollbar-thumb:hover { - background-color: var(--color-gray-600); -} - -#root { - height: 100vh; - width: 100vw; - border-radius: 20px; - background-color: var(--color-gray-100); - padding: 30px; - display: flex; - flex-direction: column; - gap: 14px; - overflow: hidden; - - .title { - font-size: 20px; - font-weight: bold; - - .package { - color: var(--color-blue-900); - } - } - - .description { - position: relative; - overflow: auto; - flex: 1; - - b { - font-weight: bold; - } - - a { - color: var(--color-blue-900); - } - - .progress { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - } - } - - .footer { - display: flex; - gap: 14px; - justify-content: flex-end; - - > button { - font-weight: bold; - } - } +body { + overflow: hidden; + cursor: default; + background: transparent; + + :not(input):not(textarea), + :not(input):not(textarea)::after, + :not(input):not(textarea)::before { + -webkit-user-select: none; + user-select: none; + } +} + +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background-color: transparent; +} + +::-webkit-scrollbar-thumb { + background-color: var(--color-gray-500); + border-radius: 6px; +} + +::-webkit-scrollbar-thumb:hover { + background-color: var(--color-gray-600); +} + +#root { + height: 100vh; + width: 100vw; + border-radius: 20px; + background-color: var(--color-gray-100); + padding: 30px; + display: flex; + flex-direction: column; + gap: 14px; + overflow: hidden; + + .title { + font-size: 20px; + font-weight: bold; + + .package { + color: var(--color-blue-900); + } + } + + .description { + position: relative; + overflow: auto; + flex: 1; + + b { + font-weight: bold; + } + + a { + color: var(--color-blue-900); + } + + .progress { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + } + + .footer { + display: flex; + gap: 14px; + justify-content: flex-end; + + > button { + font-weight: bold; + } + } } \ No newline at end of file diff --git a/src/apps/update/styles/reset.css b/src/apps/update/styles/reset.css index 00912b16..8bba46cd 100644 --- a/src/apps/update/styles/reset.css +++ b/src/apps/update/styles/reset.css @@ -1,84 +1,84 @@ -:root { - font-size: 100%; - --main-typo: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; - --primary-color: var(--color-gray-900); - --secondary-color: var(--color-gray-50); -} - -*, *:after, *:before { - margin: 0; - padding: 0; - border: 0; - outline: none; - box-sizing: border-box; - vertical-align: baseline; -} - -img, image, picture, video, iframe, figure { - max-width: 100%; - width: 100%; - display: block; -} - -a { - display: block; -} - -p a { - display: inline; -} - -li { - list-style-type: none; -} - -html { - scroll-behavior: smooth; -} - -h1, h2, h3, h4, h5, h6, p, span, a, strong, blockquote, i, b, em, pre { - font-size: 1em; - font-weight: inherit; - font-style: inherit; - text-decoration: none; - color: inherit; -} - -form, input, textarea, select, button, label { - font-family: inherit; - font-size: inherit; - hyphens: auto; - background-color: transparent; - display: block; - color: inherit; -} - -table, tr, td { - border-collapse: collapse; - border-spacing: 0; -} - -svg { - width: 100%; - display: block; - fill: currentColor; -} - -body { - font-size: 1em; - line-height: 1.4em; - font-family: var(--main-typo); - color: var(--primary-color); - background-color: var(--secondary-color); - hyphens: auto; - font-smooth: always; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -hr { - border: 1px solid; - margin: 1em 0; - opacity: 0.8; - color: var(--color-gray-200); +:root { + font-size: 100%; + --main-typo: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + --primary-color: var(--color-gray-900); + --secondary-color: var(--color-gray-50); +} + +*, *:after, *:before { + margin: 0; + padding: 0; + border: 0; + outline: none; + box-sizing: border-box; + vertical-align: baseline; +} + +img, image, picture, video, iframe, figure { + max-width: 100%; + width: 100%; + display: block; +} + +a { + display: block; +} + +p a { + display: inline; +} + +li { + list-style-type: none; +} + +html { + scroll-behavior: smooth; +} + +h1, h2, h3, h4, h5, h6, p, span, a, strong, blockquote, i, b, em, pre { + font-size: 1em; + font-weight: inherit; + font-style: inherit; + text-decoration: none; + color: inherit; +} + +form, input, textarea, select, button, label { + font-family: inherit; + font-size: inherit; + hyphens: auto; + background-color: transparent; + display: block; + color: inherit; +} + +table, tr, td { + border-collapse: collapse; + border-spacing: 0; +} + +svg { + width: 100%; + display: block; + fill: currentColor; +} + +body { + font-size: 1em; + line-height: 1.4em; + font-family: var(--main-typo); + color: var(--primary-color); + background-color: var(--secondary-color); + hyphens: auto; + font-smooth: always; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +hr { + border: 1px solid; + margin: 1em 0; + opacity: 0.8; + color: var(--color-gray-200); } \ No newline at end of file diff --git a/src/apps/update/update.tsx b/src/apps/update/update.tsx index 42908595..e66f314f 100644 --- a/src/apps/update/update.tsx +++ b/src/apps/update/update.tsx @@ -1,84 +1,84 @@ -import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; -import { Update } from '@tauri-apps/plugin-updater'; -import { Button, Progress } from 'antd'; -import { useState } from 'react'; -import { useTranslation } from 'react-i18next'; - -interface Props { - update: Update; -} - -export function UpdateModal({ update }: Props) { - const [total, setTotal] = useState(null); - const [current, setCurrent] = useState(0); - - const { t } = useTranslation(); - - const onDownload = async () => { - update.downloadAndInstall((progress) => { - if (progress.event === 'Started' && progress.data.contentLength) { - setTotal(progress.data.contentLength); - } - - if (progress.event === 'Progress') { - setCurrent((v) => v + progress.data.chunkLength * 1000); - } - - if (progress.event === 'Finished') { - setCurrent(total!); - } - }); - }; - - if (total != null) { - const percent = Math.floor((current / total) * 100); - return ( - <> -
- {percent === 100 ? t('update.installing') : t('update.downloading')} -
-
- -
- - ); - } - - return ( - <> -
{t('update.title')}
-
-
- {t('update.date')}: {update.date ? update.date.replace(/\s.*/, '') : '-'} -
-
- {t('update.version')}: {update.version} -
-
-

- - {t('update.extra_info')}:{' '} - - {t('update.page')} - - -

-
-
- - -
- - ); -} +import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'; +import { Update } from '@tauri-apps/plugin-updater'; +import { Button, Progress } from 'antd'; +import { useState } from 'react'; +import { useTranslation } from 'react-i18next'; + +interface Props { + update: Update; +} + +export function UpdateModal({ update }: Props) { + const [total, setTotal] = useState(null); + const [current, setCurrent] = useState(0); + + const { t } = useTranslation(); + + const onDownload = async () => { + update.downloadAndInstall((progress) => { + if (progress.event === 'Started' && progress.data.contentLength) { + setTotal(progress.data.contentLength); + } + + if (progress.event === 'Progress') { + setCurrent((v) => v + progress.data.chunkLength * 1000); + } + + if (progress.event === 'Finished') { + setCurrent(total!); + } + }); + }; + + if (total != null) { + const percent = Math.floor((current / total) * 100); + return ( + <> +
+ {percent === 100 ? t('update.installing') : t('update.downloading')} +
+
+ +
+ + ); + } + + return ( + <> +
{t('update.title')}
+
+
+ {t('update.date')}: {update.date ? update.date.replace(/\s.*/, '') : '-'} +
+
+ {t('update.version')}: {update.version} +
+
+

+ + {t('update.extra_info')}:{' '} + + {t('update.page')} + + +

+
+
+ + +
+ + ); +} diff --git a/src/background/error_handler.rs b/src/background/error_handler.rs index eb8a2e82..fe9e2973 100644 --- a/src/background/error_handler.rs +++ b/src/background/error_handler.rs @@ -1,116 +1,116 @@ -macro_rules! define_app_errors { - ($( - $variant:ident($error_type:ty); - )*) => { - #[derive(Debug)] - pub enum AppError { - $( - $variant($error_type), - )* - } - - $( - impl From<$error_type> for AppError { - fn from(err: $error_type) -> Self { - AppError::$variant(err) - } - } - )* - }; -} - -define_app_errors!( - Seelen(String); - Io(std::io::Error); - Tauri(tauri::Error); - TauriShell(tauri_plugin_shell::Error); - Eyre(color_eyre::eyre::Error); - Windows(windows::core::Error); - SerdeJson(serde_json::Error); - SerdeYaml(serde_yaml::Error); - Utf8(std::string::FromUtf8Error); - Utf16(std::string::FromUtf16Error); - CrossbeamRecv(crossbeam_channel::RecvError); - WinVD(winvd::Error); - TryFromInt(std::num::TryFromIntError); - Image(image::ImageError); - Battery(battery::Error); - FileNotify(notify::Error); - Base64Decode(base64::DecodeError); - WideStringNull(widestring::error::MissingNulTerminator); - Reqwest(tauri_plugin_http::reqwest::Error); -); - -impl From<&str> for AppError { - fn from(err: &str) -> Self { - AppError::Seelen(err.to_owned()) - } -} - -impl std::fmt::Display for AppError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self) - } -} - -// needed to tauri::command macro (exposed functions to frontend) -impl From for tauri::ipc::InvokeError { - fn from(val: AppError) -> Self { - tauri::ipc::InvokeError::from(val.to_string()) - } -} - -impl From for String { - fn from(err: AppError) -> String { - format!("{}", err) - } -} - -impl From for AppError { - fn from(output: tauri_plugin_shell::process::Output) -> Self { - if !output.stderr.is_empty() { - String::from_utf8(output.stderr) - .unwrap_or_default() - .trim() - .to_owned() - .into() - } else { - String::from_utf8(output.stdout) - .unwrap_or_default() - .trim() - .to_owned() - .into() - } - } -} - -impl std::error::Error for AppError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - AppError::Eyre(err) => Some(err.root_cause()), - AppError::Io(err) => Some(err), - AppError::Tauri(err) => Some(err), - AppError::Windows(err) => Some(err), - AppError::SerdeJson(err) => Some(err), - AppError::Utf8(err) => Some(err), - AppError::Utf16(err) => Some(err), - AppError::CrossbeamRecv(err) => Some(err), - AppError::TauriShell(err) => Some(err), - AppError::TryFromInt(err) => Some(err), - _ => None, - } - } -} - -pub type Result = core::result::Result; - -#[macro_export] -macro_rules! log_error { - ($($result:expr),*) => { - $( - if let Err(err) = $result { - log::error!("{:?}", err); - } - )* - }; -} +macro_rules! define_app_errors { + ($( + $variant:ident($error_type:ty); + )*) => { + #[derive(Debug)] + pub enum AppError { + $( + $variant($error_type), + )* + } + + $( + impl From<$error_type> for AppError { + fn from(err: $error_type) -> Self { + AppError::$variant(err) + } + } + )* + }; +} + +define_app_errors!( + Seelen(String); + Io(std::io::Error); + Tauri(tauri::Error); + TauriShell(tauri_plugin_shell::Error); + Eyre(color_eyre::eyre::Error); + Windows(windows::core::Error); + SerdeJson(serde_json::Error); + SerdeYaml(serde_yaml::Error); + Utf8(std::string::FromUtf8Error); + Utf16(std::string::FromUtf16Error); + CrossbeamRecv(crossbeam_channel::RecvError); + WinVD(winvd::Error); + TryFromInt(std::num::TryFromIntError); + Image(image::ImageError); + Battery(battery::Error); + FileNotify(notify::Error); + Base64Decode(base64::DecodeError); + WideStringNull(widestring::error::MissingNulTerminator); + Reqwest(tauri_plugin_http::reqwest::Error); +); + +impl From<&str> for AppError { + fn from(err: &str) -> Self { + AppError::Seelen(err.to_owned()) + } +} + +impl std::fmt::Display for AppError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +// needed to tauri::command macro (exposed functions to frontend) +impl From for tauri::ipc::InvokeError { + fn from(val: AppError) -> Self { + tauri::ipc::InvokeError::from(val.to_string()) + } +} + +impl From for String { + fn from(err: AppError) -> String { + format!("{}", err) + } +} + +impl From for AppError { + fn from(output: tauri_plugin_shell::process::Output) -> Self { + if !output.stderr.is_empty() { + String::from_utf8(output.stderr) + .unwrap_or_default() + .trim() + .to_owned() + .into() + } else { + String::from_utf8(output.stdout) + .unwrap_or_default() + .trim() + .to_owned() + .into() + } + } +} + +impl std::error::Error for AppError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + AppError::Eyre(err) => Some(err.root_cause()), + AppError::Io(err) => Some(err), + AppError::Tauri(err) => Some(err), + AppError::Windows(err) => Some(err), + AppError::SerdeJson(err) => Some(err), + AppError::Utf8(err) => Some(err), + AppError::Utf16(err) => Some(err), + AppError::CrossbeamRecv(err) => Some(err), + AppError::TauriShell(err) => Some(err), + AppError::TryFromInt(err) => Some(err), + _ => None, + } + } +} + +pub type Result = core::result::Result; + +#[macro_export] +macro_rules! log_error { + ($($result:expr),*) => { + $( + if let Err(err) = $result { + log::error!("{:?}", err); + } + )* + }; +} diff --git a/src/background/exposed.rs b/src/background/exposed.rs index 933522a7..4609c571 100644 --- a/src/background/exposed.rs +++ b/src/background/exposed.rs @@ -1,221 +1,221 @@ -use std::collections::HashMap; -use std::path::PathBuf; -use std::process::Command; - -use serde::Serialize; -use tauri::{command, Builder, Wry}; -use tauri_plugin_shell::ShellExt; - -use crate::error_handler::Result; -use crate::modules::input::Keyboard; -use crate::seelen::{get_app_handle, Seelen, SEELEN}; -use crate::seelen_weg::handler::*; -use crate::seelen_weg::icon_extractor::extract_and_save_icon; -use crate::seelen_wm::handler::*; -use crate::state::infrastructure::*; -use crate::system::brightness::*; -use crate::utils::{is_windows_10, is_windows_11}; -use crate::{log_error, trace_lock}; - -use crate::modules::media::infrastructure::*; -use crate::modules::network::infrastructure::*; -use crate::modules::notifications::infrastructure::*; -use crate::modules::power::infrastructure::*; -use crate::modules::tray::infrastructure::*; - -#[command] -fn start_seelen_shortcuts() { - std::thread::spawn(|| { - log_error!(Seelen::start_ahk_shortcuts()); - }); -} - -#[command] -fn kill_seelen_shortcuts() { - std::thread::spawn(|| { - Seelen::kill_ahk_shortcuts(); - }); -} - -#[command] -fn select_file_on_explorer(path: String) { - log_error!(Command::new("explorer").args(["/select,", &path]).spawn()); -} - -#[command] -fn open_file(path: String) { - log_error!(Command::new("explorer").args([&path]).spawn()); -} - -#[command] -fn run_as_admin(path: String) { - tauri::async_runtime::spawn(async move { - let app = get_app_handle(); - log_error!( - app.shell() - .command("powershell") - .args(["-Command", &format!("Start-Process '{}' -Verb runAs", path)]) - .status() - .await - ); - }); -} - -#[command] -fn run(program: String, args: Vec) { - tauri::async_runtime::spawn(async move { - log_error!( - get_app_handle() - .shell() - .command(program) - .args(args) - .status() - .await - ); - }); -} - -#[command] -fn is_dev_mode() -> bool { - tauri::is_dev() -} - -#[command] -pub fn get_user_envs() -> HashMap { - std::env::vars().collect::>() -} - -#[derive(Serialize)] -enum WinVersion { - Windows10, - Windows11, - Unknown, -} - -#[command] -fn get_win_version() -> WinVersion { - if is_windows_11() { - WinVersion::Windows11 - } else if is_windows_10() { - WinVersion::Windows10 - } else { - WinVersion::Unknown - } -} - -// https://docs.rs/tauri/latest/tauri/window/struct.WindowBuilder.html#known-issues -// https://github.com/tauri-apps/wry/issues/583 -#[command] -async fn show_app_settings() { - log_error!(Seelen::show_settings()); -} - -#[command] -fn set_auto_start(enabled: bool) { - std::thread::spawn(move || { - log_error!(Seelen::set_auto_start(enabled)); - }); -} - -#[command] -fn get_auto_start_status() -> Result { - Ok(Seelen::is_auto_start_enabled()?) -} - -#[command] -fn switch_workspace(idx: u32) { - std::thread::spawn(move || winvd::switch_desktop(idx)); -} - -#[command] -fn ensure_hitboxes_zorder() { - std::thread::spawn(|| -> Result<()> { - let seelen = trace_lock!(SEELEN); - for monitor in seelen.monitors() { - if let Some(toolbar) = monitor.toolbar() { - toolbar.ensure_hitbox_zorder()?; - } - if let Some(weg) = monitor.weg() { - weg.ensure_hitbox_zorder()?; - } - } - Ok(()) - }); -} - -#[command] -fn send_keys(keys: String) -> Result<()> { - Keyboard::new().send_keys(&keys) -} - -#[command] -fn get_icon(path: String) -> Option { - extract_and_save_icon(&get_app_handle(), &path).ok() -} - -pub fn register_invoke_handler(app_builder: Builder) -> Builder { - app_builder.invoke_handler(tauri::generate_handler![ - // General - run, - is_dev_mode, - open_file, - run_as_admin, - select_file_on_explorer, - get_win_version, - get_user_envs, - show_app_settings, - switch_workspace, - ensure_hitboxes_zorder, - send_keys, - get_icon, - // Seelen Settings - set_auto_start, - get_auto_start_status, - state_get_themes, - state_get_placeholders, - state_get_weg_items, - state_get_settings, - state_get_specific_apps_configurations, - state_get_wallpaper, - state_set_wallpaper, - // Media - media_prev, - media_toggle_play_pause, - media_next, - set_volume_level, - media_toggle_mute, - media_set_default_device, - // Brightness - get_main_monitor_brightness, - set_main_monitor_brightness, - // Power - log_out, - suspend, - restart, - shutdown, - // AHK - start_seelen_shortcuts, - kill_seelen_shortcuts, - // SeelenWeg - weg_close_app, - weg_toggle_window_state, - weg_request_update_previews, - // Windows Manager - set_window_position, - bounce_handle, - request_focus, - // tray icons - temp_get_by_event_tray_info, - on_click_tray_icon, - on_context_menu_tray_icon, - // network - wlan_get_profiles, - wlan_start_scanning, - wlan_stop_scanning, - wlan_connect, - wlan_disconnect, - // notifications - notifications_close, - notifications_close_all, - ]) -} +use std::collections::HashMap; +use std::path::PathBuf; +use std::process::Command; + +use serde::Serialize; +use tauri::{command, Builder, Wry}; +use tauri_plugin_shell::ShellExt; + +use crate::error_handler::Result; +use crate::modules::input::Keyboard; +use crate::seelen::{get_app_handle, Seelen, SEELEN}; +use crate::seelen_weg::handler::*; +use crate::seelen_weg::icon_extractor::extract_and_save_icon; +use crate::seelen_wm::handler::*; +use crate::state::infrastructure::*; +use crate::system::brightness::*; +use crate::utils::{is_windows_10, is_windows_11}; +use crate::{log_error, trace_lock}; + +use crate::modules::media::infrastructure::*; +use crate::modules::network::infrastructure::*; +use crate::modules::notifications::infrastructure::*; +use crate::modules::power::infrastructure::*; +use crate::modules::tray::infrastructure::*; + +#[command] +fn start_seelen_shortcuts() { + std::thread::spawn(|| { + log_error!(Seelen::start_ahk_shortcuts()); + }); +} + +#[command] +fn kill_seelen_shortcuts() { + std::thread::spawn(|| { + Seelen::kill_ahk_shortcuts(); + }); +} + +#[command] +fn select_file_on_explorer(path: String) { + log_error!(Command::new("explorer").args(["/select,", &path]).spawn()); +} + +#[command] +fn open_file(path: String) { + log_error!(Command::new("explorer").args([&path]).spawn()); +} + +#[command] +fn run_as_admin(path: String) { + tauri::async_runtime::spawn(async move { + let app = get_app_handle(); + log_error!( + app.shell() + .command("powershell") + .args(["-Command", &format!("Start-Process '{}' -Verb runAs", path)]) + .status() + .await + ); + }); +} + +#[command] +fn run(program: String, args: Vec) { + tauri::async_runtime::spawn(async move { + log_error!( + get_app_handle() + .shell() + .command(program) + .args(args) + .status() + .await + ); + }); +} + +#[command] +fn is_dev_mode() -> bool { + tauri::is_dev() +} + +#[command] +pub fn get_user_envs() -> HashMap { + std::env::vars().collect::>() +} + +#[derive(Serialize)] +enum WinVersion { + Windows10, + Windows11, + Unknown, +} + +#[command] +fn get_win_version() -> WinVersion { + if is_windows_11() { + WinVersion::Windows11 + } else if is_windows_10() { + WinVersion::Windows10 + } else { + WinVersion::Unknown + } +} + +// https://docs.rs/tauri/latest/tauri/window/struct.WindowBuilder.html#known-issues +// https://github.com/tauri-apps/wry/issues/583 +#[command] +async fn show_app_settings() { + log_error!(Seelen::show_settings()); +} + +#[command] +fn set_auto_start(enabled: bool) { + std::thread::spawn(move || { + log_error!(Seelen::set_auto_start(enabled)); + }); +} + +#[command] +fn get_auto_start_status() -> Result { + Ok(Seelen::is_auto_start_enabled()?) +} + +#[command] +fn switch_workspace(idx: u32) { + std::thread::spawn(move || winvd::switch_desktop(idx)); +} + +#[command] +fn ensure_hitboxes_zorder() { + std::thread::spawn(|| -> Result<()> { + let seelen = trace_lock!(SEELEN); + for monitor in seelen.monitors() { + if let Some(toolbar) = monitor.toolbar() { + toolbar.ensure_hitbox_zorder()?; + } + if let Some(weg) = monitor.weg() { + weg.ensure_hitbox_zorder()?; + } + } + Ok(()) + }); +} + +#[command] +fn send_keys(keys: String) -> Result<()> { + Keyboard::new().send_keys(&keys) +} + +#[command] +fn get_icon(path: String) -> Option { + extract_and_save_icon(&get_app_handle(), &path).ok() +} + +pub fn register_invoke_handler(app_builder: Builder) -> Builder { + app_builder.invoke_handler(tauri::generate_handler![ + // General + run, + is_dev_mode, + open_file, + run_as_admin, + select_file_on_explorer, + get_win_version, + get_user_envs, + show_app_settings, + switch_workspace, + ensure_hitboxes_zorder, + send_keys, + get_icon, + // Seelen Settings + set_auto_start, + get_auto_start_status, + state_get_themes, + state_get_placeholders, + state_get_weg_items, + state_get_settings, + state_get_specific_apps_configurations, + state_get_wallpaper, + state_set_wallpaper, + // Media + media_prev, + media_toggle_play_pause, + media_next, + set_volume_level, + media_toggle_mute, + media_set_default_device, + // Brightness + get_main_monitor_brightness, + set_main_monitor_brightness, + // Power + log_out, + suspend, + restart, + shutdown, + // AHK + start_seelen_shortcuts, + kill_seelen_shortcuts, + // SeelenWeg + weg_close_app, + weg_toggle_window_state, + weg_request_update_previews, + // Windows Manager + set_window_position, + bounce_handle, + request_focus, + // tray icons + temp_get_by_event_tray_info, + on_click_tray_icon, + on_context_menu_tray_icon, + // network + wlan_get_profiles, + wlan_start_scanning, + wlan_stop_scanning, + wlan_connect, + wlan_disconnect, + // notifications + notifications_close, + notifications_close_all, + ]) +} diff --git a/src/background/hook.rs b/src/background/hook.rs index fbb44ce7..11ef3df6 100644 --- a/src/background/hook.rs +++ b/src/background/hook.rs @@ -1,306 +1,306 @@ -use std::{ - collections::HashMap, - sync::{ - atomic::{AtomicIsize, Ordering}, - Arc, - }, - time::{Duration, Instant}, -}; - -use color_eyre::owo_colors::OwoColorize; -use lazy_static::lazy_static; -use parking_lot::Mutex; -use tauri::Emitter; -use windows::Win32::{ - Foundation::HWND, - UI::{ - Accessibility::{SetWinEventHook, HWINEVENTHOOK}, - WindowsAndMessaging::{ - DispatchMessageW, GetMessageW, TranslateMessage, EVENT_MAX, EVENT_MIN, MSG, - }, - }, -}; -use winvd::{listen_desktop_events, DesktopEvent}; - -use crate::{ - error_handler::Result, - log_error, - seelen::SEELEN, - seelen_weg::SeelenWeg, - state::{application::FULL_STATE, domain::AppExtraFlag}, - trace_lock, - utils::{constants::IGNORE_FOCUS, is_windows_11}, - windows_api::WindowsApi, - winevent::WinEvent, -}; - -lazy_static! { - pub static ref HOOK_MANAGER: Arc> = Arc::new(Mutex::new(HookManager::new())); -} - -type HookCallback = Box; -pub struct HookManager { - paused: bool, - waiting_event: Option, - waiting_hwnd: Option, - resume_cb: Option, -} - -impl HookManager { - pub fn new() -> Self { - Self { - paused: false, - waiting_event: None, - waiting_hwnd: None, - resume_cb: None, - } - } - - pub fn pause(&mut self) { - self.paused = true; - } - - pub fn resume(&mut self) { - self.paused = false; - if let Some(cb) = self.resume_cb.take() { - cb(self); - } - } - - pub fn is_paused(&self) -> bool { - self.paused - } - - pub fn pause_and_resume_after(&mut self, event: WinEvent, hwnd: HWND) { - self.pause(); - self.waiting_event = Some(event); - self.waiting_hwnd = Some(hwnd); - } - - pub fn set_resume_callback(&mut self, cb: F) - where - F: Fn(&mut HookManager) + Send + 'static, - { - self.resume_cb = Some(Box::new(cb)); - } - - pub fn is_waiting_for(&self, event: WinEvent, hwnd: HWND) -> bool { - self.waiting_event == Some(event) && self.waiting_hwnd == Some(hwnd) - } - - pub fn emit_fake_win_event(&mut self, event: u32, hwnd: HWND) { - std::thread::spawn(move || { - win_event_hook(HWINEVENTHOOK::default(), event, hwnd, 0, 0, 0, 0); - }); - } - - pub fn _log_event(event: WinEvent, origin: HWND) { - if event == WinEvent::ObjectLocationChange { - return; - } - - println!( - "{:?}({:x}) || {} || {} || {:<20}", - event.green(), - origin.0, - WindowsApi::exe(origin).unwrap_or_default(), - WindowsApi::get_class(origin).unwrap_or_default(), - WindowsApi::get_window_text(origin), - ); - } - - pub fn event(&mut self, event: WinEvent, origin: HWND) { - // uncomment for debug - // Self::_log_event(event, origin); - - if self.is_paused() { - if self.is_waiting_for(event, origin) { - self.resume(); - } - return; - } - - let title = WindowsApi::get_window_text(origin); - if (event == WinEvent::ObjectFocus || event == WinEvent::SystemForeground) - && IGNORE_FOCUS.contains(&title) - { - return; - } - - let mut seelen = trace_lock!(SEELEN); - if seelen.state().is_weg_enabled() { - log_error!(SeelenWeg::process_global_win_event(event, origin)); - } - - for monitor in seelen.monitors_mut() { - if let Some(toolbar) = monitor.toolbar_mut() { - log_error!(toolbar.process_win_event(event, origin)); - } - - if let Some(weg) = monitor.weg_mut() { - log_error!(weg.process_individual_win_event(event, origin)); - } - - if let Some(wm) = monitor.wm_mut() { - log_error!(wm.process_win_event(event, origin)); - } - } - } -} - -pub fn process_vd_event(event: DesktopEvent) -> Result<()> { - let mut seelen = trace_lock!(SEELEN); - for monitor in seelen.monitors_mut() { - if let Some(wm) = monitor.wm_mut() { - log_error!(wm.process_vd_event(&event)); - } - } - - match event { - DesktopEvent::DesktopCreated(_) - | DesktopEvent::DesktopDestroyed { - destroyed: _, - fallback: _, - } - | DesktopEvent::DesktopMoved { - desktop: _, - old_index: _, - new_index: _, - } - | DesktopEvent::DesktopNameChanged(_, _) => { - let desktops = winvd::get_desktops()?; - let mut desktops_names = Vec::new(); - for (i, d) in desktops.iter().enumerate() { - if let Ok(name) = d.get_name() { - desktops_names.push(name); - } else { - desktops_names.push(format!("Desktop {}", i + 1)) - } - } - seelen.handle().emit("workspaces-changed", desktops_names)?; - } - - DesktopEvent::DesktopChanged { new, old: _ } => { - seelen - .handle() - .emit("active-workspace-changed", new.get_index()?)?; - } - _ => {} - } - - if let DesktopEvent::WindowChanged(hwnd) = event { - if WindowsApi::is_window(hwnd) { - if let Some(config) = FULL_STATE.load().get_app_config_by_window(hwnd) { - if config.options_contains(AppExtraFlag::Pinned) && !winvd::is_pinned_window(hwnd)? - { - winvd::pin_window(hwnd)?; - } - } - } - } - - Ok(()) -} - -lazy_static! { - static ref DICT: Arc>> = Arc::new(Mutex::new(HashMap::new())); -} -static LAST_LOCATION_CHANGED: AtomicIsize = AtomicIsize::new(0); - -pub fn location_delay_completed(origin: HWND) -> bool { - let last = LAST_LOCATION_CHANGED.load(Ordering::Acquire); - let mut dict = trace_lock!(DICT); - - let should_continue = match dict.entry(origin.0) { - std::collections::hash_map::Entry::Occupied(mut entry) => { - if last != origin.0 || entry.get().elapsed() > Duration::from_millis(50) { - entry.insert(Instant::now()); - true - } else { - false - } - } - std::collections::hash_map::Entry::Vacant(entry) => { - entry.insert(Instant::now()); - true - } - }; - - if should_continue { - LAST_LOCATION_CHANGED.store(origin.0, Ordering::Release); - } - - should_continue -} - -pub extern "system" fn win_event_hook( - _h_win_event_hook: HWINEVENTHOOK, - event: u32, - hwnd: HWND, - id_object: i32, - _id_child: i32, - _id_event_thread: u32, - _dwms_event_time: u32, -) { - if id_object != 0 { - return; - } - - if FULL_STATE.load().is_weg_enabled() { - // raw events should be only used for a fastest and immediately processing - log_error!(SeelenWeg::process_raw_win_event(event, hwnd)); - } - - let event = match WinEvent::try_from(event) { - Ok(event) => event, - Err(_) => return, - }; - - if event == WinEvent::ObjectLocationChange && !location_delay_completed(hwnd) { - return; - } - - let mut hook_manager = trace_lock!(HOOK_MANAGER); - hook_manager.event(event, hwnd); - - if let Some(synthetic_event) = event.get_synthetic(hwnd) { - hook_manager.event(synthetic_event, hwnd); - } -} - -pub fn register_win_hook() -> Result<()> { - log::trace!("Registering Windows and Virtual Desktop Hooks"); - - let stack_size = 5 * 1024 * 1024; // 5 MB - std::thread::Builder::new() - .name("win_event_hook".into()) - .stack_size(stack_size) - .spawn(move || unsafe { - SetWinEventHook(EVENT_MIN, EVENT_MAX, None, Some(win_event_hook), 0, 0, 0); - - let mut msg: MSG = MSG::default(); - loop { - if !GetMessageW(&mut msg, HWND(0), 0, 0).as_bool() { - log::info!("windows event processing shutdown"); - break; - }; - let _ = TranslateMessage(&msg); - DispatchMessageW(&msg); - std::thread::sleep(Duration::from_millis(10)); - } - })?; - - // Todo search why virtual desktop events are not working on windows 10 - if is_windows_11() { - std::thread::spawn(move || -> Result<()> { - let (sender, receiver) = std::sync::mpsc::channel::(); - let _notifications_thread = listen_desktop_events(sender)?; - for event in receiver { - log_error!(process_vd_event(event)) - } - Ok(()) - }); - } - - Ok(()) -} +use std::{ + collections::HashMap, + sync::{ + atomic::{AtomicIsize, Ordering}, + Arc, + }, + time::{Duration, Instant}, +}; + +use color_eyre::owo_colors::OwoColorize; +use lazy_static::lazy_static; +use parking_lot::Mutex; +use tauri::Emitter; +use windows::Win32::{ + Foundation::HWND, + UI::{ + Accessibility::{SetWinEventHook, HWINEVENTHOOK}, + WindowsAndMessaging::{ + DispatchMessageW, GetMessageW, TranslateMessage, EVENT_MAX, EVENT_MIN, MSG, + }, + }, +}; +use winvd::{listen_desktop_events, DesktopEvent}; + +use crate::{ + error_handler::Result, + log_error, + seelen::SEELEN, + seelen_weg::SeelenWeg, + state::{application::FULL_STATE, domain::AppExtraFlag}, + trace_lock, + utils::{constants::IGNORE_FOCUS, is_windows_11}, + windows_api::WindowsApi, + winevent::WinEvent, +}; + +lazy_static! { + pub static ref HOOK_MANAGER: Arc> = Arc::new(Mutex::new(HookManager::new())); +} + +type HookCallback = Box; +pub struct HookManager { + paused: bool, + waiting_event: Option, + waiting_hwnd: Option, + resume_cb: Option, +} + +impl HookManager { + pub fn new() -> Self { + Self { + paused: false, + waiting_event: None, + waiting_hwnd: None, + resume_cb: None, + } + } + + pub fn pause(&mut self) { + self.paused = true; + } + + pub fn resume(&mut self) { + self.paused = false; + if let Some(cb) = self.resume_cb.take() { + cb(self); + } + } + + pub fn is_paused(&self) -> bool { + self.paused + } + + pub fn pause_and_resume_after(&mut self, event: WinEvent, hwnd: HWND) { + self.pause(); + self.waiting_event = Some(event); + self.waiting_hwnd = Some(hwnd); + } + + pub fn set_resume_callback(&mut self, cb: F) + where + F: Fn(&mut HookManager) + Send + 'static, + { + self.resume_cb = Some(Box::new(cb)); + } + + pub fn is_waiting_for(&self, event: WinEvent, hwnd: HWND) -> bool { + self.waiting_event == Some(event) && self.waiting_hwnd == Some(hwnd) + } + + pub fn emit_fake_win_event(&mut self, event: u32, hwnd: HWND) { + std::thread::spawn(move || { + win_event_hook(HWINEVENTHOOK::default(), event, hwnd, 0, 0, 0, 0); + }); + } + + pub fn _log_event(event: WinEvent, origin: HWND) { + if event == WinEvent::ObjectLocationChange { + return; + } + + println!( + "{:?}({:x}) || {} || {} || {:<20}", + event.green(), + origin.0, + WindowsApi::exe(origin).unwrap_or_default(), + WindowsApi::get_class(origin).unwrap_or_default(), + WindowsApi::get_window_text(origin), + ); + } + + pub fn event(&mut self, event: WinEvent, origin: HWND) { + // uncomment for debug + // Self::_log_event(event, origin); + + if self.is_paused() { + if self.is_waiting_for(event, origin) { + self.resume(); + } + return; + } + + let title = WindowsApi::get_window_text(origin); + if (event == WinEvent::ObjectFocus || event == WinEvent::SystemForeground) + && IGNORE_FOCUS.contains(&title) + { + return; + } + + let mut seelen = trace_lock!(SEELEN); + if seelen.state().is_weg_enabled() { + log_error!(SeelenWeg::process_global_win_event(event, origin)); + } + + for monitor in seelen.monitors_mut() { + if let Some(toolbar) = monitor.toolbar_mut() { + log_error!(toolbar.process_win_event(event, origin)); + } + + if let Some(weg) = monitor.weg_mut() { + log_error!(weg.process_individual_win_event(event, origin)); + } + + if let Some(wm) = monitor.wm_mut() { + log_error!(wm.process_win_event(event, origin)); + } + } + } +} + +pub fn process_vd_event(event: DesktopEvent) -> Result<()> { + let mut seelen = trace_lock!(SEELEN); + for monitor in seelen.monitors_mut() { + if let Some(wm) = monitor.wm_mut() { + log_error!(wm.process_vd_event(&event)); + } + } + + match event { + DesktopEvent::DesktopCreated(_) + | DesktopEvent::DesktopDestroyed { + destroyed: _, + fallback: _, + } + | DesktopEvent::DesktopMoved { + desktop: _, + old_index: _, + new_index: _, + } + | DesktopEvent::DesktopNameChanged(_, _) => { + let desktops = winvd::get_desktops()?; + let mut desktops_names = Vec::new(); + for (i, d) in desktops.iter().enumerate() { + if let Ok(name) = d.get_name() { + desktops_names.push(name); + } else { + desktops_names.push(format!("Desktop {}", i + 1)) + } + } + seelen.handle().emit("workspaces-changed", desktops_names)?; + } + + DesktopEvent::DesktopChanged { new, old: _ } => { + seelen + .handle() + .emit("active-workspace-changed", new.get_index()?)?; + } + _ => {} + } + + if let DesktopEvent::WindowChanged(hwnd) = event { + if WindowsApi::is_window(hwnd) { + if let Some(config) = FULL_STATE.load().get_app_config_by_window(hwnd) { + if config.options_contains(AppExtraFlag::Pinned) && !winvd::is_pinned_window(hwnd)? + { + winvd::pin_window(hwnd)?; + } + } + } + } + + Ok(()) +} + +lazy_static! { + static ref DICT: Arc>> = Arc::new(Mutex::new(HashMap::new())); +} +static LAST_LOCATION_CHANGED: AtomicIsize = AtomicIsize::new(0); + +pub fn location_delay_completed(origin: HWND) -> bool { + let last = LAST_LOCATION_CHANGED.load(Ordering::Acquire); + let mut dict = trace_lock!(DICT); + + let should_continue = match dict.entry(origin.0) { + std::collections::hash_map::Entry::Occupied(mut entry) => { + if last != origin.0 || entry.get().elapsed() > Duration::from_millis(50) { + entry.insert(Instant::now()); + true + } else { + false + } + } + std::collections::hash_map::Entry::Vacant(entry) => { + entry.insert(Instant::now()); + true + } + }; + + if should_continue { + LAST_LOCATION_CHANGED.store(origin.0, Ordering::Release); + } + + should_continue +} + +pub extern "system" fn win_event_hook( + _h_win_event_hook: HWINEVENTHOOK, + event: u32, + hwnd: HWND, + id_object: i32, + _id_child: i32, + _id_event_thread: u32, + _dwms_event_time: u32, +) { + if id_object != 0 { + return; + } + + if FULL_STATE.load().is_weg_enabled() { + // raw events should be only used for a fastest and immediately processing + log_error!(SeelenWeg::process_raw_win_event(event, hwnd)); + } + + let event = match WinEvent::try_from(event) { + Ok(event) => event, + Err(_) => return, + }; + + if event == WinEvent::ObjectLocationChange && !location_delay_completed(hwnd) { + return; + } + + let mut hook_manager = trace_lock!(HOOK_MANAGER); + hook_manager.event(event, hwnd); + + if let Some(synthetic_event) = event.get_synthetic(hwnd) { + hook_manager.event(synthetic_event, hwnd); + } +} + +pub fn register_win_hook() -> Result<()> { + log::trace!("Registering Windows and Virtual Desktop Hooks"); + + let stack_size = 5 * 1024 * 1024; // 5 MB + std::thread::Builder::new() + .name("win_event_hook".into()) + .stack_size(stack_size) + .spawn(move || unsafe { + SetWinEventHook(EVENT_MIN, EVENT_MAX, None, Some(win_event_hook), 0, 0, 0); + + let mut msg: MSG = MSG::default(); + loop { + if !GetMessageW(&mut msg, HWND(0), 0, 0).as_bool() { + log::info!("windows event processing shutdown"); + break; + }; + let _ = TranslateMessage(&msg); + DispatchMessageW(&msg); + std::thread::sleep(Duration::from_millis(10)); + } + })?; + + // Todo search why virtual desktop events are not working on windows 10 + if is_windows_11() { + std::thread::spawn(move || -> Result<()> { + let (sender, receiver) = std::sync::mpsc::channel::(); + let _notifications_thread = listen_desktop_events(sender)?; + for event in receiver { + log_error!(process_vd_event(event)) + } + Ok(()) + }); + } + + Ok(()) +} diff --git a/src/background/main.rs b/src/background/main.rs index ec813a1e..942fc0de 100644 --- a/src/background/main.rs +++ b/src/background/main.rs @@ -1,160 +1,160 @@ -// Prevents additional console window on Windows in release -#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] - -mod error_handler; -mod exposed; -mod hook; -mod modules; -mod monitor; -mod plugins; -mod seelen; -mod seelen_bar; -mod seelen_shell; -mod seelen_weg; -mod seelen_wm; -mod state; -mod system; -mod tray; -mod utils; -mod windows_api; -mod winevent; - -use std::io::{BufWriter, Write}; - -use color_eyre::owo_colors::OwoColorize; -use error_handler::Result; -use exposed::register_invoke_handler; -use itertools::Itertools; -use modules::{ - cli::{ - application::{attach_console, is_just_getting_info, SEELEN_COMMAND_LINE}, - Client, - }, - tray::application::ensure_tray_overflow_creation, -}; -use plugins::register_plugins; -use seelen::{Seelen, SEELEN}; -use tray::try_register_tray_icon; -use utils::PERFORMANCE_HELPER; - -fn register_panic_hook() { - std::panic::set_hook(Box::new(|info| { - let cause = info - .payload() - .downcast_ref::() - .map(|s| s.to_string()) - .unwrap_or_else(|| { - info.payload() - .downcast_ref::<&str>() - .unwrap_or(&"") - .to_string() - }); - - let mut string_location = String::from(""); - if let Some(location) = info.location() { - string_location = format!( - "{}:{}:{}", - location.file(), - location.line(), - location.column() - ); - } - - log::error!( - "A panic occurred:\n Cause: {}\n Location: {}", - cause.cyan(), - string_location.purple() - ); - })); -} - -fn setup(app: &mut tauri::App) -> Result<(), Box> { - log::info!("───────────────────── Starting Seelen ─────────────────────"); - Client::listen_tcp()?; - // try it at start it on open the program to avoid do it before - log_error!(ensure_tray_overflow_creation()); - - let mut seelen = unsafe { SEELEN.make_guard_unchecked() }; - seelen.init(app.handle().clone())?; - - if !tauri::is_dev() { - Seelen::show_update_modal()?; - let command = trace_lock!(SEELEN_COMMAND_LINE).clone(); - let matches = command.get_matches(); - if !matches.get_flag("silent") { - Seelen::show_settings()?; - } - } - - seelen.start()?; - - log_error!(try_register_tray_icon(app)); - std::mem::forget(seelen); - Ok(()) -} - -fn app_callback(_: &tauri::AppHandle, event: tauri::RunEvent) { - match event { - tauri::RunEvent::ExitRequested { api, code, .. } => { - // prevent close background on webview windows closing - if code.is_none() { - api.prevent_exit(); - } - } - tauri::RunEvent::Exit => { - log::info!("───────────────────── Exiting Seelen ─────────────────────"); - trace_lock!(SEELEN).stop() - } - _ => {} - } -} - -fn main() -> Result<()> { - color_eyre::install().expect("Failed to install color_eyre"); - register_panic_hook(); - PERFORMANCE_HELPER.lock().start(); - - let command = trace_lock!(SEELEN_COMMAND_LINE).clone(); - let matches = match command.try_get_matches() { - Ok(m) => m, - // (help, --help or -h) is also managed as error - Err(e) => { - attach_console()?; - e.print()?; - return Ok(()); - } - }; - - if is_just_getting_info(&matches)? { - return Ok(()); - } - - let mut sys = sysinfo::System::new(); - sys.refresh_processes(); - let already_running = sys.processes_by_name("seelen-ui.exe").collect_vec().len() > 1; - - if already_running { - if let Ok(stream) = Client::connect_tcp() { - let mut writer = BufWriter::new(stream); - - let args = std::env::args().collect_vec(); - let msg = serde_json::to_string(&args).expect("could not serialize"); - - writer.write_all(msg.as_bytes()).expect("could not write"); - writer.flush().expect("could not flush"); - } - return Ok(()); - } - - let mut app_builder = tauri::Builder::default(); - app_builder = register_plugins(app_builder); - app_builder = register_invoke_handler(app_builder); - - let app = app_builder - .setup(setup) - .build(tauri::generate_context!()) - .expect("error while building tauri application"); - - app.run(app_callback); - Ok(()) -} +// Prevents additional console window on Windows in release +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +mod error_handler; +mod exposed; +mod hook; +mod modules; +mod monitor; +mod plugins; +mod seelen; +mod seelen_bar; +mod seelen_shell; +mod seelen_weg; +mod seelen_wm; +mod state; +mod system; +mod tray; +mod utils; +mod windows_api; +mod winevent; + +use std::io::{BufWriter, Write}; + +use color_eyre::owo_colors::OwoColorize; +use error_handler::Result; +use exposed::register_invoke_handler; +use itertools::Itertools; +use modules::{ + cli::{ + application::{attach_console, is_just_getting_info, SEELEN_COMMAND_LINE}, + Client, + }, + tray::application::ensure_tray_overflow_creation, +}; +use plugins::register_plugins; +use seelen::{Seelen, SEELEN}; +use tray::try_register_tray_icon; +use utils::PERFORMANCE_HELPER; + +fn register_panic_hook() { + std::panic::set_hook(Box::new(|info| { + let cause = info + .payload() + .downcast_ref::() + .map(|s| s.to_string()) + .unwrap_or_else(|| { + info.payload() + .downcast_ref::<&str>() + .unwrap_or(&"") + .to_string() + }); + + let mut string_location = String::from(""); + if let Some(location) = info.location() { + string_location = format!( + "{}:{}:{}", + location.file(), + location.line(), + location.column() + ); + } + + log::error!( + "A panic occurred:\n Cause: {}\n Location: {}", + cause.cyan(), + string_location.purple() + ); + })); +} + +fn setup(app: &mut tauri::App) -> Result<(), Box> { + log::info!("───────────────────── Starting Seelen ─────────────────────"); + Client::listen_tcp()?; + // try it at start it on open the program to avoid do it before + log_error!(ensure_tray_overflow_creation()); + + let mut seelen = unsafe { SEELEN.make_guard_unchecked() }; + seelen.init(app.handle().clone())?; + + if !tauri::is_dev() { + Seelen::show_update_modal()?; + let command = trace_lock!(SEELEN_COMMAND_LINE).clone(); + let matches = command.get_matches(); + if !matches.get_flag("silent") { + Seelen::show_settings()?; + } + } + + seelen.start()?; + + log_error!(try_register_tray_icon(app)); + std::mem::forget(seelen); + Ok(()) +} + +fn app_callback(_: &tauri::AppHandle, event: tauri::RunEvent) { + match event { + tauri::RunEvent::ExitRequested { api, code, .. } => { + // prevent close background on webview windows closing + if code.is_none() { + api.prevent_exit(); + } + } + tauri::RunEvent::Exit => { + log::info!("───────────────────── Exiting Seelen ─────────────────────"); + trace_lock!(SEELEN).stop() + } + _ => {} + } +} + +fn main() -> Result<()> { + color_eyre::install().expect("Failed to install color_eyre"); + register_panic_hook(); + PERFORMANCE_HELPER.lock().start(); + + let command = trace_lock!(SEELEN_COMMAND_LINE).clone(); + let matches = match command.try_get_matches() { + Ok(m) => m, + // (help, --help or -h) is also managed as error + Err(e) => { + attach_console()?; + e.print()?; + return Ok(()); + } + }; + + if is_just_getting_info(&matches)? { + return Ok(()); + } + + let mut sys = sysinfo::System::new(); + sys.refresh_processes(); + let already_running = sys.processes_by_name("seelen-ui.exe").collect_vec().len() > 1; + + if already_running { + if let Ok(stream) = Client::connect_tcp() { + let mut writer = BufWriter::new(stream); + + let args = std::env::args().collect_vec(); + let msg = serde_json::to_string(&args).expect("could not serialize"); + + writer.write_all(msg.as_bytes()).expect("could not write"); + writer.flush().expect("could not flush"); + } + return Ok(()); + } + + let mut app_builder = tauri::Builder::default(); + app_builder = register_plugins(app_builder); + app_builder = register_invoke_handler(app_builder); + + let app = app_builder + .setup(setup) + .build(tauri::generate_context!()) + .expect("error while building tauri application"); + + app.run(app_callback); + Ok(()) +} diff --git a/src/background/modules/cli/application.rs b/src/background/modules/cli/application.rs index ff9f842d..22e6e2bc 100644 --- a/src/background/modules/cli/application.rs +++ b/src/background/modules/cli/application.rs @@ -1,205 +1,205 @@ -use std::ffi::OsStr; -use std::path::PathBuf; -use std::sync::Arc; - -use base64::Engine; -use clap::{Arg, ArgAction, Command}; -use lazy_static::lazy_static; -use parking_lot::Mutex; -use windows::Win32::System::Console::{AttachConsole, FreeConsole, ATTACH_PARENT_PROCESS}; - -use crate::error_handler::Result; -use crate::seelen::{Seelen, SEELEN}; -use crate::seelen_bar::FancyToolbar; -use crate::seelen_wm::WindowManager; -use crate::state::application::FULL_STATE; -use crate::trace_lock; - -#[macro_export] -macro_rules! get_subcommands { - ($( - #[$meta:meta] - $subcommand:ident $(($($arg_name:ident: $arg_type:ty => $arg_desc:literal),*))?, - )*) => { - #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] - enum SubCommand { - $( - #[$meta] - $subcommand$(($($arg_type),*))?, - )* - } - - impl SubCommand { - pub fn commands() -> Vec { - let mut commands = Vec::new(); - $( - commands.push({ - let args: Vec = vec![ - $($( - clap::Arg::new(stringify!($arg_name)) - .help($arg_desc) - .action(clap::ArgAction::Set) - .value_parser(clap::value_parser!($arg_type)) - .required(true) - ),*)? - ]; - - let about = stringify!($meta).trim_start_matches("doc = r\"").trim_end_matches("\"").trim(); - let command = $crate::utils::pascal_to_kebab(stringify!($subcommand)); - Command::new(command).about(about).args(args) - }); - )* - commands - } - - fn try_from(matches: &clap::ArgMatches) -> $crate::error_handler::Result { - #[allow(unused_variables)] - if let Some((subcommand, sub_matches)) = matches.subcommand() { - match $crate::utils::kebab_to_pascal(subcommand).as_str() { - $( - stringify!($subcommand) => { - Ok(SubCommand::$subcommand$(($((sub_matches.get_one(stringify!($arg_name)) as Option<&$arg_type>).unwrap().clone()),*))?) - }, - )* - _ => Err(color_eyre::eyre::eyre!("Unknown subcommand.").into()), - } - } else { - Err(color_eyre::eyre::eyre!("No subcommand was provided.").into()) - } - } - } - } -} - -lazy_static! { - pub static ref SEELEN_COMMAND_LINE: Arc> = Arc::new(Mutex::new( - Command::new("Seelen") - .author("eythaann") - .about("Seelen Command Line Interface.") - .long_about("Seelen Command Line Interface.") - .before_help("") - .after_help("To read more about Seelen visit https://github.com/eythaann/seelen-ui.git") - .args([ - Arg::new("silent") - .short('s') - .long("silent") - .action(ArgAction::SetTrue) - .help("Start only background processes."), - Arg::new("verbose") - .short('V') - .long("verbose") - .action(ArgAction::SetTrue) - .help("Prints some extra process on the console."), - Arg::new("version") - .short('v') - .long("version") - .action(ArgAction::SetTrue) - .help("Prints the current version of Seelen."), - Arg::new("uri") - .help("Path or URI to load.") - .long_help("Path or URI to load. (example: 'C:\\path\\to\\file.slu' or 'seelen-ui.uri:example')") - .value_parser(clap::value_parser!(std::string::String)) - .action(clap::ArgAction::Set) - ]) - .subcommands([ - Command::new("settings").about("Opens the Seelen settings gui."), - WindowManager::get_cli(), - FancyToolbar::get_cli(), - ]) - )); -} - -pub fn attach_console() -> Result<()> { - if !tauri::is_dev() { - unsafe { AttachConsole(ATTACH_PARENT_PROCESS)? }; - } - Ok(()) -} - -pub fn detach_console() -> Result<()> { - if !tauri::is_dev() { - unsafe { FreeConsole()? }; - } - Ok(()) -} - -pub fn is_just_getting_info(matches: &clap::ArgMatches) -> Result { - let mut r = false; - - if matches.get_flag("verbose") { - attach_console()?; - println!("{:?}", matches); - detach_console()?; - } - - if matches.get_flag("version") { - attach_console()?; - println!("{}", env!("CARGO_PKG_VERSION")); - detach_console()?; - r = true; - } - - Ok(r) -} - -const URI: &str = "seelen-ui.uri:"; -const URI_MSIX: &str = "seelen-ui-msix.uri:"; - -pub fn process_uri(uri: &str) -> Result<()> { - log::trace!("Loading URI: {}", uri); - - let contents = if uri.starts_with(URI) { - uri.trim_start_matches(URI).to_string() - } else if uri.starts_with(URI_MSIX) { - uri.trim_start_matches(URI_MSIX).to_string() - } else { - let path = PathBuf::from(uri); - if path.is_file() && path.extension() == Some(OsStr::new("slu")) && path.exists() { - std::fs::read_to_string(path)? - } else { - return Err("Invalid URI format".into()); - } - }; - - let engine = base64::engine::general_purpose::URL_SAFE_NO_PAD; - let decoded = engine.decode(contents.as_bytes())?; - - let mut state = FULL_STATE.load().cloned(); - state.load_resource(serde_yaml::from_slice(&decoded)?)?; - state.store(); - Ok(()) -} - -pub fn handle_cli_events(matches: &clap::ArgMatches) -> Result<()> { - if let Some(uri) = matches.get_one::("uri") { - return process_uri(uri).map_err(|e| format!("Corrupted SLU file: {}", e).into()); - } - - if let Some((subcommand, matches)) = matches.subcommand() { - match subcommand { - "settings" => { - Seelen::show_settings()?; - } - WindowManager::CLI_IDENTIFIER => { - if let Some(monitor) = trace_lock!(SEELEN).focused_monitor_mut() { - if let Some(wm) = monitor.wm_mut() { - wm.process(matches)?; - } - } - } - FancyToolbar::CLI_IDENTIFIER => { - let mut seelen = trace_lock!(SEELEN); - for monitor in seelen.monitors_mut() { - if let Some(toolbar) = monitor.toolbar_mut() { - toolbar.process(matches)?; - } - } - } - _ => {} - } - return Ok(()); - } - - Seelen::show_settings()?; - Ok(()) -} +use std::ffi::OsStr; +use std::path::PathBuf; +use std::sync::Arc; + +use base64::Engine; +use clap::{Arg, ArgAction, Command}; +use lazy_static::lazy_static; +use parking_lot::Mutex; +use windows::Win32::System::Console::{AttachConsole, FreeConsole, ATTACH_PARENT_PROCESS}; + +use crate::error_handler::Result; +use crate::seelen::{Seelen, SEELEN}; +use crate::seelen_bar::FancyToolbar; +use crate::seelen_wm::WindowManager; +use crate::state::application::FULL_STATE; +use crate::trace_lock; + +#[macro_export] +macro_rules! get_subcommands { + ($( + #[$meta:meta] + $subcommand:ident $(($($arg_name:ident: $arg_type:ty => $arg_desc:literal),*))?, + )*) => { + #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] + enum SubCommand { + $( + #[$meta] + $subcommand$(($($arg_type),*))?, + )* + } + + impl SubCommand { + pub fn commands() -> Vec { + let mut commands = Vec::new(); + $( + commands.push({ + let args: Vec = vec![ + $($( + clap::Arg::new(stringify!($arg_name)) + .help($arg_desc) + .action(clap::ArgAction::Set) + .value_parser(clap::value_parser!($arg_type)) + .required(true) + ),*)? + ]; + + let about = stringify!($meta).trim_start_matches("doc = r\"").trim_end_matches("\"").trim(); + let command = $crate::utils::pascal_to_kebab(stringify!($subcommand)); + Command::new(command).about(about).args(args) + }); + )* + commands + } + + fn try_from(matches: &clap::ArgMatches) -> $crate::error_handler::Result { + #[allow(unused_variables)] + if let Some((subcommand, sub_matches)) = matches.subcommand() { + match $crate::utils::kebab_to_pascal(subcommand).as_str() { + $( + stringify!($subcommand) => { + Ok(SubCommand::$subcommand$(($((sub_matches.get_one(stringify!($arg_name)) as Option<&$arg_type>).unwrap().clone()),*))?) + }, + )* + _ => Err(color_eyre::eyre::eyre!("Unknown subcommand.").into()), + } + } else { + Err(color_eyre::eyre::eyre!("No subcommand was provided.").into()) + } + } + } + } +} + +lazy_static! { + pub static ref SEELEN_COMMAND_LINE: Arc> = Arc::new(Mutex::new( + Command::new("Seelen") + .author("eythaann") + .about("Seelen Command Line Interface.") + .long_about("Seelen Command Line Interface.") + .before_help("") + .after_help("To read more about Seelen visit https://github.com/eythaann/seelen-ui.git") + .args([ + Arg::new("silent") + .short('s') + .long("silent") + .action(ArgAction::SetTrue) + .help("Start only background processes."), + Arg::new("verbose") + .short('V') + .long("verbose") + .action(ArgAction::SetTrue) + .help("Prints some extra process on the console."), + Arg::new("version") + .short('v') + .long("version") + .action(ArgAction::SetTrue) + .help("Prints the current version of Seelen."), + Arg::new("uri") + .help("Path or URI to load.") + .long_help("Path or URI to load. (example: 'C:\\path\\to\\file.slu' or 'seelen-ui.uri:example')") + .value_parser(clap::value_parser!(std::string::String)) + .action(clap::ArgAction::Set) + ]) + .subcommands([ + Command::new("settings").about("Opens the Seelen settings gui."), + WindowManager::get_cli(), + FancyToolbar::get_cli(), + ]) + )); +} + +pub fn attach_console() -> Result<()> { + if !tauri::is_dev() { + unsafe { AttachConsole(ATTACH_PARENT_PROCESS)? }; + } + Ok(()) +} + +pub fn detach_console() -> Result<()> { + if !tauri::is_dev() { + unsafe { FreeConsole()? }; + } + Ok(()) +} + +pub fn is_just_getting_info(matches: &clap::ArgMatches) -> Result { + let mut r = false; + + if matches.get_flag("verbose") { + attach_console()?; + println!("{:?}", matches); + detach_console()?; + } + + if matches.get_flag("version") { + attach_console()?; + println!("{}", env!("CARGO_PKG_VERSION")); + detach_console()?; + r = true; + } + + Ok(r) +} + +const URI: &str = "seelen-ui.uri:"; +const URI_MSIX: &str = "seelen-ui-msix.uri:"; + +pub fn process_uri(uri: &str) -> Result<()> { + log::trace!("Loading URI: {}", uri); + + let contents = if uri.starts_with(URI) { + uri.trim_start_matches(URI).to_string() + } else if uri.starts_with(URI_MSIX) { + uri.trim_start_matches(URI_MSIX).to_string() + } else { + let path = PathBuf::from(uri); + if path.is_file() && path.extension() == Some(OsStr::new("slu")) && path.exists() { + std::fs::read_to_string(path)? + } else { + return Err("Invalid URI format".into()); + } + }; + + let engine = base64::engine::general_purpose::URL_SAFE_NO_PAD; + let decoded = engine.decode(contents.as_bytes())?; + + let mut state = FULL_STATE.load().cloned(); + state.load_resource(serde_yaml::from_slice(&decoded)?)?; + state.store(); + Ok(()) +} + +pub fn handle_cli_events(matches: &clap::ArgMatches) -> Result<()> { + if let Some(uri) = matches.get_one::("uri") { + return process_uri(uri).map_err(|e| format!("Corrupted SLU file: {}", e).into()); + } + + if let Some((subcommand, matches)) = matches.subcommand() { + match subcommand { + "settings" => { + Seelen::show_settings()?; + } + WindowManager::CLI_IDENTIFIER => { + if let Some(monitor) = trace_lock!(SEELEN).focused_monitor_mut() { + if let Some(wm) = monitor.wm_mut() { + wm.process(matches)?; + } + } + } + FancyToolbar::CLI_IDENTIFIER => { + let mut seelen = trace_lock!(SEELEN); + for monitor in seelen.monitors_mut() { + if let Some(toolbar) = monitor.toolbar_mut() { + toolbar.process(matches)?; + } + } + } + _ => {} + } + return Ok(()); + } + + Seelen::show_settings()?; + Ok(()) +} diff --git a/src/background/modules/cli/domain.rs b/src/background/modules/cli/domain.rs index f34aabf3..d517c3b1 100644 --- a/src/background/modules/cli/domain.rs +++ b/src/background/modules/cli/domain.rs @@ -1,18 +1,18 @@ -use serde::{Deserialize, Serialize}; - -use crate::state::domain::{Placeholder, Theme}; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Resource { - pub id: String, - /// Url of wallpaper - pub wallpaper: Option, - pub resources: ResourceItems, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ResourceItems { - pub theme: Option, - pub placeholder: Option, - pub layout: Option, -} +use serde::{Deserialize, Serialize}; + +use crate::state::domain::{Placeholder, Theme}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Resource { + pub id: String, + /// Url of wallpaper + pub wallpaper: Option, + pub resources: ResourceItems, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ResourceItems { + pub theme: Option, + pub placeholder: Option, + pub layout: Option, +} diff --git a/src/background/modules/cli/mod.rs b/src/background/modules/cli/mod.rs index a0d69a27..2e87736f 100644 --- a/src/background/modules/cli/mod.rs +++ b/src/background/modules/cli/mod.rs @@ -1,74 +1,74 @@ -pub mod application; -pub mod domain; - -use std::{ - fs, - io::{BufReader, Read}, - net::{TcpListener, TcpStream}, -}; - -use application::{handle_cli_events, SEELEN_COMMAND_LINE}; - -use crate::{error_handler::Result, log_error, trace_lock}; - -pub struct Client; -impl Client { - const BUFFER_SIZE: usize = 5 * 1024 * 1024; // 5 MB - - fn handle_message(stream: TcpStream) { - let mut reader = BufReader::new(stream); - let mut buffer = vec![]; - match reader.read_to_end(&mut buffer) { - Ok(_) => { - let message = String::from_utf8_lossy(&buffer).to_string(); - match serde_json::from_str::>(&message) { - Ok(argv) => { - log::trace!(target: "slu::cli", "{}", argv[1..].join(" ")); - std::thread::spawn(move || { - let command = trace_lock!(SEELEN_COMMAND_LINE).clone(); - log_error!(handle_cli_events(&command.get_matches_from(argv))); - }); - } - Err(e) => { - log::error!("Failed to deserialize message: {}", e); - } - } - } - Err(e) => { - log::error!("Failed to read from stream: {}", e); - } - } - } - - pub fn listen_tcp() -> Result<()> { - let listener = TcpListener::bind("127.0.0.1:0")?; - let socket_addr = listener.local_addr()?; - let port = socket_addr.port(); - - log::info!("TCP server listening on 127.0.0.1:{}", port); - fs::write( - std::env::temp_dir().join("slu_tcp_socket"), - port.to_string(), - )?; - - std::thread::Builder::new() - .name("TCP Thread".to_string()) - .stack_size(Self::BUFFER_SIZE) - .spawn(move || { - for stream in listener.incoming() { - match stream { - Ok(stream) => Self::handle_message(stream), - Err(e) => { - log::error!("Failed to accept connection: {}", e); - } - } - } - })?; - Ok(()) - } - - pub fn connect_tcp() -> Result { - let port = fs::read_to_string(std::env::temp_dir().join("slu_tcp_socket"))?; - Ok(TcpStream::connect(format!("127.0.0.1:{}", port))?) - } -} +pub mod application; +pub mod domain; + +use std::{ + fs, + io::{BufReader, Read}, + net::{TcpListener, TcpStream}, +}; + +use application::{handle_cli_events, SEELEN_COMMAND_LINE}; + +use crate::{error_handler::Result, log_error, trace_lock}; + +pub struct Client; +impl Client { + const BUFFER_SIZE: usize = 5 * 1024 * 1024; // 5 MB + + fn handle_message(stream: TcpStream) { + let mut reader = BufReader::new(stream); + let mut buffer = vec![]; + match reader.read_to_end(&mut buffer) { + Ok(_) => { + let message = String::from_utf8_lossy(&buffer).to_string(); + match serde_json::from_str::>(&message) { + Ok(argv) => { + log::trace!(target: "slu::cli", "{}", argv[1..].join(" ")); + std::thread::spawn(move || { + let command = trace_lock!(SEELEN_COMMAND_LINE).clone(); + log_error!(handle_cli_events(&command.get_matches_from(argv))); + }); + } + Err(e) => { + log::error!("Failed to deserialize message: {}", e); + } + } + } + Err(e) => { + log::error!("Failed to read from stream: {}", e); + } + } + } + + pub fn listen_tcp() -> Result<()> { + let listener = TcpListener::bind("127.0.0.1:0")?; + let socket_addr = listener.local_addr()?; + let port = socket_addr.port(); + + log::info!("TCP server listening on 127.0.0.1:{}", port); + fs::write( + std::env::temp_dir().join("slu_tcp_socket"), + port.to_string(), + )?; + + std::thread::Builder::new() + .name("TCP Thread".to_string()) + .stack_size(Self::BUFFER_SIZE) + .spawn(move || { + for stream in listener.incoming() { + match stream { + Ok(stream) => Self::handle_message(stream), + Err(e) => { + log::error!("Failed to accept connection: {}", e); + } + } + } + })?; + Ok(()) + } + + pub fn connect_tcp() -> Result { + let port = fs::read_to_string(std::env::temp_dir().join("slu_tcp_socket"))?; + Ok(TcpStream::connect(format!("127.0.0.1:{}", port))?) + } +} diff --git a/src/background/modules/input/domain.rs b/src/background/modules/input/domain.rs index 71e17cb0..c8f8e0c6 100644 --- a/src/background/modules/input/domain.rs +++ b/src/background/modules/input/domain.rs @@ -1,64 +1,64 @@ -use std::fmt::Debug; -use std::fmt::Display; - -use windows::Win32::Foundation::POINT; - -/// A Point type stores the x and y position. -#[derive(Clone, Copy, PartialEq, Eq, Default)] -pub struct Point(POINT); - -impl Point { - /// Creates a new position. - pub fn new(x: i32, y: i32) -> Self { - Self(POINT { x, y }) - } - - /// Retrieves the x position. - pub fn get_x(&self) -> i32 { - self.0.x - } - - /// Retrieves the y position. - pub fn get_y(&self) -> i32 { - self.0.y - } -} - -impl Debug for Point { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Point") - .field("x", &self.0.x) - .field("y", &self.0.y) - .finish() - } -} - -impl Display for Point { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "({}, {})", self.0.x, self.0.y) - } -} - -impl From for Point { - fn from(point: POINT) -> Self { - Self(point) - } -} - -impl From for POINT { - fn from(val: Point) -> Self { - val.0 - } -} - -impl AsRef for Point { - fn as_ref(&self) -> &POINT { - &self.0 - } -} - -impl AsMut for Point { - fn as_mut(&mut self) -> &mut POINT { - &mut self.0 - } -} +use std::fmt::Debug; +use std::fmt::Display; + +use windows::Win32::Foundation::POINT; + +/// A Point type stores the x and y position. +#[derive(Clone, Copy, PartialEq, Eq, Default)] +pub struct Point(POINT); + +impl Point { + /// Creates a new position. + pub fn new(x: i32, y: i32) -> Self { + Self(POINT { x, y }) + } + + /// Retrieves the x position. + pub fn get_x(&self) -> i32 { + self.0.x + } + + /// Retrieves the y position. + pub fn get_y(&self) -> i32 { + self.0.y + } +} + +impl Debug for Point { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Point") + .field("x", &self.0.x) + .field("y", &self.0.y) + .finish() + } +} + +impl Display for Point { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "({}, {})", self.0.x, self.0.y) + } +} + +impl From for Point { + fn from(point: POINT) -> Self { + Self(point) + } +} + +impl From for POINT { + fn from(val: Point) -> Self { + val.0 + } +} + +impl AsRef for Point { + fn as_ref(&self) -> &POINT { + &self.0 + } +} + +impl AsMut for Point { + fn as_mut(&mut self) -> &mut POINT { + &mut self.0 + } +} diff --git a/src/background/modules/input/mod.rs b/src/background/modules/input/mod.rs index 4811a4cf..dd4444ac 100644 --- a/src/background/modules/input/mod.rs +++ b/src/background/modules/input/mod.rs @@ -1,805 +1,805 @@ -pub mod domain; - -use std::cmp::max; -use std::cmp::min; -use std::mem; -use std::str::Chars; -use std::thread::sleep; -use std::time::Duration; - -use domain::Point; -use phf::phf_map; -use phf::phf_set; -use windows::Win32::UI::Input::KeyboardAndMouse::*; -use windows::Win32::UI::WindowsAndMessaging::GetCursorPos; -use windows::Win32::UI::WindowsAndMessaging::GetSystemMetrics; -use windows::Win32::UI::WindowsAndMessaging::SetCursorPos; -use windows::Win32::UI::WindowsAndMessaging::SM_CXSCREEN; -use windows::Win32::UI::WindowsAndMessaging::SM_CYSCREEN; - -use crate::error_handler::Result; - -const VIRTUAL_KEYS: phf::Map<&'static str, VIRTUAL_KEY> = phf_map! { - "CONTROL" => VK_CONTROL, "CTRL" => VK_CONTROL, "LCONTROL" => VK_LCONTROL, "LCTRL" => VK_LCONTROL, "RCONTROL" => VK_RCONTROL, "RCTRL" => VK_RCONTROL, - "ALT" => VK_MENU, "MENU" => VK_MENU, "LALT" => VK_LMENU, "LMENU" => VK_LMENU, "RALT" => VK_RMENU, "RMENU" => VK_RMENU, - "SHIFT" => VK_SHIFT, "LSHIFT" => VK_LSHIFT, "RSHIFT" => VK_RSHIFT, "APPS" => VK_APPS, - "WIN" => VK_LWIN, "WINDOWS" => VK_LWIN, "LWIN" => VK_LWIN, "LWINDOWS" => VK_LWIN, "RWIN" => VK_RWIN, "RWINDOWS" => VK_RWIN, - "LBUTTON" => VK_LBUTTON, "RBUTTON" => VK_RBUTTON, "MBUTTON" => VK_MBUTTON, "XBUTTON1" => VK_XBUTTON1, "XBUTTON2" => VK_XBUTTON2, - "CANCEL" => VK_CANCEL, "BACK" => VK_BACK, "TAB" => VK_TAB, "RETURN" => VK_RETURN, "ENTER" => VK_RETURN, "PAUSE" => VK_PAUSE, "CAPITAL" => VK_CAPITAL, - "ESCAPE" => VK_ESCAPE, "ESC" => VK_ESCAPE, "SPACE" => VK_SPACE, - "PRIOR" => VK_PRIOR, "PAGE_UP" => VK_PRIOR, "NEXT" => VK_NEXT, "PAGE_DOWN" => VK_NEXT, "HOME" => VK_HOME, "END" => VK_END, - "LEFT" => VK_LEFT, "UP" => VK_UP, "RIGHT" => VK_RIGHT, "DOWN" => VK_DOWN, "PRINT" => VK_PRINT, - "INSERT" => VK_INSERT, "DELETE" => VK_DELETE, - "F1" => VK_F1, "F2" => VK_F2, "F3" => VK_F3, "F4" => VK_F4, "F5" => VK_F5, "F6" => VK_F6, "F7" => VK_F7, "F8" => VK_F8, "F9" => VK_F9, "F10" => VK_F10, - "F11" => VK_F11, "F12" => VK_F12, "F13" => VK_F13, "F14" => VK_F14, "F15" => VK_F15, "F16" => VK_F16, "F17" => VK_F17, "F18" => VK_F18, "F19" => VK_F19, - "F20" => VK_F20, "F21" => VK_F21, "F22" => VK_F22, "F23" => VK_F23, "F24" => VK_F24, -}; - -const HOLD_KEYS: phf::Set<&'static str> = phf_set! { - "CONTROL", "CTRL", "LCONTROL", "LCTRL", "RCONTROL", "RCTRL", - "ALT", "MENU", "LALT", "LMENU", "RALT", "RMENU", - "SHIFT", "LSHIFT", "RSHIFT", "APPS", - "WIN", "WINDOWS", "LWIN", "LWINDOWS", "RWIN", "RWINDOWS" -}; - -const KEYEVENTF_KEYDOWN: KEYBD_EVENT_FLAGS = KEYBD_EVENT_FLAGS(0); - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -enum InputItem { - HoldKey(VIRTUAL_KEY), - VirtualKey(VIRTUAL_KEY), - Character(char), -} - -impl InputItem { - fn is_holdkey(&self) -> bool { - matches!(self, Self::HoldKey(_)) - } -} - -#[derive(Debug, PartialEq, Eq)] -struct Input { - holdkeys: Vec, - items: Vec, -} - -impl Input { - fn new() -> Self { - Self { - holdkeys: Vec::new(), - items: Vec::new(), - } - } - - fn has_holdkey(&self) -> bool { - !self.holdkeys.is_empty() - } - - fn has_items(&self) -> bool { - !self.items.is_empty() - } - - fn is_holdkey_only(&self) -> bool { - !self.holdkeys.is_empty() && self.items.is_empty() - } - - fn push(&mut self, item: InputItem) { - if let InputItem::HoldKey(key) = item { - if !self.holdkeys.contains(&key) { - self.holdkeys.push(key); - } - } else { - self.items.push(item); - } - } - - fn push_all(&mut self, items: &Vec) { - for item in items { - self.push(*item); - } - } - - fn create_inputs(&self) -> Result> { - let mut inputs: Vec = Vec::new(); - - for holdkey in &self.holdkeys { - let input = Self::create_virtual_key(*holdkey, KEYEVENTF_KEYDOWN); - inputs.push(input); - } - - for item in &self.items { - match item { - InputItem::VirtualKey(key) => { - inputs.push(Self::create_virtual_key(*key, KEYEVENTF_KEYDOWN)); - inputs.push(Self::create_virtual_key(*key, KEYEVENTF_KEYUP)); - } - InputItem::Character(ch) => { - let mut buffer = [0; 2]; - let chars = ch.encode_utf16(&mut buffer); - for ch_u16 in chars { - let keys = Self::create_char_key(*ch_u16, self.has_holdkey()); - inputs.extend(keys); - } - } - _ => (), - } - } - - for holdkey in self.holdkeys.iter().rev() { - let input = Self::create_virtual_key(*holdkey, KEYEVENTF_KEYUP); - inputs.push(input); - } - - Ok(inputs) - } - - fn create_virtual_key(key: VIRTUAL_KEY, flags: KEYBD_EVENT_FLAGS) -> INPUT { - INPUT { - r#type: INPUT_KEYBOARD, - Anonymous: INPUT_0 { - ki: KEYBDINPUT { - wVk: key, - wScan: 0, - dwFlags: flags, - time: 0, - dwExtraInfo: 0, - }, - }, - } - } - - fn create_char_key(ch: u16, hold_mode: bool) -> Vec { - // let code = ch as i32; - let vk: i16 = if ch < 256 { - unsafe { VkKeyScanW(ch) } - } else { - -1 - }; - - if vk == -1 { - // Unicode - vec![ - INPUT { - r#type: INPUT_KEYBOARD, - Anonymous: INPUT_0 { - ki: KEYBDINPUT { - wVk: VIRTUAL_KEY(0), - wScan: ch, - dwFlags: KEYEVENTF_UNICODE, - time: 0, - dwExtraInfo: 0, - }, - }, - }, - INPUT { - r#type: INPUT_KEYBOARD, - Anonymous: INPUT_0 { - ki: KEYBDINPUT { - wVk: VIRTUAL_KEY(0), - wScan: ch, - dwFlags: KEYEVENTF_UNICODE | KEYEVENTF_KEYUP, - time: 0, - dwExtraInfo: 0, - }, - }, - }, - ] - } else { - // ASCII - let key: VIRTUAL_KEY = VIRTUAL_KEY((vk & 0xFF) as _); - if hold_mode { - vec![ - INPUT { - r#type: INPUT_KEYBOARD, - Anonymous: INPUT_0 { - ki: KEYBDINPUT { - wVk: key, - wScan: 0, - dwFlags: KEYEVENTF_KEYDOWN, - time: 0, - dwExtraInfo: 0, - }, - }, - }, - INPUT { - r#type: INPUT_KEYBOARD, - Anonymous: INPUT_0 { - ki: KEYBDINPUT { - wVk: key, - wScan: 0, - dwFlags: KEYEVENTF_KEYUP, - time: 0, - dwExtraInfo: 0, - }, - }, - }, - ] - } else { - let mut shift: bool = (vk >> 8 & 0x01) != 0; - let state = unsafe { GetKeyState(VK_CAPITAL.0 as _) }; - if (state & 0x01) != 0 - && ((ch >= 'a' as u16 && ch <= 'z' as u16) - || (ch >= 'A' as u16 && ch <= 'Z' as u16)) - { - shift = !shift; - }; - let mut char_inputs: Vec = Vec::new(); - if shift { - char_inputs.push(INPUT { - r#type: INPUT_KEYBOARD, - Anonymous: INPUT_0 { - ki: KEYBDINPUT { - wVk: VK_SHIFT, - wScan: 0, - dwFlags: KEYEVENTF_KEYDOWN, - time: 0, - dwExtraInfo: 0, - }, - }, - }); - } - char_inputs.push(INPUT { - r#type: INPUT_KEYBOARD, - Anonymous: INPUT_0 { - ki: KEYBDINPUT { - wVk: key, - wScan: 0, - dwFlags: KEYEVENTF_KEYDOWN, - time: 0, - dwExtraInfo: 0, - }, - }, - }); - char_inputs.push(INPUT { - r#type: INPUT_KEYBOARD, - Anonymous: INPUT_0 { - ki: KEYBDINPUT { - wVk: key, - wScan: 0, - dwFlags: KEYEVENTF_KEYUP, - time: 0, - dwExtraInfo: 0, - }, - }, - }); - if shift { - char_inputs.push(INPUT { - r#type: INPUT_KEYBOARD, - Anonymous: INPUT_0 { - ki: KEYBDINPUT { - wVk: VK_SHIFT, - wScan: 0, - dwFlags: KEYEVENTF_KEYUP, - time: 0, - dwExtraInfo: 0, - }, - }, - }); - }; - char_inputs - } - } - } -} - -fn parse_input(expression: &str) -> Result> { - let mut inputs: Vec = Vec::new(); - - let mut expr = expression.chars(); - while let Some((items, is_holdkey)) = next_input(&mut expr)? { - if let Some(prev) = inputs.last_mut() { - // if !is_holdkey && (prev.is_holdkey_only() || !prev.has_holdkey()) { - if (is_holdkey && !prev.has_items()) - || (!is_holdkey && (!prev.has_holdkey() || prev.is_holdkey_only())) - { - prev.push_all(&items); - continue; - } - } - - let mut input = Input::new(); - input.push_all(&items); - - inputs.push(input); - } - - Ok(inputs) -} - -fn next_input(expr: &mut Chars<'_>) -> Result, bool)>> { - if let Some(ch) = expr.next() { - let next = match ch { - '{' => { - let item = read_special_item(expr)?; - Some((vec![item], item.is_holdkey())) - } - '(' => { - let items = read_group_items(expr)?; - Some((items, false)) - } - _ => Some((vec![InputItem::Character(ch)], false)), - }; - Ok(next) - } else { - Ok(None) - } -} - -fn read_special_item(expr: &mut Chars<'_>) -> Result { - let mut token = String::new(); - let mut matched = false; - for ch in expr.by_ref() { - if ch == '}' && !token.is_empty() { - matched = true; - break; - } else { - token.push(ch); - } - } - - if matched { - if token == "(" || token == ")" || token == "{" || token == "}" { - Ok(InputItem::Character(token.chars().next().unwrap())) - } else { - let token = token.to_uppercase(); - if let Some(key) = VIRTUAL_KEYS.get(&token) { - if HOLD_KEYS.contains(&token) { - Ok(InputItem::HoldKey(*key)) - } else { - Ok(InputItem::VirtualKey(*key)) - } - } else { - Err("Error Input Format".into()) - } - } - } else { - Err("Error Input Format".into()) - } -} - -fn read_group_items(expr: &mut Chars<'_>) -> Result> { - let mut items: Vec = Vec::new(); - let mut matched = false; - - while let Some((next, _)) = next_input(expr)? { - if next.len() == 1 && next[0] == InputItem::Character(')') { - matched = true; - break; - } - - items.extend(next); - } - - if matched { - Ok(items) - } else { - Err("Error Input Format".into()) - } -} - -/// Simulate typing keys on keyboard. -#[derive(Debug, Default)] -pub struct Keyboard { - interval: u64, - holdkeys: Vec, -} - -#[allow(dead_code)] -impl Keyboard { - /// Create a keyboard to simulate typing keys. - pub fn new() -> Self { - Self { - interval: 0, - holdkeys: Vec::new(), - } - } - - /// Set the interval time between keys. - /// - /// `interval` is the time number of milliseconds, `0` is default value. - pub fn interval(mut self, interval: u64) -> Self { - self.interval = interval; - self - } - - /// Simulates typing `keys` on keyboard. - /// - /// `{}` is used for some special keys. For example: `{ctrl}{alt}{delete}`, `{shift}{home}`. - /// - /// `()` is used for group keys. For example: `{ctrl}(AB)` types `Ctrl+A+B`. - /// - /// `{` `}` `(` `)` can be quoted by `{}`. For example: `{{}Hi,{(}rust!{)}{}}` types `{Hi,(rust)}`. - pub fn send_keys(&self, keys: &str) -> Result<()> { - let inputs = parse_input(keys)?; - for ref input in inputs { - // self.send_keyboard(input)?; - let input_keys = input.create_inputs()?; - self.send_keyboard(&input_keys)?; - } - - Ok(()) - } - - /// Simulates starting to hold `keys` on keyboard. Only holdkeys are allowed. - /// - /// The `keys` will be released when `end_hold_keys()` is invoked. - pub fn begin_hold_keys(&mut self, keys: &str) -> Result<()> { - let mut holdkeys: Vec = Vec::new(); - - let inputs = parse_input(keys)?; - for input in inputs { - if input.has_items() { - return Err("Error holdkeys".into()); - } - - holdkeys.extend(input.holdkeys); - } - - if holdkeys.is_empty() { - return Err("Error holdkeys".into()); - } - - let mut holdkey_inputs: Vec = Vec::new(); - for holdkey in &holdkeys { - holdkey_inputs.push(Input::create_virtual_key(*holdkey, KEYEVENTF_KEYDOWN)); - } - // send_input(&holdkey_inputs.as_slice())?; - self.send_keyboard(&holdkey_inputs)?; - - self.holdkeys.extend(holdkeys); - - Ok(()) - } - - /// Stop holding keys on keyboard. - pub fn end_hold_keys(&mut self) -> Result<()> { - if self.holdkeys.is_empty() { - Ok(()) - } else { - let mut holdkey_inputs = Vec::new(); - for holdkey in self.holdkeys.iter().rev() { - holdkey_inputs.push(Input::create_virtual_key(*holdkey, KEYEVENTF_KEYUP)); - } - self.holdkeys.clear(); - - // send_input(&holdkey_inputs.as_slice()) - self.send_keyboard(&holdkey_inputs) - } - } - - // fn send_keyboard(&self, input: &Input) -> Result<()> { - // let input_keys = input.create_inputs()?; - // if self.interval == 0 { - // send_input(&input_keys.as_slice()) - // } else { - // for input_key in &input_keys { - // let input_key_slice: [INPUT; 1] = [input_key.clone()]; - // send_input(&input_key_slice)?; - - // self.wait(); - // } - - // Ok(()) - // } - // } - - fn send_keyboard(&self, input_keys: &[INPUT]) -> Result<()> { - // let input_keys = input.create_inputs()?; - if self.interval == 0 { - send_input(input_keys) - } else { - for input_key in input_keys { - let input_key_slice: [INPUT; 1] = [*input_key]; - send_input(&input_key_slice)?; - - self.wait(); - } - - Ok(()) - } - } - - fn wait(&self) { - if self.interval > 0 { - sleep(Duration::from_millis(self.interval)); - } - } -} - -impl Drop for Keyboard { - fn drop(&mut self) { - if !self.holdkeys.is_empty() { - let mut holdkey_inputs: Vec = Vec::new(); - for holdkey in self.holdkeys.iter().rev() { - holdkey_inputs.push(Input::create_virtual_key(*holdkey, KEYEVENTF_KEYUP)); - } - - if send_input(holdkey_inputs.as_slice()).is_ok() { - self.holdkeys.clear(); - } - } - } -} - -/// Simulate mouse event. -#[derive(Debug)] -pub struct Mouse { - interval: u64, - move_time: u64, - auto_move: bool, - holdkeys: Vec, -} - -impl Default for Mouse { - fn default() -> Self { - Self { - interval: 100, - move_time: 500, - auto_move: true, - holdkeys: Vec::new(), - } - } -} - -#[allow(dead_code)] -impl Mouse { - /// Creates a `Mouse` to simulate mouse event. - pub fn new() -> Self { - Self::default() - } - - /// Sets the interval time between events. - /// - /// `interval` is the time number of milliseconds, `100` is default value. - pub fn interval(mut self, interval: u64) -> Self { - self.interval = interval; - self - } - - /// Sets the mouse move time in millionseconds. `500` is default value. - pub fn move_time(mut self, move_time: u64) -> Self { - self.move_time = move_time; - self - } - - /// Sets whether move the cursor to the click point automatically. Default is `true`. - pub fn auto_move(mut self, auto_move: bool) -> Self { - self.auto_move = auto_move; - self - } - - /// Sets the holdkeys when mouse clicks. - /// - /// The holdkeys is quoted by `{}`. For example: `{Shift}`, `{Ctrl}{Alt}`. - pub fn holdkeys(mut self, holdkeys: &str) -> Self { - self.holdkeys.clear(); - - let mut expr = holdkeys.chars(); - while let Some((items, is_holdkey)) = next_input(&mut expr).unwrap() { - if is_holdkey { - for item in items { - if let InputItem::HoldKey(key) = item { - self.holdkeys.push(key); - } - } - } - } - - self - } - - /// Retrieves the position of the mouse cursor, in screen coordinates. - pub fn get_cursor_pos() -> Result { - let mut pos: Point = Point::default(); - // let ret = unsafe { - // GetCursorPos(pos.as_mut()) - // }; - - // if ret.as_bool() { - // Ok(pos) - // } else { - // Err(Error::last_os_error()) - // } - unsafe { GetCursorPos(pos.as_mut())? }; - Ok(pos) - } - - /// Moves the cursor to the specified screen coordinates. - pub fn set_cursor_pos(pos: Point) -> Result<()> { - // let ret = unsafe { SetCursorPos(pos.get_x(), pos.get_y()) }; - // if ret.as_bool() { - // Ok(()) - // } else { - // Err(Error::last_os_error()) - // } - unsafe { SetCursorPos(pos.get_x(), pos.get_y())? }; - Ok(()) - } - - /// Moves the cursor from current position to the `target` position. - /// - /// # Examples - /// - /// ``` - /// use uiautomation::inputs::Mouse; - /// use uiautomation::types::Point; - /// - /// let mouse = Mouse::new().move_time(800); - /// mouse.move_to(Point::new(10, 20)).unwrap(); - /// mouse.move_to(Point::new(1000,800)).unwrap(); - /// ``` - pub fn move_to(&self, target: Point) -> Result<()> { - let (width, height) = get_screen_size()?; - let x = min(max(0, target.get_x()), width); - let y = min(max(0, target.get_y()), height); - let target = Point::new(x, y); - - if self.move_time > 0 { - let source = Self::get_cursor_pos()?; - let delta_x = target.get_x() - source.get_x(); - let delta_y = target.get_y() - source.get_y(); - - let delta = max(delta_x.abs(), delta_y.abs()); - let steps = delta / 20; - if steps > 1 { - let step_x = delta_x / steps; - let step_y = delta_y / steps; - let interval = Duration::from_millis(self.move_time / steps as u64); - for i in 1..steps { - let pos = Point::new(source.get_x() + step_x * i, source.get_y() + step_y * i); - Self::set_cursor_pos(pos)?; - sleep(interval); - } - } - } - - Self::set_cursor_pos(target) - } - - /// Simulates a mouse click event. - /// - /// # Examples - /// ``` - /// use uiautomation::inputs::Mouse; - /// - /// let mouse = Mouse::new(); - /// let pos = Mouse::get_cursor_pos().unwrap(); - /// mouse.click(pos).unwrap(); - /// ``` - pub fn click(&self, pos: Point) -> Result<()> { - if self.auto_move { - self.move_to(pos)?; - } - - self.before_click()?; - self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_LEFTDOWN)?; - self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_LEFTUP)?; - self.after_click()?; - - Ok(()) - } - - /// Simulates a mouse double click event. - /// - /// # Examples - /// ``` - /// use uiautomation::inputs::Mouse; - /// - /// let mouse = Mouse::new(); - /// let pos = Mouse::get_cursor_pos().unwrap(); - /// mouse.double_click(pos).unwrap(); - /// ``` - pub fn double_click(&self, pos: Point) -> Result<()> { - if self.auto_move { - self.move_to(pos)?; - } - - self.before_click()?; - - self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_LEFTDOWN)?; - self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_LEFTUP)?; - - sleep(Duration::from_millis(max(200, self.interval))); - - self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_LEFTDOWN)?; - self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_LEFTUP)?; - - self.after_click()?; - - Ok(()) - } - - /// Simulates a right mouse click event. - /// - /// # Examples - /// ``` - /// use uiautomation::inputs::Mouse; - /// - /// let mouse = Mouse::new(); - /// let pos = Mouse::get_cursor_pos().unwrap(); - /// mouse.right_click(pos).unwrap(); - /// ``` - pub fn right_click(&self, pos: Point) -> Result<()> { - if self.auto_move { - self.move_to(pos)?; - } - - self.before_click()?; - self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_RIGHTDOWN)?; - self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_RIGHTUP)?; - self.after_click()?; - - Ok(()) - } - - fn before_click(&self) -> Result<()> { - for holdkey in &self.holdkeys { - let key_input = [Input::create_virtual_key(*holdkey, KEYEVENTF_KEYDOWN)]; - send_input(&key_input)?; - self.wait(); - } - - Ok(()) - } - - fn after_click(&self) -> Result<()> { - for holdkey in &self.holdkeys { - let key_input = [Input::create_virtual_key(*holdkey, KEYEVENTF_KEYUP)]; - send_input(&key_input)?; - self.wait(); - } - - Ok(()) - } - - fn mouse_event(&self, x: i32, y: i32, flags: MOUSE_EVENT_FLAGS) -> Result<()> { - let input = [INPUT { - r#type: INPUT_MOUSE, - Anonymous: INPUT_0 { - mi: MOUSEINPUT { - dx: x, - dy: y, - mouseData: 0, - dwFlags: flags, - time: 0, - dwExtraInfo: 0, - }, - }, - }]; - send_input(&input)?; - self.wait(); - - Ok(()) - } - - fn wait(&self) { - if self.interval > 0 { - sleep(Duration::from_millis(self.interval)); - } - } -} - -/// Retrieves the `(width, height)` size of the primary screen. -pub fn get_screen_size() -> Result<(i32, i32)> { - let width = unsafe { GetSystemMetrics(SM_CXSCREEN) }; - if width == 0 { - return Err("Failed to get screen width".into()); - } - - let height = unsafe { GetSystemMetrics(SM_CYSCREEN) }; - if height == 0 { - return Err("Failed to get screen height".into()); - } - - Ok((width, height)) -} - -fn send_input(inputs: &[INPUT]) -> Result<()> { - let sent = unsafe { SendInput(inputs, mem::size_of::() as _) }; - - if sent == inputs.len() as u32 { - Ok(()) - } else { - Err("Failed to send input".into()) - } -} +pub mod domain; + +use std::cmp::max; +use std::cmp::min; +use std::mem; +use std::str::Chars; +use std::thread::sleep; +use std::time::Duration; + +use domain::Point; +use phf::phf_map; +use phf::phf_set; +use windows::Win32::UI::Input::KeyboardAndMouse::*; +use windows::Win32::UI::WindowsAndMessaging::GetCursorPos; +use windows::Win32::UI::WindowsAndMessaging::GetSystemMetrics; +use windows::Win32::UI::WindowsAndMessaging::SetCursorPos; +use windows::Win32::UI::WindowsAndMessaging::SM_CXSCREEN; +use windows::Win32::UI::WindowsAndMessaging::SM_CYSCREEN; + +use crate::error_handler::Result; + +const VIRTUAL_KEYS: phf::Map<&'static str, VIRTUAL_KEY> = phf_map! { + "CONTROL" => VK_CONTROL, "CTRL" => VK_CONTROL, "LCONTROL" => VK_LCONTROL, "LCTRL" => VK_LCONTROL, "RCONTROL" => VK_RCONTROL, "RCTRL" => VK_RCONTROL, + "ALT" => VK_MENU, "MENU" => VK_MENU, "LALT" => VK_LMENU, "LMENU" => VK_LMENU, "RALT" => VK_RMENU, "RMENU" => VK_RMENU, + "SHIFT" => VK_SHIFT, "LSHIFT" => VK_LSHIFT, "RSHIFT" => VK_RSHIFT, "APPS" => VK_APPS, + "WIN" => VK_LWIN, "WINDOWS" => VK_LWIN, "LWIN" => VK_LWIN, "LWINDOWS" => VK_LWIN, "RWIN" => VK_RWIN, "RWINDOWS" => VK_RWIN, + "LBUTTON" => VK_LBUTTON, "RBUTTON" => VK_RBUTTON, "MBUTTON" => VK_MBUTTON, "XBUTTON1" => VK_XBUTTON1, "XBUTTON2" => VK_XBUTTON2, + "CANCEL" => VK_CANCEL, "BACK" => VK_BACK, "TAB" => VK_TAB, "RETURN" => VK_RETURN, "ENTER" => VK_RETURN, "PAUSE" => VK_PAUSE, "CAPITAL" => VK_CAPITAL, + "ESCAPE" => VK_ESCAPE, "ESC" => VK_ESCAPE, "SPACE" => VK_SPACE, + "PRIOR" => VK_PRIOR, "PAGE_UP" => VK_PRIOR, "NEXT" => VK_NEXT, "PAGE_DOWN" => VK_NEXT, "HOME" => VK_HOME, "END" => VK_END, + "LEFT" => VK_LEFT, "UP" => VK_UP, "RIGHT" => VK_RIGHT, "DOWN" => VK_DOWN, "PRINT" => VK_PRINT, + "INSERT" => VK_INSERT, "DELETE" => VK_DELETE, + "F1" => VK_F1, "F2" => VK_F2, "F3" => VK_F3, "F4" => VK_F4, "F5" => VK_F5, "F6" => VK_F6, "F7" => VK_F7, "F8" => VK_F8, "F9" => VK_F9, "F10" => VK_F10, + "F11" => VK_F11, "F12" => VK_F12, "F13" => VK_F13, "F14" => VK_F14, "F15" => VK_F15, "F16" => VK_F16, "F17" => VK_F17, "F18" => VK_F18, "F19" => VK_F19, + "F20" => VK_F20, "F21" => VK_F21, "F22" => VK_F22, "F23" => VK_F23, "F24" => VK_F24, +}; + +const HOLD_KEYS: phf::Set<&'static str> = phf_set! { + "CONTROL", "CTRL", "LCONTROL", "LCTRL", "RCONTROL", "RCTRL", + "ALT", "MENU", "LALT", "LMENU", "RALT", "RMENU", + "SHIFT", "LSHIFT", "RSHIFT", "APPS", + "WIN", "WINDOWS", "LWIN", "LWINDOWS", "RWIN", "RWINDOWS" +}; + +const KEYEVENTF_KEYDOWN: KEYBD_EVENT_FLAGS = KEYBD_EVENT_FLAGS(0); + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum InputItem { + HoldKey(VIRTUAL_KEY), + VirtualKey(VIRTUAL_KEY), + Character(char), +} + +impl InputItem { + fn is_holdkey(&self) -> bool { + matches!(self, Self::HoldKey(_)) + } +} + +#[derive(Debug, PartialEq, Eq)] +struct Input { + holdkeys: Vec, + items: Vec, +} + +impl Input { + fn new() -> Self { + Self { + holdkeys: Vec::new(), + items: Vec::new(), + } + } + + fn has_holdkey(&self) -> bool { + !self.holdkeys.is_empty() + } + + fn has_items(&self) -> bool { + !self.items.is_empty() + } + + fn is_holdkey_only(&self) -> bool { + !self.holdkeys.is_empty() && self.items.is_empty() + } + + fn push(&mut self, item: InputItem) { + if let InputItem::HoldKey(key) = item { + if !self.holdkeys.contains(&key) { + self.holdkeys.push(key); + } + } else { + self.items.push(item); + } + } + + fn push_all(&mut self, items: &Vec) { + for item in items { + self.push(*item); + } + } + + fn create_inputs(&self) -> Result> { + let mut inputs: Vec = Vec::new(); + + for holdkey in &self.holdkeys { + let input = Self::create_virtual_key(*holdkey, KEYEVENTF_KEYDOWN); + inputs.push(input); + } + + for item in &self.items { + match item { + InputItem::VirtualKey(key) => { + inputs.push(Self::create_virtual_key(*key, KEYEVENTF_KEYDOWN)); + inputs.push(Self::create_virtual_key(*key, KEYEVENTF_KEYUP)); + } + InputItem::Character(ch) => { + let mut buffer = [0; 2]; + let chars = ch.encode_utf16(&mut buffer); + for ch_u16 in chars { + let keys = Self::create_char_key(*ch_u16, self.has_holdkey()); + inputs.extend(keys); + } + } + _ => (), + } + } + + for holdkey in self.holdkeys.iter().rev() { + let input = Self::create_virtual_key(*holdkey, KEYEVENTF_KEYUP); + inputs.push(input); + } + + Ok(inputs) + } + + fn create_virtual_key(key: VIRTUAL_KEY, flags: KEYBD_EVENT_FLAGS) -> INPUT { + INPUT { + r#type: INPUT_KEYBOARD, + Anonymous: INPUT_0 { + ki: KEYBDINPUT { + wVk: key, + wScan: 0, + dwFlags: flags, + time: 0, + dwExtraInfo: 0, + }, + }, + } + } + + fn create_char_key(ch: u16, hold_mode: bool) -> Vec { + // let code = ch as i32; + let vk: i16 = if ch < 256 { + unsafe { VkKeyScanW(ch) } + } else { + -1 + }; + + if vk == -1 { + // Unicode + vec![ + INPUT { + r#type: INPUT_KEYBOARD, + Anonymous: INPUT_0 { + ki: KEYBDINPUT { + wVk: VIRTUAL_KEY(0), + wScan: ch, + dwFlags: KEYEVENTF_UNICODE, + time: 0, + dwExtraInfo: 0, + }, + }, + }, + INPUT { + r#type: INPUT_KEYBOARD, + Anonymous: INPUT_0 { + ki: KEYBDINPUT { + wVk: VIRTUAL_KEY(0), + wScan: ch, + dwFlags: KEYEVENTF_UNICODE | KEYEVENTF_KEYUP, + time: 0, + dwExtraInfo: 0, + }, + }, + }, + ] + } else { + // ASCII + let key: VIRTUAL_KEY = VIRTUAL_KEY((vk & 0xFF) as _); + if hold_mode { + vec![ + INPUT { + r#type: INPUT_KEYBOARD, + Anonymous: INPUT_0 { + ki: KEYBDINPUT { + wVk: key, + wScan: 0, + dwFlags: KEYEVENTF_KEYDOWN, + time: 0, + dwExtraInfo: 0, + }, + }, + }, + INPUT { + r#type: INPUT_KEYBOARD, + Anonymous: INPUT_0 { + ki: KEYBDINPUT { + wVk: key, + wScan: 0, + dwFlags: KEYEVENTF_KEYUP, + time: 0, + dwExtraInfo: 0, + }, + }, + }, + ] + } else { + let mut shift: bool = (vk >> 8 & 0x01) != 0; + let state = unsafe { GetKeyState(VK_CAPITAL.0 as _) }; + if (state & 0x01) != 0 + && ((ch >= 'a' as u16 && ch <= 'z' as u16) + || (ch >= 'A' as u16 && ch <= 'Z' as u16)) + { + shift = !shift; + }; + let mut char_inputs: Vec = Vec::new(); + if shift { + char_inputs.push(INPUT { + r#type: INPUT_KEYBOARD, + Anonymous: INPUT_0 { + ki: KEYBDINPUT { + wVk: VK_SHIFT, + wScan: 0, + dwFlags: KEYEVENTF_KEYDOWN, + time: 0, + dwExtraInfo: 0, + }, + }, + }); + } + char_inputs.push(INPUT { + r#type: INPUT_KEYBOARD, + Anonymous: INPUT_0 { + ki: KEYBDINPUT { + wVk: key, + wScan: 0, + dwFlags: KEYEVENTF_KEYDOWN, + time: 0, + dwExtraInfo: 0, + }, + }, + }); + char_inputs.push(INPUT { + r#type: INPUT_KEYBOARD, + Anonymous: INPUT_0 { + ki: KEYBDINPUT { + wVk: key, + wScan: 0, + dwFlags: KEYEVENTF_KEYUP, + time: 0, + dwExtraInfo: 0, + }, + }, + }); + if shift { + char_inputs.push(INPUT { + r#type: INPUT_KEYBOARD, + Anonymous: INPUT_0 { + ki: KEYBDINPUT { + wVk: VK_SHIFT, + wScan: 0, + dwFlags: KEYEVENTF_KEYUP, + time: 0, + dwExtraInfo: 0, + }, + }, + }); + }; + char_inputs + } + } + } +} + +fn parse_input(expression: &str) -> Result> { + let mut inputs: Vec = Vec::new(); + + let mut expr = expression.chars(); + while let Some((items, is_holdkey)) = next_input(&mut expr)? { + if let Some(prev) = inputs.last_mut() { + // if !is_holdkey && (prev.is_holdkey_only() || !prev.has_holdkey()) { + if (is_holdkey && !prev.has_items()) + || (!is_holdkey && (!prev.has_holdkey() || prev.is_holdkey_only())) + { + prev.push_all(&items); + continue; + } + } + + let mut input = Input::new(); + input.push_all(&items); + + inputs.push(input); + } + + Ok(inputs) +} + +fn next_input(expr: &mut Chars<'_>) -> Result, bool)>> { + if let Some(ch) = expr.next() { + let next = match ch { + '{' => { + let item = read_special_item(expr)?; + Some((vec![item], item.is_holdkey())) + } + '(' => { + let items = read_group_items(expr)?; + Some((items, false)) + } + _ => Some((vec![InputItem::Character(ch)], false)), + }; + Ok(next) + } else { + Ok(None) + } +} + +fn read_special_item(expr: &mut Chars<'_>) -> Result { + let mut token = String::new(); + let mut matched = false; + for ch in expr.by_ref() { + if ch == '}' && !token.is_empty() { + matched = true; + break; + } else { + token.push(ch); + } + } + + if matched { + if token == "(" || token == ")" || token == "{" || token == "}" { + Ok(InputItem::Character(token.chars().next().unwrap())) + } else { + let token = token.to_uppercase(); + if let Some(key) = VIRTUAL_KEYS.get(&token) { + if HOLD_KEYS.contains(&token) { + Ok(InputItem::HoldKey(*key)) + } else { + Ok(InputItem::VirtualKey(*key)) + } + } else { + Err("Error Input Format".into()) + } + } + } else { + Err("Error Input Format".into()) + } +} + +fn read_group_items(expr: &mut Chars<'_>) -> Result> { + let mut items: Vec = Vec::new(); + let mut matched = false; + + while let Some((next, _)) = next_input(expr)? { + if next.len() == 1 && next[0] == InputItem::Character(')') { + matched = true; + break; + } + + items.extend(next); + } + + if matched { + Ok(items) + } else { + Err("Error Input Format".into()) + } +} + +/// Simulate typing keys on keyboard. +#[derive(Debug, Default)] +pub struct Keyboard { + interval: u64, + holdkeys: Vec, +} + +#[allow(dead_code)] +impl Keyboard { + /// Create a keyboard to simulate typing keys. + pub fn new() -> Self { + Self { + interval: 0, + holdkeys: Vec::new(), + } + } + + /// Set the interval time between keys. + /// + /// `interval` is the time number of milliseconds, `0` is default value. + pub fn interval(mut self, interval: u64) -> Self { + self.interval = interval; + self + } + + /// Simulates typing `keys` on keyboard. + /// + /// `{}` is used for some special keys. For example: `{ctrl}{alt}{delete}`, `{shift}{home}`. + /// + /// `()` is used for group keys. For example: `{ctrl}(AB)` types `Ctrl+A+B`. + /// + /// `{` `}` `(` `)` can be quoted by `{}`. For example: `{{}Hi,{(}rust!{)}{}}` types `{Hi,(rust)}`. + pub fn send_keys(&self, keys: &str) -> Result<()> { + let inputs = parse_input(keys)?; + for ref input in inputs { + // self.send_keyboard(input)?; + let input_keys = input.create_inputs()?; + self.send_keyboard(&input_keys)?; + } + + Ok(()) + } + + /// Simulates starting to hold `keys` on keyboard. Only holdkeys are allowed. + /// + /// The `keys` will be released when `end_hold_keys()` is invoked. + pub fn begin_hold_keys(&mut self, keys: &str) -> Result<()> { + let mut holdkeys: Vec = Vec::new(); + + let inputs = parse_input(keys)?; + for input in inputs { + if input.has_items() { + return Err("Error holdkeys".into()); + } + + holdkeys.extend(input.holdkeys); + } + + if holdkeys.is_empty() { + return Err("Error holdkeys".into()); + } + + let mut holdkey_inputs: Vec = Vec::new(); + for holdkey in &holdkeys { + holdkey_inputs.push(Input::create_virtual_key(*holdkey, KEYEVENTF_KEYDOWN)); + } + // send_input(&holdkey_inputs.as_slice())?; + self.send_keyboard(&holdkey_inputs)?; + + self.holdkeys.extend(holdkeys); + + Ok(()) + } + + /// Stop holding keys on keyboard. + pub fn end_hold_keys(&mut self) -> Result<()> { + if self.holdkeys.is_empty() { + Ok(()) + } else { + let mut holdkey_inputs = Vec::new(); + for holdkey in self.holdkeys.iter().rev() { + holdkey_inputs.push(Input::create_virtual_key(*holdkey, KEYEVENTF_KEYUP)); + } + self.holdkeys.clear(); + + // send_input(&holdkey_inputs.as_slice()) + self.send_keyboard(&holdkey_inputs) + } + } + + // fn send_keyboard(&self, input: &Input) -> Result<()> { + // let input_keys = input.create_inputs()?; + // if self.interval == 0 { + // send_input(&input_keys.as_slice()) + // } else { + // for input_key in &input_keys { + // let input_key_slice: [INPUT; 1] = [input_key.clone()]; + // send_input(&input_key_slice)?; + + // self.wait(); + // } + + // Ok(()) + // } + // } + + fn send_keyboard(&self, input_keys: &[INPUT]) -> Result<()> { + // let input_keys = input.create_inputs()?; + if self.interval == 0 { + send_input(input_keys) + } else { + for input_key in input_keys { + let input_key_slice: [INPUT; 1] = [*input_key]; + send_input(&input_key_slice)?; + + self.wait(); + } + + Ok(()) + } + } + + fn wait(&self) { + if self.interval > 0 { + sleep(Duration::from_millis(self.interval)); + } + } +} + +impl Drop for Keyboard { + fn drop(&mut self) { + if !self.holdkeys.is_empty() { + let mut holdkey_inputs: Vec = Vec::new(); + for holdkey in self.holdkeys.iter().rev() { + holdkey_inputs.push(Input::create_virtual_key(*holdkey, KEYEVENTF_KEYUP)); + } + + if send_input(holdkey_inputs.as_slice()).is_ok() { + self.holdkeys.clear(); + } + } + } +} + +/// Simulate mouse event. +#[derive(Debug)] +pub struct Mouse { + interval: u64, + move_time: u64, + auto_move: bool, + holdkeys: Vec, +} + +impl Default for Mouse { + fn default() -> Self { + Self { + interval: 100, + move_time: 500, + auto_move: true, + holdkeys: Vec::new(), + } + } +} + +#[allow(dead_code)] +impl Mouse { + /// Creates a `Mouse` to simulate mouse event. + pub fn new() -> Self { + Self::default() + } + + /// Sets the interval time between events. + /// + /// `interval` is the time number of milliseconds, `100` is default value. + pub fn interval(mut self, interval: u64) -> Self { + self.interval = interval; + self + } + + /// Sets the mouse move time in millionseconds. `500` is default value. + pub fn move_time(mut self, move_time: u64) -> Self { + self.move_time = move_time; + self + } + + /// Sets whether move the cursor to the click point automatically. Default is `true`. + pub fn auto_move(mut self, auto_move: bool) -> Self { + self.auto_move = auto_move; + self + } + + /// Sets the holdkeys when mouse clicks. + /// + /// The holdkeys is quoted by `{}`. For example: `{Shift}`, `{Ctrl}{Alt}`. + pub fn holdkeys(mut self, holdkeys: &str) -> Self { + self.holdkeys.clear(); + + let mut expr = holdkeys.chars(); + while let Some((items, is_holdkey)) = next_input(&mut expr).unwrap() { + if is_holdkey { + for item in items { + if let InputItem::HoldKey(key) = item { + self.holdkeys.push(key); + } + } + } + } + + self + } + + /// Retrieves the position of the mouse cursor, in screen coordinates. + pub fn get_cursor_pos() -> Result { + let mut pos: Point = Point::default(); + // let ret = unsafe { + // GetCursorPos(pos.as_mut()) + // }; + + // if ret.as_bool() { + // Ok(pos) + // } else { + // Err(Error::last_os_error()) + // } + unsafe { GetCursorPos(pos.as_mut())? }; + Ok(pos) + } + + /// Moves the cursor to the specified screen coordinates. + pub fn set_cursor_pos(pos: Point) -> Result<()> { + // let ret = unsafe { SetCursorPos(pos.get_x(), pos.get_y()) }; + // if ret.as_bool() { + // Ok(()) + // } else { + // Err(Error::last_os_error()) + // } + unsafe { SetCursorPos(pos.get_x(), pos.get_y())? }; + Ok(()) + } + + /// Moves the cursor from current position to the `target` position. + /// + /// # Examples + /// + /// ``` + /// use uiautomation::inputs::Mouse; + /// use uiautomation::types::Point; + /// + /// let mouse = Mouse::new().move_time(800); + /// mouse.move_to(Point::new(10, 20)).unwrap(); + /// mouse.move_to(Point::new(1000,800)).unwrap(); + /// ``` + pub fn move_to(&self, target: Point) -> Result<()> { + let (width, height) = get_screen_size()?; + let x = min(max(0, target.get_x()), width); + let y = min(max(0, target.get_y()), height); + let target = Point::new(x, y); + + if self.move_time > 0 { + let source = Self::get_cursor_pos()?; + let delta_x = target.get_x() - source.get_x(); + let delta_y = target.get_y() - source.get_y(); + + let delta = max(delta_x.abs(), delta_y.abs()); + let steps = delta / 20; + if steps > 1 { + let step_x = delta_x / steps; + let step_y = delta_y / steps; + let interval = Duration::from_millis(self.move_time / steps as u64); + for i in 1..steps { + let pos = Point::new(source.get_x() + step_x * i, source.get_y() + step_y * i); + Self::set_cursor_pos(pos)?; + sleep(interval); + } + } + } + + Self::set_cursor_pos(target) + } + + /// Simulates a mouse click event. + /// + /// # Examples + /// ``` + /// use uiautomation::inputs::Mouse; + /// + /// let mouse = Mouse::new(); + /// let pos = Mouse::get_cursor_pos().unwrap(); + /// mouse.click(pos).unwrap(); + /// ``` + pub fn click(&self, pos: Point) -> Result<()> { + if self.auto_move { + self.move_to(pos)?; + } + + self.before_click()?; + self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_LEFTDOWN)?; + self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_LEFTUP)?; + self.after_click()?; + + Ok(()) + } + + /// Simulates a mouse double click event. + /// + /// # Examples + /// ``` + /// use uiautomation::inputs::Mouse; + /// + /// let mouse = Mouse::new(); + /// let pos = Mouse::get_cursor_pos().unwrap(); + /// mouse.double_click(pos).unwrap(); + /// ``` + pub fn double_click(&self, pos: Point) -> Result<()> { + if self.auto_move { + self.move_to(pos)?; + } + + self.before_click()?; + + self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_LEFTDOWN)?; + self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_LEFTUP)?; + + sleep(Duration::from_millis(max(200, self.interval))); + + self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_LEFTDOWN)?; + self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_LEFTUP)?; + + self.after_click()?; + + Ok(()) + } + + /// Simulates a right mouse click event. + /// + /// # Examples + /// ``` + /// use uiautomation::inputs::Mouse; + /// + /// let mouse = Mouse::new(); + /// let pos = Mouse::get_cursor_pos().unwrap(); + /// mouse.right_click(pos).unwrap(); + /// ``` + pub fn right_click(&self, pos: Point) -> Result<()> { + if self.auto_move { + self.move_to(pos)?; + } + + self.before_click()?; + self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_RIGHTDOWN)?; + self.mouse_event(pos.get_x(), pos.get_y(), MOUSEEVENTF_RIGHTUP)?; + self.after_click()?; + + Ok(()) + } + + fn before_click(&self) -> Result<()> { + for holdkey in &self.holdkeys { + let key_input = [Input::create_virtual_key(*holdkey, KEYEVENTF_KEYDOWN)]; + send_input(&key_input)?; + self.wait(); + } + + Ok(()) + } + + fn after_click(&self) -> Result<()> { + for holdkey in &self.holdkeys { + let key_input = [Input::create_virtual_key(*holdkey, KEYEVENTF_KEYUP)]; + send_input(&key_input)?; + self.wait(); + } + + Ok(()) + } + + fn mouse_event(&self, x: i32, y: i32, flags: MOUSE_EVENT_FLAGS) -> Result<()> { + let input = [INPUT { + r#type: INPUT_MOUSE, + Anonymous: INPUT_0 { + mi: MOUSEINPUT { + dx: x, + dy: y, + mouseData: 0, + dwFlags: flags, + time: 0, + dwExtraInfo: 0, + }, + }, + }]; + send_input(&input)?; + self.wait(); + + Ok(()) + } + + fn wait(&self) { + if self.interval > 0 { + sleep(Duration::from_millis(self.interval)); + } + } +} + +/// Retrieves the `(width, height)` size of the primary screen. +pub fn get_screen_size() -> Result<(i32, i32)> { + let width = unsafe { GetSystemMetrics(SM_CXSCREEN) }; + if width == 0 { + return Err("Failed to get screen width".into()); + } + + let height = unsafe { GetSystemMetrics(SM_CYSCREEN) }; + if height == 0 { + return Err("Failed to get screen height".into()); + } + + Ok((width, height)) +} + +fn send_input(inputs: &[INPUT]) -> Result<()> { + let sent = unsafe { SendInput(inputs, mem::size_of::() as _) }; + + if sent == inputs.len() as u32 { + Ok(()) + } else { + Err("Failed to send input".into()) + } +} diff --git a/src/background/modules/media/application.rs b/src/background/modules/media/application.rs index f80529d1..1162be8b 100644 --- a/src/background/modules/media/application.rs +++ b/src/background/modules/media/application.rs @@ -1,741 +1,741 @@ -use std::{collections::HashMap, path::PathBuf, sync::Arc}; - -use itertools::Itertools; -use lazy_static::lazy_static; -use parking_lot::Mutex; -use windows::{ - Foundation::{EventRegistrationToken, TypedEventHandler}, - Media::Control::{ - GlobalSystemMediaTransportControlsSession, - GlobalSystemMediaTransportControlsSessionManager, - GlobalSystemMediaTransportControlsSessionPlaybackStatus, MediaPropertiesChangedEventArgs, - PlaybackInfoChangedEventArgs, SessionsChangedEventArgs, - }, - Win32::{ - Devices::FunctionDiscovery::PKEY_Device_FriendlyName, - Media::Audio::{ - eAll, eCapture, eCommunications, eConsole, eMultimedia, eRender, EDataFlow, ERole, - Endpoints::{ - IAudioEndpointVolume, IAudioEndpointVolumeCallback, - IAudioEndpointVolumeCallback_Impl, - }, - IAudioSessionControl, IAudioSessionControl2, IAudioSessionEvents, - IAudioSessionEvents_Impl, IAudioSessionManager2, IAudioSessionNotification, - IAudioSessionNotification_Impl, IMMDevice, IMMDeviceEnumerator, IMMEndpoint, - IMMNotificationClient, IMMNotificationClient_Impl, ISimpleAudioVolume, - MMDeviceEnumerator, DEVICE_STATE_ACTIVE, - }, - Storage::EnhancedStorage::PKEY_FileDescription, - System::Com::{CLSCTX_ALL, STGM_READ}, - UI::Shell::{PropertiesSystem::PROPERTYKEY, SIGDN_NORMALDISPLAY}, - }, -}; -use windows_core::Interface; - -use crate::{ - error_handler::Result, - log_error, - seelen::get_app_handle, - seelen_weg::icon_extractor::extract_and_save_icon, - trace_lock, - utils::pcwstr, - windows_api::{Com, WindowsApi}, -}; - -use super::domain::{Device, DeviceChannel, IPolicyConfig, MediaPlayer, PolicyConfig}; - -lazy_static! { - pub static ref MEDIA_MANAGER: Arc> = Arc::new(Mutex::new( - MediaManager::new().expect("Failed to create media manager") - )); - pub static ref REG_PROPERTY_EVENTS: Arc>> = - Arc::new(Mutex::new(HashMap::new())); - pub static ref REG_PLAYBACK_EVENTS: Arc>> = - Arc::new(Mutex::new(HashMap::new())); -} - -enum MediaEvent { - DeviceAdded(String), - DeviceRemoved(String), - DefaultDeviceChanged { - flow: EDataFlow, - role: ERole, - device_id: String, - }, - DeviceVolumeChanged { - device_id: String, - volume: f32, - muted: bool, - }, - MediaPlayerAdded(GlobalSystemMediaTransportControlsSession), - MediaPlayerRemoved(String), - MediaPlayerPropertiesChanged { - id: String, - title: String, - author: String, - thumbnail: Option, - }, - MediaPlayerPlaybackStatusChanged { - id: String, - playing: bool, - }, -} - -#[windows_core::implement(IMMNotificationClient)] -struct MediaManagerEvents; - -impl IMMNotificationClient_Impl for MediaManagerEvents { - fn OnDefaultDeviceChanged( - &self, - flow: EDataFlow, - role: ERole, - device_id: &windows_core::PCWSTR, - ) -> windows_core::Result<()> { - trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::DefaultDeviceChanged { - flow, - role, - device_id: unsafe { device_id.to_string()? }, - }); - Ok(()) - } - - fn OnDeviceAdded(&self, device_id: &windows_core::PCWSTR) -> windows_core::Result<()> { - trace_lock!(MEDIA_MANAGER) - .emit_event(MediaEvent::DeviceAdded(unsafe { device_id.to_string()? })); - Ok(()) - } - - fn OnDeviceRemoved(&self, device_id: &windows_core::PCWSTR) -> windows_core::Result<()> { - trace_lock!(MEDIA_MANAGER) - .emit_event(MediaEvent::DeviceRemoved(unsafe { device_id.to_string()? })); - Ok(()) - } - - fn OnDeviceStateChanged( - &self, - device_id: &windows_core::PCWSTR, - new_device_state: windows::Win32::Media::Audio::DEVICE_STATE, - ) -> windows_core::Result<()> { - let device_id = unsafe { device_id.to_string()? }; - match new_device_state { - DEVICE_STATE_ACTIVE => { - trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::DeviceAdded(device_id)); - } - _ => { - trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::DeviceRemoved(device_id)); - } - } - Ok(()) - } - - fn OnPropertyValueChanged( - &self, - _device_id: &windows_core::PCWSTR, - _key: &PROPERTYKEY, - ) -> windows_core::Result<()> { - Ok(()) - } -} - -impl MediaManagerEvents { - fn on_media_player_properties_changed( - session: &Option, - _args: &Option, - ) -> windows_core::Result<()> { - if let Some(session) = session { - let id = session.SourceAppUserModelId()?.to_string(); - let properties = session.TryGetMediaPropertiesAsync()?.get()?; - trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::MediaPlayerPropertiesChanged { - id, - title: properties.Title()?.to_string(), - author: properties.Artist()?.to_string(), - thumbnail: WindowsApi::extract_thumbnail_from_ref(properties.Thumbnail()?).ok(), - }); - } - Ok(()) - } - - fn on_media_player_playback_changed( - session: &Option, - _args: &Option, - ) -> windows_core::Result<()> { - if let Some(session) = session { - let playback = session.GetPlaybackInfo()?; - trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::MediaPlayerPlaybackStatusChanged { - id: session.SourceAppUserModelId()?.to_string(), - playing: playback.PlaybackStatus()? - == GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing, - }); - } - Ok(()) - } - - fn on_media_players_changed( - session_manager: &Option, - _args: &Option, - ) -> windows_core::Result<()> { - if let Some(session_manager) = session_manager { - let mut current_list = trace_lock!(MEDIA_MANAGER) - .playing() - .iter() - .map(|session| session.id.clone()) - .collect_vec(); - - for session in session_manager.GetSessions()? { - let id = session.SourceAppUserModelId()?.to_string(); - if !current_list.contains(&id) { - trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::MediaPlayerAdded(session)); - } - current_list.retain(|x| *x != id); - } - - for id in current_list { - trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::MediaPlayerRemoved(id)); - } - } - Ok(()) - } -} - -#[windows::core::implement(IAudioEndpointVolumeCallback, IAudioSessionNotification)] -struct MediaDeviceEventHandler { - device_id: String, -} - -impl IAudioEndpointVolumeCallback_Impl for MediaDeviceEventHandler { - fn OnNotify( - &self, - data: *mut windows::Win32::Media::Audio::AUDIO_VOLUME_NOTIFICATION_DATA, - ) -> windows_core::Result<()> { - if let Some(data) = unsafe { data.as_ref() } { - trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::DeviceVolumeChanged { - device_id: self.device_id.clone(), - volume: data.fMasterVolume, - muted: data.bMuted.as_bool(), - }); - } - Ok(()) - } -} - -impl IAudioSessionNotification_Impl for MediaDeviceEventHandler { - fn OnSessionCreated( - &self, - _new_session: Option<&IAudioSessionControl>, - ) -> windows::core::Result<()> { - // println!("SESSION CREATED!") - Ok(()) - } -} - -#[windows::core::implement(IAudioSessionEvents)] -struct MediaSessionEventHandler; - -impl IAudioSessionEvents_Impl for MediaSessionEventHandler { - fn OnChannelVolumeChanged( - &self, - _channel_count: u32, - _new_channel_volume_array: *const f32, - _changed_channel: u32, - _event_context: *const windows::core::GUID, - ) -> windows::core::Result<()> { - // println!("CHANNEL VOLUME CHANGED!"); - Ok(()) - } - - fn OnDisplayNameChanged( - &self, - _new_display_name: &windows::core::PCWSTR, - _event_context: *const windows::core::GUID, - ) -> windows::core::Result<()> { - // println!("DISPLAY NAME CHANGED!"); - Ok(()) - } - - fn OnGroupingParamChanged( - &self, - _new_grouping_param: *const windows::core::GUID, - _event_context: *const windows::core::GUID, - ) -> windows::core::Result<()> { - // println!("GROUPING PARAM CHANGED!"); - Ok(()) - } - - fn OnIconPathChanged( - &self, - _new_icon_path: &windows::core::PCWSTR, - _event_context: *const windows::core::GUID, - ) -> windows::core::Result<()> { - // println!("ICON PATH CHANGED!"); - Ok(()) - } - - fn OnSessionDisconnected( - &self, - _disconnect_reason: windows::Win32::Media::Audio::AudioSessionDisconnectReason, - ) -> windows::core::Result<()> { - // println!("SESSION DISCONNECTED!"); - Ok(()) - } - - fn OnSimpleVolumeChanged( - &self, - _new_volume: f32, - _new_mute: windows::Win32::Foundation::BOOL, - _event_context: *const windows::core::GUID, - ) -> windows::core::Result<()> { - // println!("SIMPLE VOLUME CHANGED!"); - Ok(()) - } - - fn OnStateChanged( - &self, - _new_state: windows::Win32::Media::Audio::AudioSessionState, - ) -> windows::core::Result<()> { - // println!("STATE CHANGED! {:?}", _new_state); - Ok(()) - } -} - -type OnDevicesChange = Box, &Vec) + Send + Sync>; -type OnPlayersChange = Box) + Send + Sync>; -pub struct MediaManager { - inputs: Vec, - outputs: Vec, - playing: Vec, - - registered_devices_callbacks: Vec, - registered_players_callbacks: Vec, - - device_enumerator: IMMDeviceEnumerator, - mm_notification_client: IMMNotificationClient, - devices_audio_endpoint: HashMap, - - media_player_manager: GlobalSystemMediaTransportControlsSessionManager, - media_player_manager_event_handler: TypedEventHandler< - GlobalSystemMediaTransportControlsSessionManager, - SessionsChangedEventArgs, - >, - - media_players: HashMap, - media_player_properties_event_handler: TypedEventHandler< - GlobalSystemMediaTransportControlsSession, - MediaPropertiesChangedEventArgs, - >, - media_player_playback_event_handler: - TypedEventHandler, - /// session id -> (media properties changed event, playback info changed event) - media_player_event_tokens: HashMap, -} - -unsafe impl Send for MediaManager {} - -// getters/setters -impl MediaManager { - pub fn inputs(&self) -> &Vec { - &self.inputs - } - - pub fn outputs(&self) -> &Vec { - &self.outputs - } - - pub fn playing(&self) -> &Vec { - &self.playing - } - - pub fn device_mut(&mut self, id: &str) -> Option<&mut Device> { - self.inputs - .iter_mut() - .chain(self.outputs.iter_mut()) - .find(|d| d.id == id) - } - - pub fn player_mut(&mut self, id: &str) -> Option<&mut MediaPlayer> { - self.playing.iter_mut().find(|p| p.id == id) - } - - pub fn get_raw_device(&self, device_id: &str) -> Option { - unsafe { self.device_enumerator.GetDevice(pcwstr(device_id)) }.ok() - } - - pub fn devices_audio_endpoint( - &self, - ) -> &HashMap { - &self.devices_audio_endpoint - } - - pub fn session_by_id(&self, id: &str) -> Option<&GlobalSystemMediaTransportControlsSession> { - self.media_players.get(id) - } - - pub fn get_recommended_player_id(&self) -> Result { - Ok(self - .media_player_manager - .GetCurrentSession()? - .SourceAppUserModelId()? - .to_string_lossy()) - } -} - -impl MediaManager { - pub fn new() -> Result { - let media_player_manager = - GlobalSystemMediaTransportControlsSessionManager::RequestAsync()?.get()?; - - let mut manager = Self { - inputs: Vec::new(), - outputs: Vec::new(), - playing: Vec::new(), - registered_devices_callbacks: Vec::new(), - registered_players_callbacks: Vec::new(), - - // unsafe com objects - devices_audio_endpoint: HashMap::new(), - device_enumerator: Com::create_instance(&MMDeviceEnumerator)?, - mm_notification_client: MediaManagerEvents.into(), - - media_player_manager, - media_player_manager_event_handler: TypedEventHandler::new( - MediaManagerEvents::on_media_players_changed, - ), - media_players: HashMap::new(), - media_player_event_tokens: HashMap::new(), - media_player_properties_event_handler: TypedEventHandler::new( - MediaManagerEvents::on_media_player_properties_changed, - ), - media_player_playback_event_handler: TypedEventHandler::new( - MediaManagerEvents::on_media_player_playback_changed, - ), - }; - - unsafe { manager.initialize()? }; - Ok(manager) - } - - pub fn on_change_players(&mut self, callback: F) - where - F: Fn(&Vec) + Send + Sync + 'static, - { - self.registered_players_callbacks.push(Box::new(callback)); - } - - pub fn on_change_devices(&mut self, callback: F) - where - F: Fn(&Vec, &Vec) + Send + Sync + 'static, - { - self.registered_devices_callbacks.push(Box::new(callback)); - } - - unsafe fn initialize(&mut self) -> Result<()> { - let collection = self - .device_enumerator - .EnumAudioEndpoints(eAll, DEVICE_STATE_ACTIVE)?; - - for idx in 0..collection.GetCount()? { - self.load_device(&collection.Item(idx)?)?; - } - - self.device_enumerator - .RegisterEndpointNotificationCallback(&self.mm_notification_client)?; - - for session in self.media_player_manager.GetSessions()? { - self.load_media_transport_session(session)?; - } - - self.update_recommended_player(); - self.media_player_manager - .SessionsChanged(&self.media_player_manager_event_handler)?; - - Ok(()) - } - - unsafe fn load_device(&mut self, device: &IMMDevice) -> Result<()> { - let device_id = device.GetId()?.to_string()?; - let device_volume: IAudioEndpointVolume = device.Activate(CLSCTX_ALL, None)?; - let device_session_manager: IAudioSessionManager2 = device.Activate(CLSCTX_ALL, None)?; - - // create Serializable Device object - let mut sessions = Vec::new(); - let enumerator = device_session_manager.GetSessionEnumerator()?; - for session_idx in 0..enumerator.GetCount()? { - let session: IAudioSessionControl2 = enumerator.GetSession(session_idx)?.cast()?; - let volume: ISimpleAudioVolume = session.cast()?; - - let name; - let icon_path; - match WindowsApi::exe_path_by_process(session.GetProcessId()?) { - Ok(path) => { - let shell_item = WindowsApi::get_shell_item(&path)?; - name = match shell_item.GetString(&PKEY_FileDescription) { - Ok(description) => description.to_string()?, - Err(_) => shell_item - .GetDisplayName(SIGDN_NORMALDISPLAY)? - .to_string()?, - } - .replace(".exe", ""); - icon_path = extract_and_save_icon(&get_app_handle(), &path) - .ok() - .map(|p| p.to_string_lossy().to_string()); - } - Err(_) => { - name = session.GetDisplayName()?.to_string()?; - icon_path = None; - } - } - - sessions.push(DeviceChannel { - id: session.GetSessionIdentifier()?.to_string()?, - instance_id: session.GetSessionInstanceIdentifier()?.to_string()?, - process_id: session.GetProcessId()?, - name, - icon_path, - is_system: session.IsSystemSoundsSession().0 == 0, - volume: volume.GetMasterVolume()?, - muted: volume.GetMute()?.as_bool(), - }); - } - - let is_input = device.cast::()?.GetDataFlow()? == eCapture; - let properties = device.OpenPropertyStore(STGM_READ)?; - - let (is_default_multimedia, is_default_communications) = if is_input { - ( - self.is_default_device(&device_id, eCapture, eMultimedia), - self.is_default_device(&device_id, eCapture, eCommunications), - ) - } else { - ( - self.is_default_device(&device_id, eRender, eMultimedia), - self.is_default_device(&device_id, eRender, eCommunications), - ) - }; - - let device = Device { - id: device_id.clone(), - name: properties.GetValue(&PKEY_Device_FriendlyName)?.to_string(), - is_default_multimedia, - is_default_communications, - sessions, - volume: device_volume.GetMasterVolumeLevelScalar()?, - muted: device_volume.GetMute()?.as_bool(), - }; - - if is_input { - self.inputs.push(device); - } else { - self.outputs.push(device); - } - - // listen for device events - let device_volume_callback = IAudioEndpointVolumeCallback::from(MediaDeviceEventHandler { - device_id: device_id.clone(), - }); - - device_volume.RegisterControlChangeNotify(&device_volume_callback)?; - self.devices_audio_endpoint - .insert(device_id, (device_volume, device_volume_callback)); - Ok(()) - } - - fn release_device(&mut self, device_id: &str) -> Result<()> { - if let Some((endpoint, callback)) = self.devices_audio_endpoint.remove(device_id) { - unsafe { endpoint.UnregisterControlChangeNotify(&callback)? }; - } - self.inputs.retain(|d| d.id != device_id); - self.outputs.retain(|d| d.id != device_id); - Ok(()) - } - - fn load_media_transport_session( - &mut self, - session: GlobalSystemMediaTransportControlsSession, - ) -> Result<()> { - let properties = session.TryGetMediaPropertiesAsync()?.get()?; - - let playback_info = session.GetPlaybackInfo()?; - let status = playback_info.PlaybackStatus()?; - let id = session.SourceAppUserModelId()?.to_string_lossy(); - - self.playing.push(MediaPlayer { - title: properties.Title().unwrap_or_default().to_string_lossy(), - author: properties.Artist().unwrap_or_default().to_string_lossy(), - thumbnail: properties - .Thumbnail() - .ok() - .and_then(|stream| WindowsApi::extract_thumbnail_from_ref(stream).ok()), - playing: status == GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing, - default: false, - id: id.clone(), - }); - - // listen for media transport events - self.media_player_event_tokens.insert( - id.clone(), - ( - session.MediaPropertiesChanged(&self.media_player_properties_event_handler)?, - session.PlaybackInfoChanged(&self.media_player_playback_event_handler)?, - ), - ); - self.media_players.insert(id, session); - Ok(()) - } - - fn update_recommended_player(&mut self) { - if let Ok(recommended) = self.get_recommended_player_id() { - for player in &mut self.playing { - player.default = player.id == recommended; - } - } - } - - fn release_media_transport_session(&mut self, player_id: &str) -> Result<()> { - if let Some(session) = self.media_players.remove(player_id) { - if let Some((properties_token, playback_token)) = - self.media_player_event_tokens.remove(player_id) - { - session.RemoveMediaPropertiesChanged(properties_token)?; - session.RemovePlaybackInfoChanged(playback_token)?; - } - } - self.playing.retain(|player| player.id != player_id); - Ok(()) - } - - fn is_default_device(&self, device_id: &str, dataflow: EDataFlow, role: ERole) -> bool { - unsafe { - self.device_enumerator - .GetDefaultAudioEndpoint(dataflow, role) - .and_then(|d| d.GetId()) - .and_then(|id| id.to_hstring()) - .map(|id| id.to_string()) - .map(|id| id == device_id) - .unwrap_or(false) - } - } - - fn emit_event(&mut self, event: MediaEvent) { - let is_changing_players = matches!( - event, - MediaEvent::MediaPlayerAdded(_) - | MediaEvent::MediaPlayerRemoved(_) - | MediaEvent::MediaPlayerPropertiesChanged { .. } - | MediaEvent::MediaPlayerPlaybackStatusChanged { .. } - ); - - log_error!(self.process_event(event)); - - if is_changing_players { - self.update_recommended_player(); - for callback in &self.registered_players_callbacks { - callback(self.playing()); - } - } else { - for callback in &self.registered_devices_callbacks { - callback(self.inputs(), self.outputs()); - } - } - } - - fn process_event(&mut self, event: MediaEvent) -> Result<()> { - match event { - MediaEvent::DeviceAdded(device_id) => { - if let Some(device) = self.get_raw_device(&device_id) { - unsafe { self.load_device(&device)? }; - } - } - MediaEvent::DeviceRemoved(device_id) => { - self.release_device(&device_id)?; - } - MediaEvent::DefaultDeviceChanged { - flow, - role, - device_id, - } => { - let devices = if flow == eCapture { - &mut self.inputs - } else { - &mut self.outputs - }; - - for device in devices { - if role == eMultimedia { - device.is_default_multimedia = device.id == device_id; - } else if role == eCommunications { - device.is_default_communications = device.id == device_id; - } - } - } - MediaEvent::DeviceVolumeChanged { - device_id, - volume, - muted, - } => { - if let Some(device) = self.device_mut(&device_id) { - device.volume = volume; - device.muted = muted; - } - } - MediaEvent::MediaPlayerAdded(session) => { - self.load_media_transport_session(session)?; - } - MediaEvent::MediaPlayerRemoved(id) => { - self.release_media_transport_session(&id)?; - } - MediaEvent::MediaPlayerPropertiesChanged { - id, - title, - author, - thumbnail, - } => { - if let Some(player) = self.player_mut(&id) { - player.title = title; - player.author = author; - player.thumbnail = thumbnail; - } - } - MediaEvent::MediaPlayerPlaybackStatusChanged { id, playing } => { - if let Some(player) = self.player_mut(&id) { - player.playing = playing; - } - } - } - Ok(()) - } - - pub fn set_default_device(&mut self, id: &str, role: &str) -> Result<()> { - let role = match role { - "multimedia" => eMultimedia, - "communications" => eCommunications, - "console" => eConsole, - _ => return Err("invalid role".into()), - }; - - let policy: IPolicyConfig = Com::create_instance(&PolicyConfig)?; - unsafe { - policy.SetDefaultEndpoint(pcwstr(id), role)?; - } - Ok(()) - } - - /// Release all resources - /// should be called on application exit - pub fn release(&mut self) { - let player_ids = self.playing.iter().map(|p| p.id.clone()).collect_vec(); - - for player_id in player_ids { - log_error!(self.release_media_transport_session(&player_id)); - } - - let device_ids = self - .inputs - .iter() - .map(|d| d.id.clone()) - .chain(self.outputs.iter().map(|d| d.id.clone())) - .collect_vec(); - - for device_id in device_ids { - log_error!(self.release_device(&device_id)); - } - } -} +use std::{collections::HashMap, path::PathBuf, sync::Arc}; + +use itertools::Itertools; +use lazy_static::lazy_static; +use parking_lot::Mutex; +use windows::{ + Foundation::{EventRegistrationToken, TypedEventHandler}, + Media::Control::{ + GlobalSystemMediaTransportControlsSession, + GlobalSystemMediaTransportControlsSessionManager, + GlobalSystemMediaTransportControlsSessionPlaybackStatus, MediaPropertiesChangedEventArgs, + PlaybackInfoChangedEventArgs, SessionsChangedEventArgs, + }, + Win32::{ + Devices::FunctionDiscovery::PKEY_Device_FriendlyName, + Media::Audio::{ + eAll, eCapture, eCommunications, eConsole, eMultimedia, eRender, EDataFlow, ERole, + Endpoints::{ + IAudioEndpointVolume, IAudioEndpointVolumeCallback, + IAudioEndpointVolumeCallback_Impl, + }, + IAudioSessionControl, IAudioSessionControl2, IAudioSessionEvents, + IAudioSessionEvents_Impl, IAudioSessionManager2, IAudioSessionNotification, + IAudioSessionNotification_Impl, IMMDevice, IMMDeviceEnumerator, IMMEndpoint, + IMMNotificationClient, IMMNotificationClient_Impl, ISimpleAudioVolume, + MMDeviceEnumerator, DEVICE_STATE_ACTIVE, + }, + Storage::EnhancedStorage::PKEY_FileDescription, + System::Com::{CLSCTX_ALL, STGM_READ}, + UI::Shell::{PropertiesSystem::PROPERTYKEY, SIGDN_NORMALDISPLAY}, + }, +}; +use windows_core::Interface; + +use crate::{ + error_handler::Result, + log_error, + seelen::get_app_handle, + seelen_weg::icon_extractor::extract_and_save_icon, + trace_lock, + utils::pcwstr, + windows_api::{Com, WindowsApi}, +}; + +use super::domain::{Device, DeviceChannel, IPolicyConfig, MediaPlayer, PolicyConfig}; + +lazy_static! { + pub static ref MEDIA_MANAGER: Arc> = Arc::new(Mutex::new( + MediaManager::new().expect("Failed to create media manager") + )); + pub static ref REG_PROPERTY_EVENTS: Arc>> = + Arc::new(Mutex::new(HashMap::new())); + pub static ref REG_PLAYBACK_EVENTS: Arc>> = + Arc::new(Mutex::new(HashMap::new())); +} + +enum MediaEvent { + DeviceAdded(String), + DeviceRemoved(String), + DefaultDeviceChanged { + flow: EDataFlow, + role: ERole, + device_id: String, + }, + DeviceVolumeChanged { + device_id: String, + volume: f32, + muted: bool, + }, + MediaPlayerAdded(GlobalSystemMediaTransportControlsSession), + MediaPlayerRemoved(String), + MediaPlayerPropertiesChanged { + id: String, + title: String, + author: String, + thumbnail: Option, + }, + MediaPlayerPlaybackStatusChanged { + id: String, + playing: bool, + }, +} + +#[windows_core::implement(IMMNotificationClient)] +struct MediaManagerEvents; + +impl IMMNotificationClient_Impl for MediaManagerEvents { + fn OnDefaultDeviceChanged( + &self, + flow: EDataFlow, + role: ERole, + device_id: &windows_core::PCWSTR, + ) -> windows_core::Result<()> { + trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::DefaultDeviceChanged { + flow, + role, + device_id: unsafe { device_id.to_string()? }, + }); + Ok(()) + } + + fn OnDeviceAdded(&self, device_id: &windows_core::PCWSTR) -> windows_core::Result<()> { + trace_lock!(MEDIA_MANAGER) + .emit_event(MediaEvent::DeviceAdded(unsafe { device_id.to_string()? })); + Ok(()) + } + + fn OnDeviceRemoved(&self, device_id: &windows_core::PCWSTR) -> windows_core::Result<()> { + trace_lock!(MEDIA_MANAGER) + .emit_event(MediaEvent::DeviceRemoved(unsafe { device_id.to_string()? })); + Ok(()) + } + + fn OnDeviceStateChanged( + &self, + device_id: &windows_core::PCWSTR, + new_device_state: windows::Win32::Media::Audio::DEVICE_STATE, + ) -> windows_core::Result<()> { + let device_id = unsafe { device_id.to_string()? }; + match new_device_state { + DEVICE_STATE_ACTIVE => { + trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::DeviceAdded(device_id)); + } + _ => { + trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::DeviceRemoved(device_id)); + } + } + Ok(()) + } + + fn OnPropertyValueChanged( + &self, + _device_id: &windows_core::PCWSTR, + _key: &PROPERTYKEY, + ) -> windows_core::Result<()> { + Ok(()) + } +} + +impl MediaManagerEvents { + fn on_media_player_properties_changed( + session: &Option, + _args: &Option, + ) -> windows_core::Result<()> { + if let Some(session) = session { + let id = session.SourceAppUserModelId()?.to_string(); + let properties = session.TryGetMediaPropertiesAsync()?.get()?; + trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::MediaPlayerPropertiesChanged { + id, + title: properties.Title()?.to_string(), + author: properties.Artist()?.to_string(), + thumbnail: WindowsApi::extract_thumbnail_from_ref(properties.Thumbnail()?).ok(), + }); + } + Ok(()) + } + + fn on_media_player_playback_changed( + session: &Option, + _args: &Option, + ) -> windows_core::Result<()> { + if let Some(session) = session { + let playback = session.GetPlaybackInfo()?; + trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::MediaPlayerPlaybackStatusChanged { + id: session.SourceAppUserModelId()?.to_string(), + playing: playback.PlaybackStatus()? + == GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing, + }); + } + Ok(()) + } + + fn on_media_players_changed( + session_manager: &Option, + _args: &Option, + ) -> windows_core::Result<()> { + if let Some(session_manager) = session_manager { + let mut current_list = trace_lock!(MEDIA_MANAGER) + .playing() + .iter() + .map(|session| session.id.clone()) + .collect_vec(); + + for session in session_manager.GetSessions()? { + let id = session.SourceAppUserModelId()?.to_string(); + if !current_list.contains(&id) { + trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::MediaPlayerAdded(session)); + } + current_list.retain(|x| *x != id); + } + + for id in current_list { + trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::MediaPlayerRemoved(id)); + } + } + Ok(()) + } +} + +#[windows::core::implement(IAudioEndpointVolumeCallback, IAudioSessionNotification)] +struct MediaDeviceEventHandler { + device_id: String, +} + +impl IAudioEndpointVolumeCallback_Impl for MediaDeviceEventHandler { + fn OnNotify( + &self, + data: *mut windows::Win32::Media::Audio::AUDIO_VOLUME_NOTIFICATION_DATA, + ) -> windows_core::Result<()> { + if let Some(data) = unsafe { data.as_ref() } { + trace_lock!(MEDIA_MANAGER).emit_event(MediaEvent::DeviceVolumeChanged { + device_id: self.device_id.clone(), + volume: data.fMasterVolume, + muted: data.bMuted.as_bool(), + }); + } + Ok(()) + } +} + +impl IAudioSessionNotification_Impl for MediaDeviceEventHandler { + fn OnSessionCreated( + &self, + _new_session: Option<&IAudioSessionControl>, + ) -> windows::core::Result<()> { + // println!("SESSION CREATED!") + Ok(()) + } +} + +#[windows::core::implement(IAudioSessionEvents)] +struct MediaSessionEventHandler; + +impl IAudioSessionEvents_Impl for MediaSessionEventHandler { + fn OnChannelVolumeChanged( + &self, + _channel_count: u32, + _new_channel_volume_array: *const f32, + _changed_channel: u32, + _event_context: *const windows::core::GUID, + ) -> windows::core::Result<()> { + // println!("CHANNEL VOLUME CHANGED!"); + Ok(()) + } + + fn OnDisplayNameChanged( + &self, + _new_display_name: &windows::core::PCWSTR, + _event_context: *const windows::core::GUID, + ) -> windows::core::Result<()> { + // println!("DISPLAY NAME CHANGED!"); + Ok(()) + } + + fn OnGroupingParamChanged( + &self, + _new_grouping_param: *const windows::core::GUID, + _event_context: *const windows::core::GUID, + ) -> windows::core::Result<()> { + // println!("GROUPING PARAM CHANGED!"); + Ok(()) + } + + fn OnIconPathChanged( + &self, + _new_icon_path: &windows::core::PCWSTR, + _event_context: *const windows::core::GUID, + ) -> windows::core::Result<()> { + // println!("ICON PATH CHANGED!"); + Ok(()) + } + + fn OnSessionDisconnected( + &self, + _disconnect_reason: windows::Win32::Media::Audio::AudioSessionDisconnectReason, + ) -> windows::core::Result<()> { + // println!("SESSION DISCONNECTED!"); + Ok(()) + } + + fn OnSimpleVolumeChanged( + &self, + _new_volume: f32, + _new_mute: windows::Win32::Foundation::BOOL, + _event_context: *const windows::core::GUID, + ) -> windows::core::Result<()> { + // println!("SIMPLE VOLUME CHANGED!"); + Ok(()) + } + + fn OnStateChanged( + &self, + _new_state: windows::Win32::Media::Audio::AudioSessionState, + ) -> windows::core::Result<()> { + // println!("STATE CHANGED! {:?}", _new_state); + Ok(()) + } +} + +type OnDevicesChange = Box, &Vec) + Send + Sync>; +type OnPlayersChange = Box) + Send + Sync>; +pub struct MediaManager { + inputs: Vec, + outputs: Vec, + playing: Vec, + + registered_devices_callbacks: Vec, + registered_players_callbacks: Vec, + + device_enumerator: IMMDeviceEnumerator, + mm_notification_client: IMMNotificationClient, + devices_audio_endpoint: HashMap, + + media_player_manager: GlobalSystemMediaTransportControlsSessionManager, + media_player_manager_event_handler: TypedEventHandler< + GlobalSystemMediaTransportControlsSessionManager, + SessionsChangedEventArgs, + >, + + media_players: HashMap, + media_player_properties_event_handler: TypedEventHandler< + GlobalSystemMediaTransportControlsSession, + MediaPropertiesChangedEventArgs, + >, + media_player_playback_event_handler: + TypedEventHandler, + /// session id -> (media properties changed event, playback info changed event) + media_player_event_tokens: HashMap, +} + +unsafe impl Send for MediaManager {} + +// getters/setters +impl MediaManager { + pub fn inputs(&self) -> &Vec { + &self.inputs + } + + pub fn outputs(&self) -> &Vec { + &self.outputs + } + + pub fn playing(&self) -> &Vec { + &self.playing + } + + pub fn device_mut(&mut self, id: &str) -> Option<&mut Device> { + self.inputs + .iter_mut() + .chain(self.outputs.iter_mut()) + .find(|d| d.id == id) + } + + pub fn player_mut(&mut self, id: &str) -> Option<&mut MediaPlayer> { + self.playing.iter_mut().find(|p| p.id == id) + } + + pub fn get_raw_device(&self, device_id: &str) -> Option { + unsafe { self.device_enumerator.GetDevice(pcwstr(device_id)) }.ok() + } + + pub fn devices_audio_endpoint( + &self, + ) -> &HashMap { + &self.devices_audio_endpoint + } + + pub fn session_by_id(&self, id: &str) -> Option<&GlobalSystemMediaTransportControlsSession> { + self.media_players.get(id) + } + + pub fn get_recommended_player_id(&self) -> Result { + Ok(self + .media_player_manager + .GetCurrentSession()? + .SourceAppUserModelId()? + .to_string_lossy()) + } +} + +impl MediaManager { + pub fn new() -> Result { + let media_player_manager = + GlobalSystemMediaTransportControlsSessionManager::RequestAsync()?.get()?; + + let mut manager = Self { + inputs: Vec::new(), + outputs: Vec::new(), + playing: Vec::new(), + registered_devices_callbacks: Vec::new(), + registered_players_callbacks: Vec::new(), + + // unsafe com objects + devices_audio_endpoint: HashMap::new(), + device_enumerator: Com::create_instance(&MMDeviceEnumerator)?, + mm_notification_client: MediaManagerEvents.into(), + + media_player_manager, + media_player_manager_event_handler: TypedEventHandler::new( + MediaManagerEvents::on_media_players_changed, + ), + media_players: HashMap::new(), + media_player_event_tokens: HashMap::new(), + media_player_properties_event_handler: TypedEventHandler::new( + MediaManagerEvents::on_media_player_properties_changed, + ), + media_player_playback_event_handler: TypedEventHandler::new( + MediaManagerEvents::on_media_player_playback_changed, + ), + }; + + unsafe { manager.initialize()? }; + Ok(manager) + } + + pub fn on_change_players(&mut self, callback: F) + where + F: Fn(&Vec) + Send + Sync + 'static, + { + self.registered_players_callbacks.push(Box::new(callback)); + } + + pub fn on_change_devices(&mut self, callback: F) + where + F: Fn(&Vec, &Vec) + Send + Sync + 'static, + { + self.registered_devices_callbacks.push(Box::new(callback)); + } + + unsafe fn initialize(&mut self) -> Result<()> { + let collection = self + .device_enumerator + .EnumAudioEndpoints(eAll, DEVICE_STATE_ACTIVE)?; + + for idx in 0..collection.GetCount()? { + self.load_device(&collection.Item(idx)?)?; + } + + self.device_enumerator + .RegisterEndpointNotificationCallback(&self.mm_notification_client)?; + + for session in self.media_player_manager.GetSessions()? { + self.load_media_transport_session(session)?; + } + + self.update_recommended_player(); + self.media_player_manager + .SessionsChanged(&self.media_player_manager_event_handler)?; + + Ok(()) + } + + unsafe fn load_device(&mut self, device: &IMMDevice) -> Result<()> { + let device_id = device.GetId()?.to_string()?; + let device_volume: IAudioEndpointVolume = device.Activate(CLSCTX_ALL, None)?; + let device_session_manager: IAudioSessionManager2 = device.Activate(CLSCTX_ALL, None)?; + + // create Serializable Device object + let mut sessions = Vec::new(); + let enumerator = device_session_manager.GetSessionEnumerator()?; + for session_idx in 0..enumerator.GetCount()? { + let session: IAudioSessionControl2 = enumerator.GetSession(session_idx)?.cast()?; + let volume: ISimpleAudioVolume = session.cast()?; + + let name; + let icon_path; + match WindowsApi::exe_path_by_process(session.GetProcessId()?) { + Ok(path) => { + let shell_item = WindowsApi::get_shell_item(&path)?; + name = match shell_item.GetString(&PKEY_FileDescription) { + Ok(description) => description.to_string()?, + Err(_) => shell_item + .GetDisplayName(SIGDN_NORMALDISPLAY)? + .to_string()?, + } + .replace(".exe", ""); + icon_path = extract_and_save_icon(&get_app_handle(), &path) + .ok() + .map(|p| p.to_string_lossy().to_string()); + } + Err(_) => { + name = session.GetDisplayName()?.to_string()?; + icon_path = None; + } + } + + sessions.push(DeviceChannel { + id: session.GetSessionIdentifier()?.to_string()?, + instance_id: session.GetSessionInstanceIdentifier()?.to_string()?, + process_id: session.GetProcessId()?, + name, + icon_path, + is_system: session.IsSystemSoundsSession().0 == 0, + volume: volume.GetMasterVolume()?, + muted: volume.GetMute()?.as_bool(), + }); + } + + let is_input = device.cast::()?.GetDataFlow()? == eCapture; + let properties = device.OpenPropertyStore(STGM_READ)?; + + let (is_default_multimedia, is_default_communications) = if is_input { + ( + self.is_default_device(&device_id, eCapture, eMultimedia), + self.is_default_device(&device_id, eCapture, eCommunications), + ) + } else { + ( + self.is_default_device(&device_id, eRender, eMultimedia), + self.is_default_device(&device_id, eRender, eCommunications), + ) + }; + + let device = Device { + id: device_id.clone(), + name: properties.GetValue(&PKEY_Device_FriendlyName)?.to_string(), + is_default_multimedia, + is_default_communications, + sessions, + volume: device_volume.GetMasterVolumeLevelScalar()?, + muted: device_volume.GetMute()?.as_bool(), + }; + + if is_input { + self.inputs.push(device); + } else { + self.outputs.push(device); + } + + // listen for device events + let device_volume_callback = IAudioEndpointVolumeCallback::from(MediaDeviceEventHandler { + device_id: device_id.clone(), + }); + + device_volume.RegisterControlChangeNotify(&device_volume_callback)?; + self.devices_audio_endpoint + .insert(device_id, (device_volume, device_volume_callback)); + Ok(()) + } + + fn release_device(&mut self, device_id: &str) -> Result<()> { + if let Some((endpoint, callback)) = self.devices_audio_endpoint.remove(device_id) { + unsafe { endpoint.UnregisterControlChangeNotify(&callback)? }; + } + self.inputs.retain(|d| d.id != device_id); + self.outputs.retain(|d| d.id != device_id); + Ok(()) + } + + fn load_media_transport_session( + &mut self, + session: GlobalSystemMediaTransportControlsSession, + ) -> Result<()> { + let properties = session.TryGetMediaPropertiesAsync()?.get()?; + + let playback_info = session.GetPlaybackInfo()?; + let status = playback_info.PlaybackStatus()?; + let id = session.SourceAppUserModelId()?.to_string_lossy(); + + self.playing.push(MediaPlayer { + title: properties.Title().unwrap_or_default().to_string_lossy(), + author: properties.Artist().unwrap_or_default().to_string_lossy(), + thumbnail: properties + .Thumbnail() + .ok() + .and_then(|stream| WindowsApi::extract_thumbnail_from_ref(stream).ok()), + playing: status == GlobalSystemMediaTransportControlsSessionPlaybackStatus::Playing, + default: false, + id: id.clone(), + }); + + // listen for media transport events + self.media_player_event_tokens.insert( + id.clone(), + ( + session.MediaPropertiesChanged(&self.media_player_properties_event_handler)?, + session.PlaybackInfoChanged(&self.media_player_playback_event_handler)?, + ), + ); + self.media_players.insert(id, session); + Ok(()) + } + + fn update_recommended_player(&mut self) { + if let Ok(recommended) = self.get_recommended_player_id() { + for player in &mut self.playing { + player.default = player.id == recommended; + } + } + } + + fn release_media_transport_session(&mut self, player_id: &str) -> Result<()> { + if let Some(session) = self.media_players.remove(player_id) { + if let Some((properties_token, playback_token)) = + self.media_player_event_tokens.remove(player_id) + { + session.RemoveMediaPropertiesChanged(properties_token)?; + session.RemovePlaybackInfoChanged(playback_token)?; + } + } + self.playing.retain(|player| player.id != player_id); + Ok(()) + } + + fn is_default_device(&self, device_id: &str, dataflow: EDataFlow, role: ERole) -> bool { + unsafe { + self.device_enumerator + .GetDefaultAudioEndpoint(dataflow, role) + .and_then(|d| d.GetId()) + .and_then(|id| id.to_hstring()) + .map(|id| id.to_string()) + .map(|id| id == device_id) + .unwrap_or(false) + } + } + + fn emit_event(&mut self, event: MediaEvent) { + let is_changing_players = matches!( + event, + MediaEvent::MediaPlayerAdded(_) + | MediaEvent::MediaPlayerRemoved(_) + | MediaEvent::MediaPlayerPropertiesChanged { .. } + | MediaEvent::MediaPlayerPlaybackStatusChanged { .. } + ); + + log_error!(self.process_event(event)); + + if is_changing_players { + self.update_recommended_player(); + for callback in &self.registered_players_callbacks { + callback(self.playing()); + } + } else { + for callback in &self.registered_devices_callbacks { + callback(self.inputs(), self.outputs()); + } + } + } + + fn process_event(&mut self, event: MediaEvent) -> Result<()> { + match event { + MediaEvent::DeviceAdded(device_id) => { + if let Some(device) = self.get_raw_device(&device_id) { + unsafe { self.load_device(&device)? }; + } + } + MediaEvent::DeviceRemoved(device_id) => { + self.release_device(&device_id)?; + } + MediaEvent::DefaultDeviceChanged { + flow, + role, + device_id, + } => { + let devices = if flow == eCapture { + &mut self.inputs + } else { + &mut self.outputs + }; + + for device in devices { + if role == eMultimedia { + device.is_default_multimedia = device.id == device_id; + } else if role == eCommunications { + device.is_default_communications = device.id == device_id; + } + } + } + MediaEvent::DeviceVolumeChanged { + device_id, + volume, + muted, + } => { + if let Some(device) = self.device_mut(&device_id) { + device.volume = volume; + device.muted = muted; + } + } + MediaEvent::MediaPlayerAdded(session) => { + self.load_media_transport_session(session)?; + } + MediaEvent::MediaPlayerRemoved(id) => { + self.release_media_transport_session(&id)?; + } + MediaEvent::MediaPlayerPropertiesChanged { + id, + title, + author, + thumbnail, + } => { + if let Some(player) = self.player_mut(&id) { + player.title = title; + player.author = author; + player.thumbnail = thumbnail; + } + } + MediaEvent::MediaPlayerPlaybackStatusChanged { id, playing } => { + if let Some(player) = self.player_mut(&id) { + player.playing = playing; + } + } + } + Ok(()) + } + + pub fn set_default_device(&mut self, id: &str, role: &str) -> Result<()> { + let role = match role { + "multimedia" => eMultimedia, + "communications" => eCommunications, + "console" => eConsole, + _ => return Err("invalid role".into()), + }; + + let policy: IPolicyConfig = Com::create_instance(&PolicyConfig)?; + unsafe { + policy.SetDefaultEndpoint(pcwstr(id), role)?; + } + Ok(()) + } + + /// Release all resources + /// should be called on application exit + pub fn release(&mut self) { + let player_ids = self.playing.iter().map(|p| p.id.clone()).collect_vec(); + + for player_id in player_ids { + log_error!(self.release_media_transport_session(&player_id)); + } + + let device_ids = self + .inputs + .iter() + .map(|d| d.id.clone()) + .chain(self.outputs.iter().map(|d| d.id.clone())) + .collect_vec(); + + for device_id in device_ids { + log_error!(self.release_device(&device_id)); + } + } +} diff --git a/src/background/modules/media/domain.rs b/src/background/modules/media/domain.rs index 4118a8ad..ba2d8c92 100644 --- a/src/background/modules/media/domain.rs +++ b/src/background/modules/media/domain.rs @@ -1,270 +1,270 @@ -use std::{ffi::c_void, mem::zeroed, path::PathBuf}; - -use serde::Serialize; - -use windows::{ - core::{Interface, Param, Result, GUID, HRESULT, PCWSTR, PROPVARIANT}, - Devices::Custom::DeviceSharingMode, - Win32::{ - Foundation::BOOL, - Media::Audio::{ERole, WAVEFORMATEX}, - UI::Shell::PropertiesSystem::PROPERTYKEY, - }, -}; - -#[derive(Debug, Serialize)] -pub struct MediaPlayer { - pub id: String, - pub title: String, - pub author: String, - pub thumbnail: Option, - pub playing: bool, - pub default: bool, -} - -#[derive(Debug, Serialize)] -pub struct DeviceChannel { - pub id: String, - pub instance_id: String, - pub process_id: u32, - pub name: String, - pub icon_path: Option, - pub is_system: bool, - pub volume: f32, - pub muted: bool, -} - -#[derive(Debug, Serialize)] -pub struct Device { - pub id: String, - pub name: String, - pub is_default_multimedia: bool, - pub is_default_communications: bool, - pub sessions: Vec, - pub volume: f32, - pub muted: bool, -} - -/* Windows IPolicyConfig UNDOCUMENTED INTERFACE */ -#[allow(non_upper_case_globals)] -pub const PolicyConfig: GUID = GUID::from_u128(0x870af99c_171d_4f9e_af0d_e63df40c2bc9); - -windows_core::imp::define_interface!( - IPolicyConfig, - IPolicyConfig_Vtbl, - 0xf8679f50_850a_41cf_9c72_430f290290c8 -); - -windows_core::imp::interface_hierarchy!(IPolicyConfig, windows_core::IUnknown); -#[allow(non_snake_case)] -impl IPolicyConfig { - pub unsafe fn GetMixFormat(&self, device_id: impl Param) -> Result<*mut WAVEFORMATEX> { - let mut result__ = zeroed::<*mut WAVEFORMATEX>(); - (Interface::vtable(self).GetMixFormat)( - Interface::as_raw(self), - device_id.param().abi(), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - - pub unsafe fn GetDeviceFormat( - &self, - device_id: impl Param, - default: impl Into, - ) -> Result<*mut WAVEFORMATEX> { - let mut result__ = zeroed::<*mut WAVEFORMATEX>(); - (Interface::vtable(self).GetDeviceFormat)( - Interface::as_raw(self), - device_id.param().abi(), - default.into().0, - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - - pub unsafe fn ResetDeviceFormat(&self, device_id: impl Param) -> Result<()> { - (Interface::vtable(self).ResetDeviceFormat)( - Interface::as_raw(self), - device_id.param().abi(), - ) - .ok() - } - - pub unsafe fn SetDeviceFormat( - &self, - device_id: impl Param, - mut endpoint_format: WAVEFORMATEX, - mut mix_format: WAVEFORMATEX, - ) -> Result<()> { - (Interface::vtable(self).SetDeviceFormat)( - Interface::as_raw(self), - device_id.param().abi(), - &mut endpoint_format, - &mut mix_format, - ) - .ok() - } - - pub unsafe fn GetProcessingPeriod( - &self, - device_id: impl Param, - default: impl Into, - default_period: *mut i64, - min_period: *mut i64, - ) -> Result<()> { - (Interface::vtable(self).GetProcessingPeriod)( - Interface::as_raw(self), - device_id.param().abi(), - default.into().0, - default_period, - min_period, - ) - .ok() - } - - pub unsafe fn SetProcessingPeriod( - &self, - device_id: impl Param, - period: *mut i64, - ) -> Result<()> { - (Interface::vtable(self).SetProcessingPeriod)( - Interface::as_raw(self), - device_id.param().abi(), - period, - ) - .ok() - } - - pub unsafe fn GetShareMode(&self, device_id: impl Param) -> Result { - let mut result__ = zeroed::(); - (Interface::vtable(self).GetShareMode)( - Interface::as_raw(self), - device_id.param().abi(), - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - - pub unsafe fn SetShareMode( - &self, - device_id: impl Param, - mut mode: DeviceSharingMode, - ) -> Result<()> { - (Interface::vtable(self).SetShareMode)( - Interface::as_raw(self), - device_id.param().abi(), - &mut mode, - ) - .ok() - } - - pub unsafe fn GetPropertyValue( - &self, - device_id: impl Param, - bFxStore: impl Into, - key: *const PROPERTYKEY, - ) -> Result { - let mut result__ = zeroed(); - (Interface::vtable(self).GetPropertyValue)( - Interface::as_raw(self), - device_id.param().abi(), - bFxStore.into().0, - key, - &mut result__, - ) - .and_then(|| windows_core::Type::from_abi(result__)) - } - - pub unsafe fn SetPropertyValue( - &self, - device_id: impl Param, - bFxStore: impl Into, - key: *const PROPERTYKEY, - propvar: *const PROPVARIANT, - ) -> Result<()> { - (Interface::vtable(self).SetPropertyValue)( - Interface::as_raw(self), - device_id.param().abi(), - bFxStore.into().0, - key, - std::mem::transmute::< - *const windows_core::PROPVARIANT, - *const std::mem::MaybeUninit, - >(propvar), - ) - .ok() - } - - pub unsafe fn SetDefaultEndpoint( - &self, - device_id: impl Param, - role: ERole, - ) -> Result<()> { - (Interface::vtable(self).SetDefaultEndpoint)( - Interface::as_raw(self), - device_id.param().abi(), - role, - ) - .ok() - } - - pub unsafe fn SetEndpointVisibility( - &self, - device_id: impl Param, - visible: impl Into, - ) -> Result<()> { - (Interface::vtable(self).SetEndpointVisibility)( - Interface::as_raw(self), - device_id.param().abi(), - visible.into().0, - ) - .ok() - } -} - -#[repr(C)] -#[doc(hidden)] -#[allow(non_snake_case, non_camel_case_types)] -pub struct IPolicyConfig_Vtbl { - pub base__: ::windows::core::IUnknown_Vtbl, - pub GetMixFormat: - unsafe extern "system" fn(this: *mut c_void, PCWSTR, *mut *mut WAVEFORMATEX) -> HRESULT, - pub GetDeviceFormat: unsafe extern "system" fn( - this: *mut c_void, - PCWSTR, - i32, - *mut *mut WAVEFORMATEX, - ) -> HRESULT, - pub ResetDeviceFormat: unsafe extern "system" fn(this: *mut c_void, PCWSTR) -> HRESULT, - pub SetDeviceFormat: unsafe extern "system" fn( - this: *mut c_void, - PCWSTR, - *mut WAVEFORMATEX, - *mut WAVEFORMATEX, - ) -> HRESULT, - pub GetProcessingPeriod: - unsafe extern "system" fn(this: *mut c_void, PCWSTR, i32, *mut i64, *mut i64) -> HRESULT, - pub SetProcessingPeriod: - unsafe extern "system" fn(this: *mut c_void, PCWSTR, *mut i64) -> HRESULT, - pub GetShareMode: - unsafe extern "system" fn(this: *mut c_void, PCWSTR, *mut DeviceSharingMode) -> HRESULT, - pub SetShareMode: - unsafe extern "system" fn(this: *mut c_void, PCWSTR, *mut DeviceSharingMode) -> HRESULT, - pub GetPropertyValue: unsafe extern "system" fn( - this: *mut c_void, - PCWSTR, - i32, - *const PROPERTYKEY, - *mut std::mem::MaybeUninit, - ) -> HRESULT, - pub SetPropertyValue: unsafe extern "system" fn( - this: *mut c_void, - PCWSTR, - i32, - *const PROPERTYKEY, - *const std::mem::MaybeUninit, - ) -> HRESULT, - pub SetDefaultEndpoint: unsafe extern "system" fn(this: *mut c_void, PCWSTR, ERole) -> HRESULT, - pub SetEndpointVisibility: unsafe extern "system" fn(this: *mut c_void, PCWSTR, i32) -> HRESULT, -} +use std::{ffi::c_void, mem::zeroed, path::PathBuf}; + +use serde::Serialize; + +use windows::{ + core::{Interface, Param, Result, GUID, HRESULT, PCWSTR, PROPVARIANT}, + Devices::Custom::DeviceSharingMode, + Win32::{ + Foundation::BOOL, + Media::Audio::{ERole, WAVEFORMATEX}, + UI::Shell::PropertiesSystem::PROPERTYKEY, + }, +}; + +#[derive(Debug, Serialize)] +pub struct MediaPlayer { + pub id: String, + pub title: String, + pub author: String, + pub thumbnail: Option, + pub playing: bool, + pub default: bool, +} + +#[derive(Debug, Serialize)] +pub struct DeviceChannel { + pub id: String, + pub instance_id: String, + pub process_id: u32, + pub name: String, + pub icon_path: Option, + pub is_system: bool, + pub volume: f32, + pub muted: bool, +} + +#[derive(Debug, Serialize)] +pub struct Device { + pub id: String, + pub name: String, + pub is_default_multimedia: bool, + pub is_default_communications: bool, + pub sessions: Vec, + pub volume: f32, + pub muted: bool, +} + +/* Windows IPolicyConfig UNDOCUMENTED INTERFACE */ +#[allow(non_upper_case_globals)] +pub const PolicyConfig: GUID = GUID::from_u128(0x870af99c_171d_4f9e_af0d_e63df40c2bc9); + +windows_core::imp::define_interface!( + IPolicyConfig, + IPolicyConfig_Vtbl, + 0xf8679f50_850a_41cf_9c72_430f290290c8 +); + +windows_core::imp::interface_hierarchy!(IPolicyConfig, windows_core::IUnknown); +#[allow(non_snake_case)] +impl IPolicyConfig { + pub unsafe fn GetMixFormat(&self, device_id: impl Param) -> Result<*mut WAVEFORMATEX> { + let mut result__ = zeroed::<*mut WAVEFORMATEX>(); + (Interface::vtable(self).GetMixFormat)( + Interface::as_raw(self), + device_id.param().abi(), + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + + pub unsafe fn GetDeviceFormat( + &self, + device_id: impl Param, + default: impl Into, + ) -> Result<*mut WAVEFORMATEX> { + let mut result__ = zeroed::<*mut WAVEFORMATEX>(); + (Interface::vtable(self).GetDeviceFormat)( + Interface::as_raw(self), + device_id.param().abi(), + default.into().0, + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + + pub unsafe fn ResetDeviceFormat(&self, device_id: impl Param) -> Result<()> { + (Interface::vtable(self).ResetDeviceFormat)( + Interface::as_raw(self), + device_id.param().abi(), + ) + .ok() + } + + pub unsafe fn SetDeviceFormat( + &self, + device_id: impl Param, + mut endpoint_format: WAVEFORMATEX, + mut mix_format: WAVEFORMATEX, + ) -> Result<()> { + (Interface::vtable(self).SetDeviceFormat)( + Interface::as_raw(self), + device_id.param().abi(), + &mut endpoint_format, + &mut mix_format, + ) + .ok() + } + + pub unsafe fn GetProcessingPeriod( + &self, + device_id: impl Param, + default: impl Into, + default_period: *mut i64, + min_period: *mut i64, + ) -> Result<()> { + (Interface::vtable(self).GetProcessingPeriod)( + Interface::as_raw(self), + device_id.param().abi(), + default.into().0, + default_period, + min_period, + ) + .ok() + } + + pub unsafe fn SetProcessingPeriod( + &self, + device_id: impl Param, + period: *mut i64, + ) -> Result<()> { + (Interface::vtable(self).SetProcessingPeriod)( + Interface::as_raw(self), + device_id.param().abi(), + period, + ) + .ok() + } + + pub unsafe fn GetShareMode(&self, device_id: impl Param) -> Result { + let mut result__ = zeroed::(); + (Interface::vtable(self).GetShareMode)( + Interface::as_raw(self), + device_id.param().abi(), + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + + pub unsafe fn SetShareMode( + &self, + device_id: impl Param, + mut mode: DeviceSharingMode, + ) -> Result<()> { + (Interface::vtable(self).SetShareMode)( + Interface::as_raw(self), + device_id.param().abi(), + &mut mode, + ) + .ok() + } + + pub unsafe fn GetPropertyValue( + &self, + device_id: impl Param, + bFxStore: impl Into, + key: *const PROPERTYKEY, + ) -> Result { + let mut result__ = zeroed(); + (Interface::vtable(self).GetPropertyValue)( + Interface::as_raw(self), + device_id.param().abi(), + bFxStore.into().0, + key, + &mut result__, + ) + .and_then(|| windows_core::Type::from_abi(result__)) + } + + pub unsafe fn SetPropertyValue( + &self, + device_id: impl Param, + bFxStore: impl Into, + key: *const PROPERTYKEY, + propvar: *const PROPVARIANT, + ) -> Result<()> { + (Interface::vtable(self).SetPropertyValue)( + Interface::as_raw(self), + device_id.param().abi(), + bFxStore.into().0, + key, + std::mem::transmute::< + *const windows_core::PROPVARIANT, + *const std::mem::MaybeUninit, + >(propvar), + ) + .ok() + } + + pub unsafe fn SetDefaultEndpoint( + &self, + device_id: impl Param, + role: ERole, + ) -> Result<()> { + (Interface::vtable(self).SetDefaultEndpoint)( + Interface::as_raw(self), + device_id.param().abi(), + role, + ) + .ok() + } + + pub unsafe fn SetEndpointVisibility( + &self, + device_id: impl Param, + visible: impl Into, + ) -> Result<()> { + (Interface::vtable(self).SetEndpointVisibility)( + Interface::as_raw(self), + device_id.param().abi(), + visible.into().0, + ) + .ok() + } +} + +#[repr(C)] +#[doc(hidden)] +#[allow(non_snake_case, non_camel_case_types)] +pub struct IPolicyConfig_Vtbl { + pub base__: ::windows::core::IUnknown_Vtbl, + pub GetMixFormat: + unsafe extern "system" fn(this: *mut c_void, PCWSTR, *mut *mut WAVEFORMATEX) -> HRESULT, + pub GetDeviceFormat: unsafe extern "system" fn( + this: *mut c_void, + PCWSTR, + i32, + *mut *mut WAVEFORMATEX, + ) -> HRESULT, + pub ResetDeviceFormat: unsafe extern "system" fn(this: *mut c_void, PCWSTR) -> HRESULT, + pub SetDeviceFormat: unsafe extern "system" fn( + this: *mut c_void, + PCWSTR, + *mut WAVEFORMATEX, + *mut WAVEFORMATEX, + ) -> HRESULT, + pub GetProcessingPeriod: + unsafe extern "system" fn(this: *mut c_void, PCWSTR, i32, *mut i64, *mut i64) -> HRESULT, + pub SetProcessingPeriod: + unsafe extern "system" fn(this: *mut c_void, PCWSTR, *mut i64) -> HRESULT, + pub GetShareMode: + unsafe extern "system" fn(this: *mut c_void, PCWSTR, *mut DeviceSharingMode) -> HRESULT, + pub SetShareMode: + unsafe extern "system" fn(this: *mut c_void, PCWSTR, *mut DeviceSharingMode) -> HRESULT, + pub GetPropertyValue: unsafe extern "system" fn( + this: *mut c_void, + PCWSTR, + i32, + *const PROPERTYKEY, + *mut std::mem::MaybeUninit, + ) -> HRESULT, + pub SetPropertyValue: unsafe extern "system" fn( + this: *mut c_void, + PCWSTR, + i32, + *const PROPERTYKEY, + *const std::mem::MaybeUninit, + ) -> HRESULT, + pub SetDefaultEndpoint: unsafe extern "system" fn(this: *mut c_void, PCWSTR, ERole) -> HRESULT, + pub SetEndpointVisibility: unsafe extern "system" fn(this: *mut c_void, PCWSTR, i32) -> HRESULT, +} diff --git a/src/background/modules/media/infrastructure.rs b/src/background/modules/media/infrastructure.rs index 9a7c688a..f7d347c7 100644 --- a/src/background/modules/media/infrastructure.rs +++ b/src/background/modules/media/infrastructure.rs @@ -1,108 +1,108 @@ -use std::sync::atomic::{AtomicBool, Ordering}; -use tauri::Emitter; -use windows::core::GUID; - -use crate::{ - error_handler::Result, modules::media::application::MEDIA_MANAGER, seelen::get_app_handle, - trace_lock, -}; - -use super::domain::{Device, MediaPlayer}; - -fn emit_media_sessions(playing: &Vec) { - let app = get_app_handle(); - app.emit("media-sessions", playing).expect("failed to emit"); -} - -fn emit_media_devices(inputs: &Vec, outputs: &Vec) { - let app = get_app_handle(); - app.emit("media-inputs", inputs).expect("failed to emit"); - app.emit("media-outputs", outputs).expect("failed to emit"); -} - -static REGISTERED: AtomicBool = AtomicBool::new(false); -pub fn register_media_events() { - let was_registered = REGISTERED.load(Ordering::Acquire); - if !was_registered { - REGISTERED.store(true, Ordering::Release); - } - std::thread::spawn(move || { - let mut manager = trace_lock!(MEDIA_MANAGER); - if !was_registered { - log::trace!("Registering media events"); - manager.on_change_devices(emit_media_devices); - manager.on_change_players(emit_media_sessions); - } - emit_media_devices(manager.inputs(), manager.outputs()); - emit_media_sessions(manager.playing()); - }); -} - -pub fn release_media_events() { - if REGISTERED.load(Ordering::Acquire) { - trace_lock!(MEDIA_MANAGER).release(); - } -} - -#[tauri::command] -pub fn media_set_default_device(id: String, role: String) -> Result<()> { - trace_lock!(MEDIA_MANAGER).set_default_device(&id, &role)?; - Ok(()) -} - -#[tauri::command] -pub fn media_next(id: String) -> Result<()> { - if let Some(session) = trace_lock!(MEDIA_MANAGER).session_by_id(&id) { - let success = tauri::async_runtime::block_on(session.TrySkipNextAsync()?)?; - if !success { - return Err("failed to skip next".into()); - } - } - Ok(()) -} - -#[tauri::command] -pub fn media_prev(id: String) -> Result<()> { - if let Some(session) = trace_lock!(MEDIA_MANAGER).session_by_id(&id) { - let success = tauri::async_runtime::block_on(session.TrySkipPreviousAsync()?)?; - if !success { - return Err("failed to skip previous".into()); - } - } - Ok(()) -} - -#[tauri::command] -pub fn media_toggle_play_pause(id: String) -> Result<()> { - if let Some(session) = trace_lock!(MEDIA_MANAGER).session_by_id(&id) { - let success = tauri::async_runtime::block_on(session.TryTogglePlayPauseAsync()?)?; - if !success { - return Err("failed to toggle play".into()); - } - } - Ok(()) -} - -#[tauri::command] -pub fn media_toggle_mute(id: String, _session_id: Option) -> Result<()> { - let manager = trace_lock!(MEDIA_MANAGER); - let endpoints = manager.devices_audio_endpoint(); - if let Some((endpoint, _)) = endpoints.get(&id) { - unsafe { - endpoint.SetMute(!endpoint.GetMute()?.as_bool(), &GUID::zeroed())?; - } - } - Ok(()) -} - -#[tauri::command] -pub fn set_volume_level(id: String, _session_id: Option, level: f32) -> Result<()> { - let manager = trace_lock!(MEDIA_MANAGER); - let endpoints = manager.devices_audio_endpoint(); - if let Some((endpoint, _)) = endpoints.get(&id) { - unsafe { - endpoint.SetMasterVolumeLevelScalar(level, &GUID::zeroed())?; - } - } - Ok(()) -} +use std::sync::atomic::{AtomicBool, Ordering}; +use tauri::Emitter; +use windows::core::GUID; + +use crate::{ + error_handler::Result, modules::media::application::MEDIA_MANAGER, seelen::get_app_handle, + trace_lock, +}; + +use super::domain::{Device, MediaPlayer}; + +fn emit_media_sessions(playing: &Vec) { + let app = get_app_handle(); + app.emit("media-sessions", playing).expect("failed to emit"); +} + +fn emit_media_devices(inputs: &Vec, outputs: &Vec) { + let app = get_app_handle(); + app.emit("media-inputs", inputs).expect("failed to emit"); + app.emit("media-outputs", outputs).expect("failed to emit"); +} + +static REGISTERED: AtomicBool = AtomicBool::new(false); +pub fn register_media_events() { + let was_registered = REGISTERED.load(Ordering::Acquire); + if !was_registered { + REGISTERED.store(true, Ordering::Release); + } + std::thread::spawn(move || { + let mut manager = trace_lock!(MEDIA_MANAGER); + if !was_registered { + log::trace!("Registering media events"); + manager.on_change_devices(emit_media_devices); + manager.on_change_players(emit_media_sessions); + } + emit_media_devices(manager.inputs(), manager.outputs()); + emit_media_sessions(manager.playing()); + }); +} + +pub fn release_media_events() { + if REGISTERED.load(Ordering::Acquire) { + trace_lock!(MEDIA_MANAGER).release(); + } +} + +#[tauri::command] +pub fn media_set_default_device(id: String, role: String) -> Result<()> { + trace_lock!(MEDIA_MANAGER).set_default_device(&id, &role)?; + Ok(()) +} + +#[tauri::command] +pub fn media_next(id: String) -> Result<()> { + if let Some(session) = trace_lock!(MEDIA_MANAGER).session_by_id(&id) { + let success = tauri::async_runtime::block_on(session.TrySkipNextAsync()?)?; + if !success { + return Err("failed to skip next".into()); + } + } + Ok(()) +} + +#[tauri::command] +pub fn media_prev(id: String) -> Result<()> { + if let Some(session) = trace_lock!(MEDIA_MANAGER).session_by_id(&id) { + let success = tauri::async_runtime::block_on(session.TrySkipPreviousAsync()?)?; + if !success { + return Err("failed to skip previous".into()); + } + } + Ok(()) +} + +#[tauri::command] +pub fn media_toggle_play_pause(id: String) -> Result<()> { + if let Some(session) = trace_lock!(MEDIA_MANAGER).session_by_id(&id) { + let success = tauri::async_runtime::block_on(session.TryTogglePlayPauseAsync()?)?; + if !success { + return Err("failed to toggle play".into()); + } + } + Ok(()) +} + +#[tauri::command] +pub fn media_toggle_mute(id: String, _session_id: Option) -> Result<()> { + let manager = trace_lock!(MEDIA_MANAGER); + let endpoints = manager.devices_audio_endpoint(); + if let Some((endpoint, _)) = endpoints.get(&id) { + unsafe { + endpoint.SetMute(!endpoint.GetMute()?.as_bool(), &GUID::zeroed())?; + } + } + Ok(()) +} + +#[tauri::command] +pub fn set_volume_level(id: String, _session_id: Option, level: f32) -> Result<()> { + let manager = trace_lock!(MEDIA_MANAGER); + let endpoints = manager.devices_audio_endpoint(); + if let Some((endpoint, _)) = endpoints.get(&id) { + unsafe { + endpoint.SetMasterVolumeLevelScalar(level, &GUID::zeroed())?; + } + } + Ok(()) +} diff --git a/src/background/modules/media/mod.rs b/src/background/modules/media/mod.rs index 426629b8..522b894c 100644 --- a/src/background/modules/media/mod.rs +++ b/src/background/modules/media/mod.rs @@ -1,3 +1,3 @@ -mod application; -mod domain; -pub mod infrastructure; +mod application; +mod domain; +pub mod infrastructure; diff --git a/src/background/modules/mod.rs b/src/background/modules/mod.rs index 99950fb7..9c25798a 100644 --- a/src/background/modules/mod.rs +++ b/src/background/modules/mod.rs @@ -1,10 +1,10 @@ -pub mod cli; -pub mod input; -pub mod media; -pub mod monitors; -pub mod network; -pub mod notifications; -pub mod power; -pub mod system_settings; -pub mod tray; -pub mod uwp; +pub mod cli; +pub mod input; +pub mod media; +pub mod monitors; +pub mod network; +pub mod notifications; +pub mod power; +pub mod system_settings; +pub mod tray; +pub mod uwp; diff --git a/src/background/modules/monitors/mod.rs b/src/background/modules/monitors/mod.rs index d276da13..1773a9ea 100644 --- a/src/background/modules/monitors/mod.rs +++ b/src/background/modules/monitors/mod.rs @@ -1,192 +1,192 @@ -use lazy_static::lazy_static; -use parking_lot::Mutex; -use std::sync::Arc; -use windows::{ - core::PCWSTR, - Win32::{ - Devices::Display::GUID_DEVINTERFACE_MONITOR, - Foundation::{HWND, LPARAM, LRESULT, WPARAM}, - Graphics::Gdi::HMONITOR, - UI::WindowsAndMessaging::{ - CreateWindowExW, DefWindowProcW, DispatchMessageW, GetMessageW, RegisterClassW, - RegisterDeviceNotificationW, TranslateMessage, DBT_DEVTYP_DEVICEINTERFACE, - DEVICE_NOTIFY_WINDOW_HANDLE, DEV_BROADCAST_DEVICEINTERFACE_W, MSG, WINDOW_EX_STYLE, - WINDOW_STYLE, WM_DEVICECHANGE, WM_DISPLAYCHANGE, WM_SETTINGCHANGE, WNDCLASSW, - }, - }, -}; - -use crate::{ - error_handler::Result, - log_error, trace_lock, - windows_api::{MonitorEnumerator, WindowsApi}, -}; - -lazy_static! { - pub static ref MONITOR_MANAGER: Arc> = Arc::new(Mutex::new( - MonitorManager::new().expect("Failed to create monitor manager") - )); -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum MonitorManagerEvent { - Added(String, HMONITOR), - Removed(String, HMONITOR), - Updated(String, HMONITOR), -} - -type OnMonitorsChange = Box; - -pub struct MonitorManager { - hwnd: isize, - pub monitors: Vec<(String, HMONITOR)>, - callbacks: Vec, -} - -impl MonitorManager { - pub fn hwnd(self) -> HWND { - HWND(self.hwnd) - } - - pub extern "system" fn window_proc( - window: HWND, - message: u32, - wparam: WPARAM, - lparam: LPARAM, - ) -> LRESULT { - unsafe { - match message { - // Added based on this https://stackoverflow.com/a/33762334 - WM_DISPLAYCHANGE | WM_SETTINGCHANGE | WM_DEVICECHANGE => { - // log::debug!("Dispatching {}, {:?}, {:?}", message, wparam, lparam); - let mut manager = trace_lock!(MONITOR_MANAGER); - - let mut old_list = manager.monitors.clone(); - let new_list = match Self::get_monitors() { - Ok(monitors) => monitors, - Err(_) => return LRESULT(0), - }; - - for (name, id) in &new_list { - match old_list.iter().position(|x| x.0 == *name) { - Some(idx) => { - let (_, old_id) = old_list.remove(idx); - if old_id != *id { - manager.notify_changes(MonitorManagerEvent::Updated( - name.clone(), - *id, - )); - } - } - None => { - manager - .notify_changes(MonitorManagerEvent::Added(name.clone(), *id)); - } - } - } - - for (name, id) in old_list { - manager.notify_changes(MonitorManagerEvent::Removed(name, id)); - } - - manager.monitors = new_list.into_iter().collect(); - LRESULT(0) - } - _ => DefWindowProcW(window, message, wparam, lparam), - } - } - } - - pub fn new() -> Result { - let wide_name: Vec = "Seelen Monitor Manager" - .encode_utf16() - .chain(Some(0)) - .collect(); - let wide_class: Vec = "SeelenMonitorManager" - .encode_utf16() - .chain(Some(0)) - .collect(); - - let h_module = WindowsApi::module_handle_w()?; - - let wnd_class = WNDCLASSW { - lpfnWndProc: Some(Self::window_proc), - hInstance: h_module.into(), - lpszClassName: PCWSTR(wide_class.as_ptr()), - ..Default::default() - }; - - unsafe { - RegisterClassW(&wnd_class); - } - - let (hwnd_sender, hwnd_receiver) = crossbeam_channel::bounded::(1); - - std::thread::spawn(move || unsafe { - let hwnd = CreateWindowExW( - WINDOW_EX_STYLE::default(), - PCWSTR(wide_class.as_ptr()), - PCWSTR(wide_name.as_ptr()), - WINDOW_STYLE::default(), - 0, - 0, - 0, - 0, - None, - None, - h_module, - None, - ); - - log_error!(hwnd_sender.send(hwnd)); - - let mut notification_filter = DEV_BROADCAST_DEVICEINTERFACE_W { - dbcc_size: std::mem::size_of::() as u32, - dbcc_devicetype: DBT_DEVTYP_DEVICEINTERFACE.0, - dbcc_reserved: 0, - dbcc_classguid: GUID_DEVINTERFACE_MONITOR, - dbcc_name: [0; 1], - }; - - log_error!(RegisterDeviceNotificationW( - hwnd, - &mut notification_filter as *mut _ as *mut _, - DEVICE_NOTIFY_WINDOW_HANDLE, - )); - - let mut msg = MSG::default(); - while GetMessageW(&mut msg, hwnd, 0, 0).into() { - let _ = TranslateMessage(&msg); - DispatchMessageW(&msg); - std::thread::sleep(std::time::Duration::from_millis(10)); - } - }); - - Ok(Self { - hwnd: hwnd_receiver.recv()?.0, - callbacks: Vec::new(), - monitors: Self::get_monitors()?, - }) - } - - fn get_monitors() -> Result> { - let mut monitors = Vec::new(); - for m in MonitorEnumerator::new_refreshed()? { - monitors.push((WindowsApi::monitor_name(m)?, m)); - } - Ok(monitors) - } - - pub fn listen_changes(&mut self, callback: F) - where - F: Fn(MonitorManagerEvent) + Send + Sync + 'static, - { - self.callbacks.push(Box::new(callback)); - } - - pub fn notify_changes(&self, event: MonitorManagerEvent) { - for callback in &self.callbacks { - callback(event.clone()); - } - } -} +use lazy_static::lazy_static; +use parking_lot::Mutex; +use std::sync::Arc; +use windows::{ + core::PCWSTR, + Win32::{ + Devices::Display::GUID_DEVINTERFACE_MONITOR, + Foundation::{HWND, LPARAM, LRESULT, WPARAM}, + Graphics::Gdi::HMONITOR, + UI::WindowsAndMessaging::{ + CreateWindowExW, DefWindowProcW, DispatchMessageW, GetMessageW, RegisterClassW, + RegisterDeviceNotificationW, TranslateMessage, DBT_DEVTYP_DEVICEINTERFACE, + DEVICE_NOTIFY_WINDOW_HANDLE, DEV_BROADCAST_DEVICEINTERFACE_W, MSG, WINDOW_EX_STYLE, + WINDOW_STYLE, WM_DEVICECHANGE, WM_DISPLAYCHANGE, WM_SETTINGCHANGE, WNDCLASSW, + }, + }, +}; + +use crate::{ + error_handler::Result, + log_error, trace_lock, + windows_api::{MonitorEnumerator, WindowsApi}, +}; + +lazy_static! { + pub static ref MONITOR_MANAGER: Arc> = Arc::new(Mutex::new( + MonitorManager::new().expect("Failed to create monitor manager") + )); +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum MonitorManagerEvent { + Added(String, HMONITOR), + Removed(String, HMONITOR), + Updated(String, HMONITOR), +} + +type OnMonitorsChange = Box; + +pub struct MonitorManager { + hwnd: isize, + pub monitors: Vec<(String, HMONITOR)>, + callbacks: Vec, +} + +impl MonitorManager { + pub fn hwnd(self) -> HWND { + HWND(self.hwnd) + } + + pub extern "system" fn window_proc( + window: HWND, + message: u32, + wparam: WPARAM, + lparam: LPARAM, + ) -> LRESULT { + unsafe { + match message { + // Added based on this https://stackoverflow.com/a/33762334 + WM_DISPLAYCHANGE | WM_SETTINGCHANGE | WM_DEVICECHANGE => { + // log::debug!("Dispatching {}, {:?}, {:?}", message, wparam, lparam); + let mut manager = trace_lock!(MONITOR_MANAGER); + + let mut old_list = manager.monitors.clone(); + let new_list = match Self::get_monitors() { + Ok(monitors) => monitors, + Err(_) => return LRESULT(0), + }; + + for (name, id) in &new_list { + match old_list.iter().position(|x| x.0 == *name) { + Some(idx) => { + let (_, old_id) = old_list.remove(idx); + if old_id != *id { + manager.notify_changes(MonitorManagerEvent::Updated( + name.clone(), + *id, + )); + } + } + None => { + manager + .notify_changes(MonitorManagerEvent::Added(name.clone(), *id)); + } + } + } + + for (name, id) in old_list { + manager.notify_changes(MonitorManagerEvent::Removed(name, id)); + } + + manager.monitors = new_list.into_iter().collect(); + LRESULT(0) + } + _ => DefWindowProcW(window, message, wparam, lparam), + } + } + } + + pub fn new() -> Result { + let wide_name: Vec = "Seelen Monitor Manager" + .encode_utf16() + .chain(Some(0)) + .collect(); + let wide_class: Vec = "SeelenMonitorManager" + .encode_utf16() + .chain(Some(0)) + .collect(); + + let h_module = WindowsApi::module_handle_w()?; + + let wnd_class = WNDCLASSW { + lpfnWndProc: Some(Self::window_proc), + hInstance: h_module.into(), + lpszClassName: PCWSTR(wide_class.as_ptr()), + ..Default::default() + }; + + unsafe { + RegisterClassW(&wnd_class); + } + + let (hwnd_sender, hwnd_receiver) = crossbeam_channel::bounded::(1); + + std::thread::spawn(move || unsafe { + let hwnd = CreateWindowExW( + WINDOW_EX_STYLE::default(), + PCWSTR(wide_class.as_ptr()), + PCWSTR(wide_name.as_ptr()), + WINDOW_STYLE::default(), + 0, + 0, + 0, + 0, + None, + None, + h_module, + None, + ); + + log_error!(hwnd_sender.send(hwnd)); + + let mut notification_filter = DEV_BROADCAST_DEVICEINTERFACE_W { + dbcc_size: std::mem::size_of::() as u32, + dbcc_devicetype: DBT_DEVTYP_DEVICEINTERFACE.0, + dbcc_reserved: 0, + dbcc_classguid: GUID_DEVINTERFACE_MONITOR, + dbcc_name: [0; 1], + }; + + log_error!(RegisterDeviceNotificationW( + hwnd, + &mut notification_filter as *mut _ as *mut _, + DEVICE_NOTIFY_WINDOW_HANDLE, + )); + + let mut msg = MSG::default(); + while GetMessageW(&mut msg, hwnd, 0, 0).into() { + let _ = TranslateMessage(&msg); + DispatchMessageW(&msg); + std::thread::sleep(std::time::Duration::from_millis(10)); + } + }); + + Ok(Self { + hwnd: hwnd_receiver.recv()?.0, + callbacks: Vec::new(), + monitors: Self::get_monitors()?, + }) + } + + fn get_monitors() -> Result> { + let mut monitors = Vec::new(); + for m in MonitorEnumerator::new_refreshed()? { + monitors.push((WindowsApi::monitor_name(m)?, m)); + } + Ok(monitors) + } + + pub fn listen_changes(&mut self, callback: F) + where + F: Fn(MonitorManagerEvent) + Send + Sync + 'static, + { + self.callbacks.push(Box::new(callback)); + } + + pub fn notify_changes(&self, event: MonitorManagerEvent) { + for callback in &self.callbacks { + callback(event.clone()); + } + } +} diff --git a/src/background/modules/network/application/mod.rs b/src/background/modules/network/application/mod.rs index 3a3734df..46e51368 100644 --- a/src/background/modules/network/application/mod.rs +++ b/src/background/modules/network/application/mod.rs @@ -1,163 +1,163 @@ -pub mod scanner; - -use std::{env::temp_dir, net::UdpSocket}; - -use tauri_plugin_shell::ShellExt; -use windows::Win32::{ - NetworkManagement::IpHelper::{ - GetAdaptersAddresses, GAA_FLAG_INCLUDE_GATEWAYS, GAA_FLAG_INCLUDE_PREFIX, - IP_ADAPTER_ADDRESSES_LH, - }, - Networking::{ - NetworkListManager::{INetworkListManager, NetworkListManager, NLM_CONNECTIVITY}, - WinSock::AF_UNSPEC, - }, -}; - -use crate::{ - error_handler::Result, seelen::get_app_handle, utils::pwsh::PwshScript, windows_api::Com, -}; - -use super::domain::{NetworkAdapter, WlanProfile}; - -impl NetworkAdapter { - pub unsafe fn iter_from_raw( - raw: *const IP_ADAPTER_ADDRESSES_LH, - ) -> Result> { - let mut adapters = Vec::new(); - - let mut raw_adapter = raw; - while !raw_adapter.is_null() { - let adapter = &*raw_adapter; - adapters.push(adapter.try_into()?); - raw_adapter = adapter.Next; - } - - Ok(adapters) - } -} - -pub struct NetworkManager {} - -impl NetworkManager { - pub fn get_adapters() -> Result> { - let adapters = unsafe { - let family = AF_UNSPEC.0 as u32; - let flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS; - let mut buffer_length = 0_u32; - - // first call to get the buffer size - GetAdaptersAddresses(family, flags, None, None, &mut buffer_length); - - let mut adapters_addresses: Vec = vec![0; buffer_length as usize]; - GetAdaptersAddresses( - family, - flags, - None, - Some(adapters_addresses.as_mut_ptr() as *mut IP_ADAPTER_ADDRESSES_LH), - &mut buffer_length, - ); - - let raw_adapter = adapters_addresses.as_ptr() as *const IP_ADAPTER_ADDRESSES_LH; - NetworkAdapter::iter_from_raw(raw_adapter)? - }; - - Ok(adapters) - } - - /// emit connectivity changes, always will emit the current state on registration - pub fn register_events(cb: F) - where - F: Fn(NLM_CONNECTIVITY) + Send + 'static, - { - std::thread::spawn(move || { - let result: Result<()> = Com::run_with_context(|| { - let list_manager: INetworkListManager = Com::create_instance(&NetworkListManager)?; - let mut last_state = None; - - loop { - let current_state = unsafe { list_manager.GetConnectivity() }.ok(); - if let (Some(current_state), Some(last_state)) = (current_state, last_state) { - if current_state != last_state { - cb(current_state); - } - } - last_state = current_state; - std::thread::sleep(std::time::Duration::from_millis(5000)); - } - }); - - log::warn!("Network loop finished: {:?}", result); - }); - } - - pub async fn get_wifi_profiles() -> Result> { - let path = PwshScript::new(include_str!("profiles.ps1")) - .execute() - .await?; - let contents = std::fs::read_to_string(path)?; - let profiles: Vec = serde_json::from_str(&contents)?; - Ok(profiles) - } - - pub async fn add_profile(ssid: &str, password: &str, hidden: bool) -> Result<()> { - log::trace!("Adding profile {}", ssid); - - // Be sure that xml is using tabs instead of spaces for indentation - let profile_xml = include_str!("profile.template.xml") - .replace("{ssid}", ssid) - .replace("{password}", password) - .replace("{hidden}", if hidden { "true" } else { "false" }); - - let profile_path = temp_dir().join(format!("slu-{}-profile.xml", ssid)); - - std::fs::write(&profile_path, profile_xml)?; - - let handle = get_app_handle(); - let output = handle - .shell() - .command("netsh") - .args([ - "wlan", - "add", - "profile", - &format!("filename={}", &profile_path.to_string_lossy()), - ]) - .output() - .await?; - - let result = if output.status.success() { - Ok(()) - } else { - Err(output.into()) - }; - - std::fs::remove_file(&profile_path)?; - result - } - - pub async fn remove_profile(ssid: &str) -> Result<()> { - log::trace!("Removing profile {}", ssid); - - let handle = get_app_handle(); - let output = handle - .shell() - .command("netsh") - .args(["wlan", "delete", "profile", &format!("name={}", ssid)]) - .output() - .await?; - - if output.status.success() { - Ok(()) - } else { - Err(output.into()) - } - } -} - -pub fn get_local_ip_address() -> Result { - let socket = UdpSocket::bind("0.0.0.0:0")?; - socket.connect("8.8.8.8:80")?; - let local_addr = socket.local_addr()?; - Ok(local_addr.ip().to_string()) -} +pub mod scanner; + +use std::{env::temp_dir, net::UdpSocket}; + +use tauri_plugin_shell::ShellExt; +use windows::Win32::{ + NetworkManagement::IpHelper::{ + GetAdaptersAddresses, GAA_FLAG_INCLUDE_GATEWAYS, GAA_FLAG_INCLUDE_PREFIX, + IP_ADAPTER_ADDRESSES_LH, + }, + Networking::{ + NetworkListManager::{INetworkListManager, NetworkListManager, NLM_CONNECTIVITY}, + WinSock::AF_UNSPEC, + }, +}; + +use crate::{ + error_handler::Result, seelen::get_app_handle, utils::pwsh::PwshScript, windows_api::Com, +}; + +use super::domain::{NetworkAdapter, WlanProfile}; + +impl NetworkAdapter { + pub unsafe fn iter_from_raw( + raw: *const IP_ADAPTER_ADDRESSES_LH, + ) -> Result> { + let mut adapters = Vec::new(); + + let mut raw_adapter = raw; + while !raw_adapter.is_null() { + let adapter = &*raw_adapter; + adapters.push(adapter.try_into()?); + raw_adapter = adapter.Next; + } + + Ok(adapters) + } +} + +pub struct NetworkManager {} + +impl NetworkManager { + pub fn get_adapters() -> Result> { + let adapters = unsafe { + let family = AF_UNSPEC.0 as u32; + let flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS; + let mut buffer_length = 0_u32; + + // first call to get the buffer size + GetAdaptersAddresses(family, flags, None, None, &mut buffer_length); + + let mut adapters_addresses: Vec = vec![0; buffer_length as usize]; + GetAdaptersAddresses( + family, + flags, + None, + Some(adapters_addresses.as_mut_ptr() as *mut IP_ADAPTER_ADDRESSES_LH), + &mut buffer_length, + ); + + let raw_adapter = adapters_addresses.as_ptr() as *const IP_ADAPTER_ADDRESSES_LH; + NetworkAdapter::iter_from_raw(raw_adapter)? + }; + + Ok(adapters) + } + + /// emit connectivity changes, always will emit the current state on registration + pub fn register_events(cb: F) + where + F: Fn(NLM_CONNECTIVITY) + Send + 'static, + { + std::thread::spawn(move || { + let result: Result<()> = Com::run_with_context(|| { + let list_manager: INetworkListManager = Com::create_instance(&NetworkListManager)?; + let mut last_state = None; + + loop { + let current_state = unsafe { list_manager.GetConnectivity() }.ok(); + if let (Some(current_state), Some(last_state)) = (current_state, last_state) { + if current_state != last_state { + cb(current_state); + } + } + last_state = current_state; + std::thread::sleep(std::time::Duration::from_millis(5000)); + } + }); + + log::warn!("Network loop finished: {:?}", result); + }); + } + + pub async fn get_wifi_profiles() -> Result> { + let path = PwshScript::new(include_str!("profiles.ps1")) + .execute() + .await?; + let contents = std::fs::read_to_string(path)?; + let profiles: Vec = serde_json::from_str(&contents)?; + Ok(profiles) + } + + pub async fn add_profile(ssid: &str, password: &str, hidden: bool) -> Result<()> { + log::trace!("Adding profile {}", ssid); + + // Be sure that xml is using tabs instead of spaces for indentation + let profile_xml = include_str!("profile.template.xml") + .replace("{ssid}", ssid) + .replace("{password}", password) + .replace("{hidden}", if hidden { "true" } else { "false" }); + + let profile_path = temp_dir().join(format!("slu-{}-profile.xml", ssid)); + + std::fs::write(&profile_path, profile_xml)?; + + let handle = get_app_handle(); + let output = handle + .shell() + .command("netsh") + .args([ + "wlan", + "add", + "profile", + &format!("filename={}", &profile_path.to_string_lossy()), + ]) + .output() + .await?; + + let result = if output.status.success() { + Ok(()) + } else { + Err(output.into()) + }; + + std::fs::remove_file(&profile_path)?; + result + } + + pub async fn remove_profile(ssid: &str) -> Result<()> { + log::trace!("Removing profile {}", ssid); + + let handle = get_app_handle(); + let output = handle + .shell() + .command("netsh") + .args(["wlan", "delete", "profile", &format!("name={}", ssid)]) + .output() + .await?; + + if output.status.success() { + Ok(()) + } else { + Err(output.into()) + } + } +} + +pub fn get_local_ip_address() -> Result { + let socket = UdpSocket::bind("0.0.0.0:0")?; + socket.connect("8.8.8.8:80")?; + let local_addr = socket.local_addr()?; + Ok(local_addr.ip().to_string()) +} diff --git a/src/background/modules/network/application/profile.template.xml b/src/background/modules/network/application/profile.template.xml index 6170e4bb..130908fe 100644 --- a/src/background/modules/network/application/profile.template.xml +++ b/src/background/modules/network/application/profile.template.xml @@ -1,26 +1,26 @@ - - - {ssid} - - - {ssid} - - {hidden} - - ESS - auto - - - - WPA2PSK - AES - false - - - passPhrase - false - {password} - - - + + + {ssid} + + + {ssid} + + {hidden} + + ESS + auto + + + + WPA2PSK + AES + false + + + passPhrase + false + {password} + + + \ No newline at end of file diff --git a/src/background/modules/network/application/profiles.ps1 b/src/background/modules/network/application/profiles.ps1 index a66bbbca..f7a80d63 100644 --- a/src/background/modules/network/application/profiles.ps1 +++ b/src/background/modules/network/application/profiles.ps1 @@ -1,21 +1,21 @@ -$tempFolder = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.Guid]::NewGuid().ToString()) -New-Item -ItemType Directory -Path $tempFolder > $null - -netsh wlan export profile folder=$tempFolder key=clear > $null - -$jsonOutputFile = [System.IO.Path]::Combine($tempFolder, "wifi_profiles.json") - -$wifiProfiles = Get-ChildItem -Path $tempFolder -Filter *.xml | ForEach-Object { - [xml]$xmlContent = Get-Content -Path $_.FullName - [PSCustomObject]@{ - ProfileName = $xmlContent.WLANProfile.name - SSID = $xmlContent.WLANProfile.SSIDConfig.SSID.name - Authentication = $xmlContent.WLANProfile.MSM.Security.authEncryption.authentication - Encryption = $xmlContent.WLANProfile.MSM.Security.authEncryption.encryption - Password = $xmlContent.WLANProfile.MSM.Security.sharedKey.keyMaterial - } -} - -$wifiProfiles | ConvertTo-Json | Set-Content -Path $jsonOutputFile - +$tempFolder = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.Guid]::NewGuid().ToString()) +New-Item -ItemType Directory -Path $tempFolder > $null + +netsh wlan export profile folder=$tempFolder key=clear > $null + +$jsonOutputFile = [System.IO.Path]::Combine($tempFolder, "wifi_profiles.json") + +$wifiProfiles = Get-ChildItem -Path $tempFolder -Filter *.xml | ForEach-Object { + [xml]$xmlContent = Get-Content -Path $_.FullName + [PSCustomObject]@{ + ProfileName = $xmlContent.WLANProfile.name + SSID = $xmlContent.WLANProfile.SSIDConfig.SSID.name + Authentication = $xmlContent.WLANProfile.MSM.Security.authEncryption.authentication + Encryption = $xmlContent.WLANProfile.MSM.Security.authEncryption.encryption + Password = $xmlContent.WLANProfile.MSM.Security.sharedKey.keyMaterial + } +} + +$wifiProfiles | ConvertTo-Json | Set-Content -Path $jsonOutputFile + Write-Host $jsonOutputFile -NoNewline \ No newline at end of file diff --git a/src/background/modules/network/application/scanner.rs b/src/background/modules/network/application/scanner.rs index e120ce0d..64845e87 100644 --- a/src/background/modules/network/application/scanner.rs +++ b/src/background/modules/network/application/scanner.rs @@ -1,257 +1,257 @@ -use std::{ - sync::atomic::{AtomicBool, Ordering}, - time::Duration, -}; - -use itertools::Itertools; -use windows::{ - core::GUID, - Win32::{ - Foundation::HANDLE, - NetworkManagement::WiFi::{ - dot11_BSS_type_any, wlan_interface_state_connected, - wlan_intf_opcode_current_connection, WlanCloseHandle, WlanEnumInterfaces, - WlanGetNetworkBssList, WlanOpenHandle, WlanQueryInterface, WlanScan, - WLAN_API_VERSION_2_0, WLAN_BSS_ENTRY, WLAN_BSS_LIST, WLAN_CONNECTION_ATTRIBUTES, - WLAN_INTERFACE_INFO_LIST, - }, - }, -}; - -use crate::{error_handler::Result, modules::network::domain::WlanBssEntry}; - -use super::NetworkManager; - -impl From<&WLAN_BSS_ENTRY> for WlanBssEntry { - fn from(entry: &WLAN_BSS_ENTRY) -> Self { - let ssid = String::from_utf8_lossy(&entry.dot11Ssid.ucSSID) - .replace("\0", "") - .to_string(); - - let ssid = if ssid.is_empty() { None } else { Some(ssid) }; - - let bssid = entry - .dot11Bssid - .iter() - .map(|b| format!("{:02x}", b)) - .join(":"); - - Self { - ssid, - bssid, - channel_frequency: entry.ulChCenterFrequency, - signal: entry.uLinkQuality, - connected: false, - connected_channel: false, - } - } -} - -static SCANNING: AtomicBool = AtomicBool::new(false); - -impl NetworkManager { - fn open_wlan() -> Result { - let mut client_handle = HANDLE::default(); - let mut negotiated_version = 0; - - let result = unsafe { - WlanOpenHandle( - WLAN_API_VERSION_2_0, - None, - &mut negotiated_version, - &mut client_handle, - ) - }; - - if result != 0 { - return Err(format!("Failed to open Wlan, error code: {}", result).into()); - } - - Ok(client_handle) - } - - fn get_connected_wlan<'a>( - handle: HANDLE, - guid: &GUID, - ) -> Option<&'a WLAN_CONNECTION_ATTRIBUTES> { - let mut connection_ptr = std::ptr::null_mut::(); - let mut data_size = 0; - unsafe { - WlanQueryInterface( - handle, - guid, - wlan_intf_opcode_current_connection, - None, - &mut data_size, - &mut connection_ptr as *mut _ as _, - None, - ); - - if connection_ptr.is_null() { - None - } else { - Some(&*connection_ptr) - } - } - } - - pub fn is_connected_to(ssid: &str) -> Result { - let client_handle = Self::open_wlan()?; - unsafe { - let mut interface_list_ptr: *mut WLAN_INTERFACE_INFO_LIST = std::ptr::null_mut(); - let result = WlanEnumInterfaces(client_handle, None, &mut interface_list_ptr); - - if result != 0 || interface_list_ptr.is_null() { - return Err(format!("Failed to get interface list, error code: {}", result).into()); - } - - let interface_list = &*interface_list_ptr; - let interfaces = std::slice::from_raw_parts( - interface_list.InterfaceInfo.as_ptr(), - interface_list.dwNumberOfItems as usize, - ); - - for interface in interfaces { - let connection = Self::get_connected_wlan(client_handle, &interface.InterfaceGuid); - - if let Some(connection) = connection { - let connected_ssid = String::from_utf8_lossy( - &connection.wlanAssociationAttributes.dot11Ssid.ucSSID, - ) - .replace("\0", "") - .to_string(); - - if connected_ssid == ssid { - return Ok(connection.isState.0 & wlan_interface_state_connected.0 - == connection.isState.0); - } - } - } - - WlanCloseHandle(client_handle, None); - } - - Ok(false) - } - - pub fn scan_networks() -> Result> { - let client_handle = Self::open_wlan()?; - let mut wlan_entries = Vec::new(); - - unsafe { - let mut interface_list_ptr: *mut WLAN_INTERFACE_INFO_LIST = std::ptr::null_mut(); - let result = WlanEnumInterfaces(client_handle, None, &mut interface_list_ptr); - - if result != 0 || interface_list_ptr.is_null() { - return Err(format!("Failed to get interface list, error code: {}", result).into()); - } - - let interface_list = &*interface_list_ptr; - let interfaces = std::slice::from_raw_parts( - interface_list.InterfaceInfo.as_ptr(), - interface_list.dwNumberOfItems as usize, - ); - - for interface in interfaces { - let interface_guid = interface.InterfaceGuid; - let result = WlanScan(client_handle, &interface_guid, None, None, None); - - if result != 0 { - return Err(format!("Failed to scan, error code: {}", result).into()); - } - - let mut bss_list_ptr = std::ptr::null_mut::(); - let result = WlanGetNetworkBssList( - client_handle, - &interface_guid, - None, - dot11_BSS_type_any, - true, - None, - &mut bss_list_ptr, - ); - - if result != 0 || bss_list_ptr.is_null() { - return Err(format!("Failed to get bss list, error code: {}", result).into()); - } - - let bss_list = &*bss_list_ptr; - if bss_list.dwNumberOfItems == 0 { - continue; - } - - let connection = Self::get_connected_wlan(client_handle, &interface_guid); - let is_connected = match connection { - Some(connection) => { - connection.isState.0 & wlan_interface_state_connected.0 - == connection.isState.0 - } - None => false, - }; - - let entries = std::slice::from_raw_parts( - bss_list.wlanBssEntries.as_ptr(), - bss_list.dwNumberOfItems as usize, - ); - - for entry in entries { - let mut wrapped_entry = WlanBssEntry::from(entry); - - if let Some(connection) = connection { - if connection.wlanAssociationAttributes.dot11Ssid.ucSSID - == entry.dot11Ssid.ucSSID - { - wrapped_entry.connected = is_connected; - } - - if connection.wlanAssociationAttributes.dot11Bssid == entry.dot11Bssid { - wrapped_entry.connected_channel = is_connected; - } - } - - wlan_entries.push(wrapped_entry); - } - } - - WlanCloseHandle(client_handle, None); - } - - Ok(wlan_entries) - } - - pub fn start_scanning(cb: F) - where - F: Fn(Vec) + Send + 'static, - { - SCANNING.store(true, Ordering::SeqCst); - std::thread::spawn(move || { - let mut attempts = 0; - loop { - if !SCANNING.load(Ordering::SeqCst) { - break; - } - - match Self::scan_networks() { - Ok(entries) => { - // sometimes we get an empty list, because the wlan list is updating after the scan - // so we will wait ~10 seconds before show empty list - if !entries.is_empty() || attempts > 3 { - cb(entries); - } else { - attempts += 1; - } - } - Err(err) => { - log::error!("{}", err); - } - } - - std::thread::sleep(Duration::from_secs(3)); - } - }); - } - - pub fn stop_scanning() { - SCANNING.store(false, Ordering::SeqCst); - } -} +use std::{ + sync::atomic::{AtomicBool, Ordering}, + time::Duration, +}; + +use itertools::Itertools; +use windows::{ + core::GUID, + Win32::{ + Foundation::HANDLE, + NetworkManagement::WiFi::{ + dot11_BSS_type_any, wlan_interface_state_connected, + wlan_intf_opcode_current_connection, WlanCloseHandle, WlanEnumInterfaces, + WlanGetNetworkBssList, WlanOpenHandle, WlanQueryInterface, WlanScan, + WLAN_API_VERSION_2_0, WLAN_BSS_ENTRY, WLAN_BSS_LIST, WLAN_CONNECTION_ATTRIBUTES, + WLAN_INTERFACE_INFO_LIST, + }, + }, +}; + +use crate::{error_handler::Result, modules::network::domain::WlanBssEntry}; + +use super::NetworkManager; + +impl From<&WLAN_BSS_ENTRY> for WlanBssEntry { + fn from(entry: &WLAN_BSS_ENTRY) -> Self { + let ssid = String::from_utf8_lossy(&entry.dot11Ssid.ucSSID) + .replace("\0", "") + .to_string(); + + let ssid = if ssid.is_empty() { None } else { Some(ssid) }; + + let bssid = entry + .dot11Bssid + .iter() + .map(|b| format!("{:02x}", b)) + .join(":"); + + Self { + ssid, + bssid, + channel_frequency: entry.ulChCenterFrequency, + signal: entry.uLinkQuality, + connected: false, + connected_channel: false, + } + } +} + +static SCANNING: AtomicBool = AtomicBool::new(false); + +impl NetworkManager { + fn open_wlan() -> Result { + let mut client_handle = HANDLE::default(); + let mut negotiated_version = 0; + + let result = unsafe { + WlanOpenHandle( + WLAN_API_VERSION_2_0, + None, + &mut negotiated_version, + &mut client_handle, + ) + }; + + if result != 0 { + return Err(format!("Failed to open Wlan, error code: {}", result).into()); + } + + Ok(client_handle) + } + + fn get_connected_wlan<'a>( + handle: HANDLE, + guid: &GUID, + ) -> Option<&'a WLAN_CONNECTION_ATTRIBUTES> { + let mut connection_ptr = std::ptr::null_mut::(); + let mut data_size = 0; + unsafe { + WlanQueryInterface( + handle, + guid, + wlan_intf_opcode_current_connection, + None, + &mut data_size, + &mut connection_ptr as *mut _ as _, + None, + ); + + if connection_ptr.is_null() { + None + } else { + Some(&*connection_ptr) + } + } + } + + pub fn is_connected_to(ssid: &str) -> Result { + let client_handle = Self::open_wlan()?; + unsafe { + let mut interface_list_ptr: *mut WLAN_INTERFACE_INFO_LIST = std::ptr::null_mut(); + let result = WlanEnumInterfaces(client_handle, None, &mut interface_list_ptr); + + if result != 0 || interface_list_ptr.is_null() { + return Err(format!("Failed to get interface list, error code: {}", result).into()); + } + + let interface_list = &*interface_list_ptr; + let interfaces = std::slice::from_raw_parts( + interface_list.InterfaceInfo.as_ptr(), + interface_list.dwNumberOfItems as usize, + ); + + for interface in interfaces { + let connection = Self::get_connected_wlan(client_handle, &interface.InterfaceGuid); + + if let Some(connection) = connection { + let connected_ssid = String::from_utf8_lossy( + &connection.wlanAssociationAttributes.dot11Ssid.ucSSID, + ) + .replace("\0", "") + .to_string(); + + if connected_ssid == ssid { + return Ok(connection.isState.0 & wlan_interface_state_connected.0 + == connection.isState.0); + } + } + } + + WlanCloseHandle(client_handle, None); + } + + Ok(false) + } + + pub fn scan_networks() -> Result> { + let client_handle = Self::open_wlan()?; + let mut wlan_entries = Vec::new(); + + unsafe { + let mut interface_list_ptr: *mut WLAN_INTERFACE_INFO_LIST = std::ptr::null_mut(); + let result = WlanEnumInterfaces(client_handle, None, &mut interface_list_ptr); + + if result != 0 || interface_list_ptr.is_null() { + return Err(format!("Failed to get interface list, error code: {}", result).into()); + } + + let interface_list = &*interface_list_ptr; + let interfaces = std::slice::from_raw_parts( + interface_list.InterfaceInfo.as_ptr(), + interface_list.dwNumberOfItems as usize, + ); + + for interface in interfaces { + let interface_guid = interface.InterfaceGuid; + let result = WlanScan(client_handle, &interface_guid, None, None, None); + + if result != 0 { + return Err(format!("Failed to scan, error code: {}", result).into()); + } + + let mut bss_list_ptr = std::ptr::null_mut::(); + let result = WlanGetNetworkBssList( + client_handle, + &interface_guid, + None, + dot11_BSS_type_any, + true, + None, + &mut bss_list_ptr, + ); + + if result != 0 || bss_list_ptr.is_null() { + return Err(format!("Failed to get bss list, error code: {}", result).into()); + } + + let bss_list = &*bss_list_ptr; + if bss_list.dwNumberOfItems == 0 { + continue; + } + + let connection = Self::get_connected_wlan(client_handle, &interface_guid); + let is_connected = match connection { + Some(connection) => { + connection.isState.0 & wlan_interface_state_connected.0 + == connection.isState.0 + } + None => false, + }; + + let entries = std::slice::from_raw_parts( + bss_list.wlanBssEntries.as_ptr(), + bss_list.dwNumberOfItems as usize, + ); + + for entry in entries { + let mut wrapped_entry = WlanBssEntry::from(entry); + + if let Some(connection) = connection { + if connection.wlanAssociationAttributes.dot11Ssid.ucSSID + == entry.dot11Ssid.ucSSID + { + wrapped_entry.connected = is_connected; + } + + if connection.wlanAssociationAttributes.dot11Bssid == entry.dot11Bssid { + wrapped_entry.connected_channel = is_connected; + } + } + + wlan_entries.push(wrapped_entry); + } + } + + WlanCloseHandle(client_handle, None); + } + + Ok(wlan_entries) + } + + pub fn start_scanning(cb: F) + where + F: Fn(Vec) + Send + 'static, + { + SCANNING.store(true, Ordering::SeqCst); + std::thread::spawn(move || { + let mut attempts = 0; + loop { + if !SCANNING.load(Ordering::SeqCst) { + break; + } + + match Self::scan_networks() { + Ok(entries) => { + // sometimes we get an empty list, because the wlan list is updating after the scan + // so we will wait ~10 seconds before show empty list + if !entries.is_empty() || attempts > 3 { + cb(entries); + } else { + attempts += 1; + } + } + Err(err) => { + log::error!("{}", err); + } + } + + std::thread::sleep(Duration::from_secs(3)); + } + }); + } + + pub fn stop_scanning() { + SCANNING.store(false, Ordering::SeqCst); + } +} diff --git a/src/background/modules/network/domain/mod.rs b/src/background/modules/network/domain/mod.rs index 53655c61..94524b58 100644 --- a/src/background/modules/network/domain/mod.rs +++ b/src/background/modules/network/domain/mod.rs @@ -1,169 +1,169 @@ -pub mod types; - -use itertools::Itertools; -use serde::{Deserialize, Serialize}; -use types::InterfaceType; -use windows::Win32::{ - NetworkManagement::{IpHelper::IP_ADAPTER_ADDRESSES_LH, Ndis::IfOperStatusUp}, - Networking::WinSock::{inet_ntop, AF_INET, AF_INET6, SOCKADDR_IN, SOCKADDR_IN6}, -}; - -use crate::error_handler::{AppError, Result}; - -#[derive(Debug, Clone, Serialize)] -pub enum AdapterStatus { - Up, - Down, -} - -#[derive(Debug, Clone, Serialize)] -pub struct NetworkAdapter { - // General information - name: String, - description: String, - status: AdapterStatus, - dns_suffix: String, - #[serde(rename = "type")] - interface_type: String, - // Address information - ipv6: Option, - ipv4: Option, - gateway: Option, - mac: String, -} - -#[derive(PartialEq, Eq)] -enum Address { - Ipv4, - Ipv6, - Gateway, -} - -unsafe fn get_gateway(adapter: &IP_ADAPTER_ADDRESSES_LH) -> Option { - let mut gateway_ptr = adapter.FirstGatewayAddress; - while !gateway_ptr.is_null() { - let gateway = &*gateway_ptr; - - if gateway.Address.lpSockaddr.is_null() { - gateway_ptr = gateway.Next; - continue; - } - - let sockaddr = &*(gateway.Address.lpSockaddr as *const SOCKADDR_IN); - if sockaddr.sin_family == AF_INET { - let mut string_buffer = [0u8; 16]; - return inet_ntop( - AF_INET.0 as i32, - &sockaddr.sin_addr as *const _ as _, - &mut string_buffer, - ) - .to_string() - .ok(); - } - - gateway_ptr = gateway.Next; - } - None -} - -unsafe fn get_address(adapter: &IP_ADAPTER_ADDRESSES_LH, address: Address) -> Option { - if address == Address::Gateway { - return get_gateway(adapter); - } - - let mut unicast_ptr = adapter.FirstUnicastAddress; - - while !unicast_ptr.is_null() { - let unicast = &*unicast_ptr; - - if unicast.Address.lpSockaddr.is_null() { - unicast_ptr = unicast.Next; - continue; - } - - let sockaddr = &*(unicast.Address.lpSockaddr as *const SOCKADDR_IN); - if address == Address::Ipv4 && sockaddr.sin_family == AF_INET { - let mut string_buffer = [0u8; 16]; - return inet_ntop( - AF_INET.0 as i32, - &sockaddr.sin_addr as *const _ as _, - &mut string_buffer, - ) - .to_string() - .ok(); - } - - let sockaddr = &*(unicast.Address.lpSockaddr as *const SOCKADDR_IN6); - if address == Address::Ipv6 && sockaddr.sin6_family == AF_INET6 { - let mut string_buffer = [0u8; 46]; - return inet_ntop( - AF_INET6.0 as i32, - &sockaddr.sin6_addr as *const _ as _, - &mut string_buffer, - ) - .to_string() - .ok(); - } - - unicast_ptr = unicast.Next; - } - - None -} - -impl TryFrom<&IP_ADAPTER_ADDRESSES_LH> for NetworkAdapter { - type Error = AppError; - fn try_from(adapter: &IP_ADAPTER_ADDRESSES_LH) -> Result { - unsafe { - let mac_address = adapter - .PhysicalAddress - .iter() - .map(|b| format!("{:02x}", b)) - .join(":"); - - let status = if adapter.OperStatus == IfOperStatusUp { - AdapterStatus::Up - } else { - AdapterStatus::Down - }; - - Ok(Self { - dns_suffix: adapter.DnsSuffix.to_string()?, - name: adapter.FriendlyName.to_string()?, - description: adapter.Description.to_string()?, - mac: mac_address, - status, - ipv4: get_address(adapter, Address::Ipv4), - gateway: get_address(adapter, Address::Gateway), - ipv6: get_address(adapter, Address::Ipv6), - interface_type: InterfaceType::from(adapter.IfType) - .to_string() - .replace("IF_TYPE_", ""), - }) - } - } -} - -#[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all(serialize = "camelCase", deserialize = "PascalCase"))] -pub struct WlanProfile { - profile_name: String, - #[serde(rename(deserialize = "SSID"))] - ssid: String, - authentication: String, - encryption: String, - password: String, -} - -#[derive(Debug, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct WlanBssEntry { - pub ssid: Option, - pub bssid: String, - pub channel_frequency: u32, - pub signal: u32, - /// true if the interface is connected to this network - pub connected: bool, - /// true if the interface is connected to this network and is using this channel frequency - pub connected_channel: bool, -} +pub mod types; + +use itertools::Itertools; +use serde::{Deserialize, Serialize}; +use types::InterfaceType; +use windows::Win32::{ + NetworkManagement::{IpHelper::IP_ADAPTER_ADDRESSES_LH, Ndis::IfOperStatusUp}, + Networking::WinSock::{inet_ntop, AF_INET, AF_INET6, SOCKADDR_IN, SOCKADDR_IN6}, +}; + +use crate::error_handler::{AppError, Result}; + +#[derive(Debug, Clone, Serialize)] +pub enum AdapterStatus { + Up, + Down, +} + +#[derive(Debug, Clone, Serialize)] +pub struct NetworkAdapter { + // General information + name: String, + description: String, + status: AdapterStatus, + dns_suffix: String, + #[serde(rename = "type")] + interface_type: String, + // Address information + ipv6: Option, + ipv4: Option, + gateway: Option, + mac: String, +} + +#[derive(PartialEq, Eq)] +enum Address { + Ipv4, + Ipv6, + Gateway, +} + +unsafe fn get_gateway(adapter: &IP_ADAPTER_ADDRESSES_LH) -> Option { + let mut gateway_ptr = adapter.FirstGatewayAddress; + while !gateway_ptr.is_null() { + let gateway = &*gateway_ptr; + + if gateway.Address.lpSockaddr.is_null() { + gateway_ptr = gateway.Next; + continue; + } + + let sockaddr = &*(gateway.Address.lpSockaddr as *const SOCKADDR_IN); + if sockaddr.sin_family == AF_INET { + let mut string_buffer = [0u8; 16]; + return inet_ntop( + AF_INET.0 as i32, + &sockaddr.sin_addr as *const _ as _, + &mut string_buffer, + ) + .to_string() + .ok(); + } + + gateway_ptr = gateway.Next; + } + None +} + +unsafe fn get_address(adapter: &IP_ADAPTER_ADDRESSES_LH, address: Address) -> Option { + if address == Address::Gateway { + return get_gateway(adapter); + } + + let mut unicast_ptr = adapter.FirstUnicastAddress; + + while !unicast_ptr.is_null() { + let unicast = &*unicast_ptr; + + if unicast.Address.lpSockaddr.is_null() { + unicast_ptr = unicast.Next; + continue; + } + + let sockaddr = &*(unicast.Address.lpSockaddr as *const SOCKADDR_IN); + if address == Address::Ipv4 && sockaddr.sin_family == AF_INET { + let mut string_buffer = [0u8; 16]; + return inet_ntop( + AF_INET.0 as i32, + &sockaddr.sin_addr as *const _ as _, + &mut string_buffer, + ) + .to_string() + .ok(); + } + + let sockaddr = &*(unicast.Address.lpSockaddr as *const SOCKADDR_IN6); + if address == Address::Ipv6 && sockaddr.sin6_family == AF_INET6 { + let mut string_buffer = [0u8; 46]; + return inet_ntop( + AF_INET6.0 as i32, + &sockaddr.sin6_addr as *const _ as _, + &mut string_buffer, + ) + .to_string() + .ok(); + } + + unicast_ptr = unicast.Next; + } + + None +} + +impl TryFrom<&IP_ADAPTER_ADDRESSES_LH> for NetworkAdapter { + type Error = AppError; + fn try_from(adapter: &IP_ADAPTER_ADDRESSES_LH) -> Result { + unsafe { + let mac_address = adapter + .PhysicalAddress + .iter() + .map(|b| format!("{:02x}", b)) + .join(":"); + + let status = if adapter.OperStatus == IfOperStatusUp { + AdapterStatus::Up + } else { + AdapterStatus::Down + }; + + Ok(Self { + dns_suffix: adapter.DnsSuffix.to_string()?, + name: adapter.FriendlyName.to_string()?, + description: adapter.Description.to_string()?, + mac: mac_address, + status, + ipv4: get_address(adapter, Address::Ipv4), + gateway: get_address(adapter, Address::Gateway), + ipv6: get_address(adapter, Address::Ipv6), + interface_type: InterfaceType::from(adapter.IfType) + .to_string() + .replace("IF_TYPE_", ""), + }) + } + } +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all(serialize = "camelCase", deserialize = "PascalCase"))] +pub struct WlanProfile { + profile_name: String, + #[serde(rename(deserialize = "SSID"))] + ssid: String, + authentication: String, + encryption: String, + password: String, +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct WlanBssEntry { + pub ssid: Option, + pub bssid: String, + pub channel_frequency: u32, + pub signal: u32, + /// true if the interface is connected to this network + pub connected: bool, + /// true if the interface is connected to this network and is using this channel frequency + pub connected_channel: bool, +} diff --git a/src/background/modules/network/domain/types.rs b/src/background/modules/network/domain/types.rs index 9babef15..b4e52172 100644 --- a/src/background/modules/network/domain/types.rs +++ b/src/background/modules/network/domain/types.rs @@ -1,235 +1,235 @@ -use windows::Win32::NetworkManagement::IpHelper::*; - -macro_rules! create_enum { - ($($variant:ident),*) => { - #[allow(non_camel_case_types)] - #[derive(Debug, serde::Serialize)] - pub enum InterfaceType { - $( - $variant = $variant as isize, - )* - Unknown - } - - impl From for InterfaceType { - fn from(value: u32) -> Self { - match value { - $( - $variant => InterfaceType::$variant, - )* - _ => InterfaceType::Unknown - } - } - } - }; -} - -create_enum![ - IF_TYPE_A12MPPSWITCH, - IF_TYPE_AAL2, - IF_TYPE_AAL5, - IF_TYPE_ADSL, - IF_TYPE_AFLANE_8023, - IF_TYPE_AFLANE_8025, - IF_TYPE_ARAP, - IF_TYPE_ARCNET, - IF_TYPE_ARCNET_PLUS, - IF_TYPE_ASYNC, - IF_TYPE_ATM, - IF_TYPE_ATM_DXI, - IF_TYPE_ATM_FUNI, - IF_TYPE_ATM_IMA, - IF_TYPE_ATM_LOGICAL, - IF_TYPE_ATM_RADIO, - IF_TYPE_ATM_SUBINTERFACE, - IF_TYPE_ATM_VCI_ENDPT, - IF_TYPE_ATM_VIRTUAL, - IF_TYPE_BASIC_ISDN, - IF_TYPE_BGP_POLICY_ACCOUNTING, - IF_TYPE_BSC, - IF_TYPE_CCTEMUL, - IF_TYPE_CES, - IF_TYPE_CHANNEL, - IF_TYPE_CNR, - IF_TYPE_COFFEE, - IF_TYPE_COMPOSITELINK, - IF_TYPE_DCN, - IF_TYPE_DDN_X25, - IF_TYPE_DIGITALPOWERLINE, - IF_TYPE_DIGITAL_WRAPPER_OVERHEAD_CHANNEL, - IF_TYPE_DLSW, - IF_TYPE_DOCSCABLE_DOWNSTREAM, - IF_TYPE_DOCSCABLE_MACLAYER, - IF_TYPE_DOCSCABLE_UPSTREAM, - IF_TYPE_DS0, - IF_TYPE_DS0_BUNDLE, - IF_TYPE_DS1, - IF_TYPE_DS1_FDL, - IF_TYPE_DS3, - IF_TYPE_DTM, - IF_TYPE_DVBRCC_DOWNSTREAM, - IF_TYPE_DVBRCC_MACLAYER, - IF_TYPE_DVBRCC_UPSTREAM, - IF_TYPE_DVB_ASI_IN, - IF_TYPE_DVB_ASI_OUT, - IF_TYPE_E1, - IF_TYPE_EON, - IF_TYPE_EPLRS, - IF_TYPE_ESCON, - IF_TYPE_ETHERNET_3MBIT, - IF_TYPE_ETHERNET_CSMACD, - IF_TYPE_FAST, - IF_TYPE_FASTETHER, - IF_TYPE_FASTETHER_FX, - IF_TYPE_FDDI, - IF_TYPE_FIBRECHANNEL, - IF_TYPE_FRAMERELAY, - IF_TYPE_FRAMERELAY_INTERCONNECT, - IF_TYPE_FRAMERELAY_MPI, - IF_TYPE_FRAMERELAY_SERVICE, - IF_TYPE_FRF16_MFR_BUNDLE, - IF_TYPE_FR_DLCI_ENDPT, - IF_TYPE_FR_FORWARD, - IF_TYPE_G703_2MB, - IF_TYPE_G703_64K, - IF_TYPE_GIGABITETHERNET, - IF_TYPE_GR303_IDT, - IF_TYPE_GR303_RDT, - IF_TYPE_H323_GATEKEEPER, - IF_TYPE_H323_PROXY, - IF_TYPE_HDH_1822, - IF_TYPE_HDLC, - IF_TYPE_HDSL2, - IF_TYPE_HIPERLAN2, - IF_TYPE_HIPPI, - IF_TYPE_HIPPIINTERFACE, - IF_TYPE_HOSTPAD, - IF_TYPE_HSSI, - IF_TYPE_HYPERCHANNEL, - IF_TYPE_IBM370PARCHAN, - IF_TYPE_IDSL, - IF_TYPE_IEEE1394, - IF_TYPE_IEEE80211, - IF_TYPE_IEEE80212, - IF_TYPE_IEEE802154, - IF_TYPE_IEEE80216_WMAN, - IF_TYPE_IEEE8023AD_LAG, - IF_TYPE_IF_GSN, - IF_TYPE_IMT, - IF_TYPE_INTERLEAVE, - IF_TYPE_IP, - IF_TYPE_IPFORWARD, - IF_TYPE_IPOVER_ATM, - IF_TYPE_IPOVER_CDLC, - IF_TYPE_IPOVER_CLAW, - IF_TYPE_IPSWITCH, - IF_TYPE_IS088023_CSMACD, - IF_TYPE_ISDN, - IF_TYPE_ISDN_S, - IF_TYPE_ISDN_U, - IF_TYPE_ISO88022_LLC, - IF_TYPE_ISO88024_TOKENBUS, - IF_TYPE_ISO88025R_DTR, - IF_TYPE_ISO88025_CRFPRINT, - IF_TYPE_ISO88025_FIBER, - IF_TYPE_ISO88025_TOKENRING, - IF_TYPE_ISO88026_MAN, - IF_TYPE_ISUP, - IF_TYPE_L2_VLAN, - IF_TYPE_L3_IPVLAN, - IF_TYPE_L3_IPXVLAN, - IF_TYPE_LAP_B, - IF_TYPE_LAP_D, - IF_TYPE_LAP_F, - IF_TYPE_LOCALTALK, - IF_TYPE_MEDIAMAILOVERIP, - IF_TYPE_MF_SIGLINK, - IF_TYPE_MIO_X25, - IF_TYPE_MODEM, - IF_TYPE_MPC, - IF_TYPE_MPLS, - IF_TYPE_MPLS_TUNNEL, - IF_TYPE_MSDSL, - IF_TYPE_MVL, - IF_TYPE_MYRINET, - IF_TYPE_NFAS, - IF_TYPE_NSIP, - IF_TYPE_OPTICAL_CHANNEL, - IF_TYPE_OPTICAL_TRANSPORT, - IF_TYPE_OTHER, - IF_TYPE_PARA, - IF_TYPE_PLC, - IF_TYPE_POS, - IF_TYPE_PPP, - IF_TYPE_PPPMULTILINKBUNDLE, - IF_TYPE_PRIMARY_ISDN, - IF_TYPE_PROP_BWA_P2MP, - IF_TYPE_PROP_CNLS, - IF_TYPE_PROP_DOCS_WIRELESS_DOWNSTREAM, - IF_TYPE_PROP_DOCS_WIRELESS_MACLAYER, - IF_TYPE_PROP_DOCS_WIRELESS_UPSTREAM, - IF_TYPE_PROP_MULTIPLEXOR, - IF_TYPE_PROP_POINT2POINT_SERIAL, - IF_TYPE_PROP_VIRTUAL, - IF_TYPE_PROP_WIRELESS_P2P, - IF_TYPE_PROTEON_10MBIT, - IF_TYPE_PROTEON_80MBIT, - IF_TYPE_QLLC, - IF_TYPE_RADIO_MAC, - IF_TYPE_RADSL, - IF_TYPE_REACH_DSL, - IF_TYPE_REGULAR_1822, - IF_TYPE_RFC1483, - IF_TYPE_RFC877_X25, - IF_TYPE_RS232, - IF_TYPE_RSRB, - IF_TYPE_SDLC, - IF_TYPE_SDSL, - IF_TYPE_SHDSL, - IF_TYPE_SIP, - IF_TYPE_SLIP, - IF_TYPE_SMDS_DXI, - IF_TYPE_SMDS_ICIP, - IF_TYPE_SOFTWARE_LOOPBACK, - IF_TYPE_SONET, - IF_TYPE_SONET_OVERHEAD_CHANNEL, - IF_TYPE_SONET_PATH, - IF_TYPE_SONET_VT, - IF_TYPE_SRP, - IF_TYPE_SS7_SIGLINK, - IF_TYPE_STACKTOSTACK, - IF_TYPE_STARLAN, - IF_TYPE_TDLC, - IF_TYPE_TERMPAD, - IF_TYPE_TR008, - IF_TYPE_TRANSPHDLC, - IF_TYPE_TUNNEL, - IF_TYPE_ULTRA, - IF_TYPE_USB, - IF_TYPE_V11, - IF_TYPE_V35, - IF_TYPE_V36, - IF_TYPE_V37, - IF_TYPE_VDSL, - IF_TYPE_VIRTUALIPADDRESS, - IF_TYPE_VOICEOVERATM, - IF_TYPE_VOICEOVERFRAMERELAY, - IF_TYPE_VOICE_EM, - IF_TYPE_VOICE_ENCAP, - IF_TYPE_VOICE_FXO, - IF_TYPE_VOICE_FXS, - IF_TYPE_VOICE_OVERIP, - IF_TYPE_WWANPP, - IF_TYPE_WWANPP2, - IF_TYPE_X213, - IF_TYPE_X25_HUNTGROUP, - IF_TYPE_X25_MLP, - IF_TYPE_X25_PLE, - IF_TYPE_XBOX_WIRELESS -]; - -impl std::fmt::Display for InterfaceType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self) - } -} +use windows::Win32::NetworkManagement::IpHelper::*; + +macro_rules! create_enum { + ($($variant:ident),*) => { + #[allow(non_camel_case_types)] + #[derive(Debug, serde::Serialize)] + pub enum InterfaceType { + $( + $variant = $variant as isize, + )* + Unknown + } + + impl From for InterfaceType { + fn from(value: u32) -> Self { + match value { + $( + $variant => InterfaceType::$variant, + )* + _ => InterfaceType::Unknown + } + } + } + }; +} + +create_enum![ + IF_TYPE_A12MPPSWITCH, + IF_TYPE_AAL2, + IF_TYPE_AAL5, + IF_TYPE_ADSL, + IF_TYPE_AFLANE_8023, + IF_TYPE_AFLANE_8025, + IF_TYPE_ARAP, + IF_TYPE_ARCNET, + IF_TYPE_ARCNET_PLUS, + IF_TYPE_ASYNC, + IF_TYPE_ATM, + IF_TYPE_ATM_DXI, + IF_TYPE_ATM_FUNI, + IF_TYPE_ATM_IMA, + IF_TYPE_ATM_LOGICAL, + IF_TYPE_ATM_RADIO, + IF_TYPE_ATM_SUBINTERFACE, + IF_TYPE_ATM_VCI_ENDPT, + IF_TYPE_ATM_VIRTUAL, + IF_TYPE_BASIC_ISDN, + IF_TYPE_BGP_POLICY_ACCOUNTING, + IF_TYPE_BSC, + IF_TYPE_CCTEMUL, + IF_TYPE_CES, + IF_TYPE_CHANNEL, + IF_TYPE_CNR, + IF_TYPE_COFFEE, + IF_TYPE_COMPOSITELINK, + IF_TYPE_DCN, + IF_TYPE_DDN_X25, + IF_TYPE_DIGITALPOWERLINE, + IF_TYPE_DIGITAL_WRAPPER_OVERHEAD_CHANNEL, + IF_TYPE_DLSW, + IF_TYPE_DOCSCABLE_DOWNSTREAM, + IF_TYPE_DOCSCABLE_MACLAYER, + IF_TYPE_DOCSCABLE_UPSTREAM, + IF_TYPE_DS0, + IF_TYPE_DS0_BUNDLE, + IF_TYPE_DS1, + IF_TYPE_DS1_FDL, + IF_TYPE_DS3, + IF_TYPE_DTM, + IF_TYPE_DVBRCC_DOWNSTREAM, + IF_TYPE_DVBRCC_MACLAYER, + IF_TYPE_DVBRCC_UPSTREAM, + IF_TYPE_DVB_ASI_IN, + IF_TYPE_DVB_ASI_OUT, + IF_TYPE_E1, + IF_TYPE_EON, + IF_TYPE_EPLRS, + IF_TYPE_ESCON, + IF_TYPE_ETHERNET_3MBIT, + IF_TYPE_ETHERNET_CSMACD, + IF_TYPE_FAST, + IF_TYPE_FASTETHER, + IF_TYPE_FASTETHER_FX, + IF_TYPE_FDDI, + IF_TYPE_FIBRECHANNEL, + IF_TYPE_FRAMERELAY, + IF_TYPE_FRAMERELAY_INTERCONNECT, + IF_TYPE_FRAMERELAY_MPI, + IF_TYPE_FRAMERELAY_SERVICE, + IF_TYPE_FRF16_MFR_BUNDLE, + IF_TYPE_FR_DLCI_ENDPT, + IF_TYPE_FR_FORWARD, + IF_TYPE_G703_2MB, + IF_TYPE_G703_64K, + IF_TYPE_GIGABITETHERNET, + IF_TYPE_GR303_IDT, + IF_TYPE_GR303_RDT, + IF_TYPE_H323_GATEKEEPER, + IF_TYPE_H323_PROXY, + IF_TYPE_HDH_1822, + IF_TYPE_HDLC, + IF_TYPE_HDSL2, + IF_TYPE_HIPERLAN2, + IF_TYPE_HIPPI, + IF_TYPE_HIPPIINTERFACE, + IF_TYPE_HOSTPAD, + IF_TYPE_HSSI, + IF_TYPE_HYPERCHANNEL, + IF_TYPE_IBM370PARCHAN, + IF_TYPE_IDSL, + IF_TYPE_IEEE1394, + IF_TYPE_IEEE80211, + IF_TYPE_IEEE80212, + IF_TYPE_IEEE802154, + IF_TYPE_IEEE80216_WMAN, + IF_TYPE_IEEE8023AD_LAG, + IF_TYPE_IF_GSN, + IF_TYPE_IMT, + IF_TYPE_INTERLEAVE, + IF_TYPE_IP, + IF_TYPE_IPFORWARD, + IF_TYPE_IPOVER_ATM, + IF_TYPE_IPOVER_CDLC, + IF_TYPE_IPOVER_CLAW, + IF_TYPE_IPSWITCH, + IF_TYPE_IS088023_CSMACD, + IF_TYPE_ISDN, + IF_TYPE_ISDN_S, + IF_TYPE_ISDN_U, + IF_TYPE_ISO88022_LLC, + IF_TYPE_ISO88024_TOKENBUS, + IF_TYPE_ISO88025R_DTR, + IF_TYPE_ISO88025_CRFPRINT, + IF_TYPE_ISO88025_FIBER, + IF_TYPE_ISO88025_TOKENRING, + IF_TYPE_ISO88026_MAN, + IF_TYPE_ISUP, + IF_TYPE_L2_VLAN, + IF_TYPE_L3_IPVLAN, + IF_TYPE_L3_IPXVLAN, + IF_TYPE_LAP_B, + IF_TYPE_LAP_D, + IF_TYPE_LAP_F, + IF_TYPE_LOCALTALK, + IF_TYPE_MEDIAMAILOVERIP, + IF_TYPE_MF_SIGLINK, + IF_TYPE_MIO_X25, + IF_TYPE_MODEM, + IF_TYPE_MPC, + IF_TYPE_MPLS, + IF_TYPE_MPLS_TUNNEL, + IF_TYPE_MSDSL, + IF_TYPE_MVL, + IF_TYPE_MYRINET, + IF_TYPE_NFAS, + IF_TYPE_NSIP, + IF_TYPE_OPTICAL_CHANNEL, + IF_TYPE_OPTICAL_TRANSPORT, + IF_TYPE_OTHER, + IF_TYPE_PARA, + IF_TYPE_PLC, + IF_TYPE_POS, + IF_TYPE_PPP, + IF_TYPE_PPPMULTILINKBUNDLE, + IF_TYPE_PRIMARY_ISDN, + IF_TYPE_PROP_BWA_P2MP, + IF_TYPE_PROP_CNLS, + IF_TYPE_PROP_DOCS_WIRELESS_DOWNSTREAM, + IF_TYPE_PROP_DOCS_WIRELESS_MACLAYER, + IF_TYPE_PROP_DOCS_WIRELESS_UPSTREAM, + IF_TYPE_PROP_MULTIPLEXOR, + IF_TYPE_PROP_POINT2POINT_SERIAL, + IF_TYPE_PROP_VIRTUAL, + IF_TYPE_PROP_WIRELESS_P2P, + IF_TYPE_PROTEON_10MBIT, + IF_TYPE_PROTEON_80MBIT, + IF_TYPE_QLLC, + IF_TYPE_RADIO_MAC, + IF_TYPE_RADSL, + IF_TYPE_REACH_DSL, + IF_TYPE_REGULAR_1822, + IF_TYPE_RFC1483, + IF_TYPE_RFC877_X25, + IF_TYPE_RS232, + IF_TYPE_RSRB, + IF_TYPE_SDLC, + IF_TYPE_SDSL, + IF_TYPE_SHDSL, + IF_TYPE_SIP, + IF_TYPE_SLIP, + IF_TYPE_SMDS_DXI, + IF_TYPE_SMDS_ICIP, + IF_TYPE_SOFTWARE_LOOPBACK, + IF_TYPE_SONET, + IF_TYPE_SONET_OVERHEAD_CHANNEL, + IF_TYPE_SONET_PATH, + IF_TYPE_SONET_VT, + IF_TYPE_SRP, + IF_TYPE_SS7_SIGLINK, + IF_TYPE_STACKTOSTACK, + IF_TYPE_STARLAN, + IF_TYPE_TDLC, + IF_TYPE_TERMPAD, + IF_TYPE_TR008, + IF_TYPE_TRANSPHDLC, + IF_TYPE_TUNNEL, + IF_TYPE_ULTRA, + IF_TYPE_USB, + IF_TYPE_V11, + IF_TYPE_V35, + IF_TYPE_V36, + IF_TYPE_V37, + IF_TYPE_VDSL, + IF_TYPE_VIRTUALIPADDRESS, + IF_TYPE_VOICEOVERATM, + IF_TYPE_VOICEOVERFRAMERELAY, + IF_TYPE_VOICE_EM, + IF_TYPE_VOICE_ENCAP, + IF_TYPE_VOICE_FXO, + IF_TYPE_VOICE_FXS, + IF_TYPE_VOICE_OVERIP, + IF_TYPE_WWANPP, + IF_TYPE_WWANPP2, + IF_TYPE_X213, + IF_TYPE_X25_HUNTGROUP, + IF_TYPE_X25_MLP, + IF_TYPE_X25_PLE, + IF_TYPE_XBOX_WIRELESS +]; + +impl std::fmt::Display for InterfaceType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} diff --git a/src/background/modules/network/infrastructure.rs b/src/background/modules/network/infrastructure.rs index edc60377..61450a43 100644 --- a/src/background/modules/network/infrastructure.rs +++ b/src/background/modules/network/infrastructure.rs @@ -1,132 +1,132 @@ -use std::sync::atomic::{AtomicBool, Ordering}; - -use tauri::Emitter; -use tauri_plugin_shell::ShellExt; -use windows::Win32::Networking::NetworkListManager::{ - INetworkListManager, NetworkListManager, NLM_CONNECTIVITY_IPV4_INTERNET, - NLM_CONNECTIVITY_IPV6_INTERNET, -}; - -use crate::{ - error_handler::Result, log_error, seelen::get_app_handle, utils::sleep_millis, windows_api::Com, -}; - -use super::{ - application::{get_local_ip_address, NetworkManager}, - domain::{NetworkAdapter, WlanProfile}, -}; - -fn emit_networks(ip: String, adapters: Vec, has_internet: bool) { - let handle = get_app_handle(); - log_error!(handle.emit("network-default-local-ip", ip)); - log_error!(handle.emit("network-adapters", adapters)); - log_error!(handle.emit("network-internet-connection", has_internet)); -} - -static REGISTERED: AtomicBool = AtomicBool::new(false); -pub fn register_network_events() -> Result<()> { - if !REGISTERED.load(Ordering::Acquire) { - log::trace!("Registering network events"); - NetworkManager::register_events(move |connectivity| { - log::trace!(target: "network", "Connectivity changed: {:?}", connectivity); - if let (Ok(ip), Ok(adapters)) = (get_local_ip_address(), NetworkManager::get_adapters()) - { - let has_internet_ipv4 = connectivity.0 & NLM_CONNECTIVITY_IPV4_INTERNET.0 - == NLM_CONNECTIVITY_IPV4_INTERNET.0; - let has_internet_ipv6 = connectivity.0 & NLM_CONNECTIVITY_IPV6_INTERNET.0 - == NLM_CONNECTIVITY_IPV6_INTERNET.0; - - emit_networks(ip, adapters, has_internet_ipv4 || has_internet_ipv6); - } - }); - REGISTERED.store(true, Ordering::Release); - } - - if let (Ok(ip), Ok(adapters)) = (get_local_ip_address(), NetworkManager::get_adapters()) { - let has_internet = Com::run_with_context(|| { - let list_manager: INetworkListManager = Com::create_instance(&NetworkListManager)?; - let connectivity = unsafe { list_manager.GetConnectivity()? }; - - let has_internet_ipv4 = connectivity.0 & NLM_CONNECTIVITY_IPV4_INTERNET.0 - == NLM_CONNECTIVITY_IPV4_INTERNET.0; - let has_internet_ipv6 = connectivity.0 & NLM_CONNECTIVITY_IPV6_INTERNET.0 - == NLM_CONNECTIVITY_IPV6_INTERNET.0; - - Ok(has_internet_ipv4 || has_internet_ipv6) - })?; - emit_networks(ip, adapters, has_internet); - } - - Ok(()) -} - -async fn try_connect_to_profile(ssid: &str) -> Result { - let handle = get_app_handle(); - let output = handle - .shell() - .command("netsh") - .args(["wlan", "connect", &format!("name={}", ssid)]) - .output() - .await?; - - if output.status.success() { - // wait to ensure connection - sleep_millis(2000); - Ok(NetworkManager::is_connected_to(ssid)?) - } else { - Err(output.into()) - } -} - -#[tauri::command] -pub fn wlan_start_scanning() { - log::trace!("Start scanning networks"); - NetworkManager::start_scanning(|list| { - let app = get_app_handle(); - log_error!(app.emit("wlan-scanned", &list)); - }); -} - -#[tauri::command] -pub fn wlan_stop_scanning() { - log::trace!("Stop scanning networks"); - NetworkManager::stop_scanning(); -} - -#[tauri::command] -pub async fn wlan_get_profiles() -> Result> { - NetworkManager::get_wifi_profiles().await -} - -#[tauri::command] -pub async fn wlan_connect(ssid: String, password: String, hidden: bool) -> Result { - NetworkManager::add_profile(&ssid, &password, hidden).await?; - match try_connect_to_profile(&ssid).await { - Ok(true) => Ok(true), - Ok(false) => { - NetworkManager::remove_profile(&ssid).await?; - Ok(false) - } - Err(err) => { - NetworkManager::remove_profile(&ssid).await?; - Err(err) - } - } -} - -#[tauri::command] -pub async fn wlan_disconnect() -> Result<()> { - let handle = get_app_handle(); - let output = handle - .shell() - .command("netsh") - .args(["wlan", "disconnect"]) - .output() - .await?; - - if output.status.success() { - Ok(()) - } else { - Err(output.into()) - } -} +use std::sync::atomic::{AtomicBool, Ordering}; + +use tauri::Emitter; +use tauri_plugin_shell::ShellExt; +use windows::Win32::Networking::NetworkListManager::{ + INetworkListManager, NetworkListManager, NLM_CONNECTIVITY_IPV4_INTERNET, + NLM_CONNECTIVITY_IPV6_INTERNET, +}; + +use crate::{ + error_handler::Result, log_error, seelen::get_app_handle, utils::sleep_millis, windows_api::Com, +}; + +use super::{ + application::{get_local_ip_address, NetworkManager}, + domain::{NetworkAdapter, WlanProfile}, +}; + +fn emit_networks(ip: String, adapters: Vec, has_internet: bool) { + let handle = get_app_handle(); + log_error!(handle.emit("network-default-local-ip", ip)); + log_error!(handle.emit("network-adapters", adapters)); + log_error!(handle.emit("network-internet-connection", has_internet)); +} + +static REGISTERED: AtomicBool = AtomicBool::new(false); +pub fn register_network_events() -> Result<()> { + if !REGISTERED.load(Ordering::Acquire) { + log::trace!("Registering network events"); + NetworkManager::register_events(move |connectivity| { + log::trace!(target: "network", "Connectivity changed: {:?}", connectivity); + if let (Ok(ip), Ok(adapters)) = (get_local_ip_address(), NetworkManager::get_adapters()) + { + let has_internet_ipv4 = connectivity.0 & NLM_CONNECTIVITY_IPV4_INTERNET.0 + == NLM_CONNECTIVITY_IPV4_INTERNET.0; + let has_internet_ipv6 = connectivity.0 & NLM_CONNECTIVITY_IPV6_INTERNET.0 + == NLM_CONNECTIVITY_IPV6_INTERNET.0; + + emit_networks(ip, adapters, has_internet_ipv4 || has_internet_ipv6); + } + }); + REGISTERED.store(true, Ordering::Release); + } + + if let (Ok(ip), Ok(adapters)) = (get_local_ip_address(), NetworkManager::get_adapters()) { + let has_internet = Com::run_with_context(|| { + let list_manager: INetworkListManager = Com::create_instance(&NetworkListManager)?; + let connectivity = unsafe { list_manager.GetConnectivity()? }; + + let has_internet_ipv4 = connectivity.0 & NLM_CONNECTIVITY_IPV4_INTERNET.0 + == NLM_CONNECTIVITY_IPV4_INTERNET.0; + let has_internet_ipv6 = connectivity.0 & NLM_CONNECTIVITY_IPV6_INTERNET.0 + == NLM_CONNECTIVITY_IPV6_INTERNET.0; + + Ok(has_internet_ipv4 || has_internet_ipv6) + })?; + emit_networks(ip, adapters, has_internet); + } + + Ok(()) +} + +async fn try_connect_to_profile(ssid: &str) -> Result { + let handle = get_app_handle(); + let output = handle + .shell() + .command("netsh") + .args(["wlan", "connect", &format!("name={}", ssid)]) + .output() + .await?; + + if output.status.success() { + // wait to ensure connection + sleep_millis(2000); + Ok(NetworkManager::is_connected_to(ssid)?) + } else { + Err(output.into()) + } +} + +#[tauri::command] +pub fn wlan_start_scanning() { + log::trace!("Start scanning networks"); + NetworkManager::start_scanning(|list| { + let app = get_app_handle(); + log_error!(app.emit("wlan-scanned", &list)); + }); +} + +#[tauri::command] +pub fn wlan_stop_scanning() { + log::trace!("Stop scanning networks"); + NetworkManager::stop_scanning(); +} + +#[tauri::command] +pub async fn wlan_get_profiles() -> Result> { + NetworkManager::get_wifi_profiles().await +} + +#[tauri::command] +pub async fn wlan_connect(ssid: String, password: String, hidden: bool) -> Result { + NetworkManager::add_profile(&ssid, &password, hidden).await?; + match try_connect_to_profile(&ssid).await { + Ok(true) => Ok(true), + Ok(false) => { + NetworkManager::remove_profile(&ssid).await?; + Ok(false) + } + Err(err) => { + NetworkManager::remove_profile(&ssid).await?; + Err(err) + } + } +} + +#[tauri::command] +pub async fn wlan_disconnect() -> Result<()> { + let handle = get_app_handle(); + let output = handle + .shell() + .command("netsh") + .args(["wlan", "disconnect"]) + .output() + .await?; + + if output.status.success() { + Ok(()) + } else { + Err(output.into()) + } +} diff --git a/src/background/modules/network/mod.rs b/src/background/modules/network/mod.rs index 50d07953..c347d7e3 100644 --- a/src/background/modules/network/mod.rs +++ b/src/background/modules/network/mod.rs @@ -1,3 +1,3 @@ -pub mod application; -pub mod domain; -pub mod infrastructure; +pub mod application; +pub mod domain; +pub mod infrastructure; diff --git a/src/background/modules/notifications/application.rs b/src/background/modules/notifications/application.rs index a53c7730..44fae4f3 100644 --- a/src/background/modules/notifications/application.rs +++ b/src/background/modules/notifications/application.rs @@ -1,227 +1,227 @@ -use std::{ - path::PathBuf, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - }, -}; - -use lazy_static::lazy_static; -use parking_lot::Mutex; -use serde::Serialize; -use windows::{ - Foundation::{EventRegistrationToken, TypedEventHandler}, - UI::Notifications::{ - KnownNotificationBindings, - Management::{UserNotificationListener, UserNotificationListenerAccessStatus}, - NotificationKinds, UserNotification, UserNotificationChangedEventArgs, - }, -}; - -use crate::{error_handler::Result, log_error}; - -lazy_static! { - pub static ref NOTIFICATION_MANAGER: Arc> = Arc::new(Mutex::new( - NotificationManager::new().expect("Failed to create notification manager") - )); -} - -#[derive(Debug, Serialize)] -#[allow(dead_code)] -pub struct AppNotification { - pub id: u32, - app_name: String, - app_description: String, - app_logo: Option, - body: Vec, - date: i64, -} - -enum NotificationEvent { - Added(u32), - Removed(u32), -} - -type OnNotificationsChange = Box) + Send + Sync>; - -pub struct NotificationManager { - listener: UserNotificationListener, - notifications: Vec, - notifications_ids: Vec, - callbacks: Vec, - event_handler: TypedEventHandler, - event_token: Option, -} - -unsafe impl Send for NotificationManager {} - -impl NotificationManager { - pub fn notifications(&self) -> &Vec { - &self.notifications - } -} - -static RELEASED: AtomicBool = AtomicBool::new(true); - -impl NotificationManager { - fn new() -> Result { - let mut manager = Self { - listener: UserNotificationListener::Current()?, - callbacks: Vec::new(), - notifications: Vec::new(), - notifications_ids: Vec::new(), - event_handler: TypedEventHandler::new(Self::internal_notifications_change), - event_token: None, - }; - manager.initialize()?; - Ok(manager) - } - - pub fn remove_notification(&mut self, id: u32) -> Result<()> { - self.notifications.retain(|n| n.id != id); - self.notify_changes(); - self.listener.RemoveNotification(id)?; - Ok(()) - } - - pub fn clear_notifications(&mut self) -> Result<()> { - self.notifications.clear(); - self.notify_changes(); - for notification in self.notifications() { - self.listener.RemoveNotification(notification.id)?; - } - Ok(()) - } - - fn initialize(&mut self) -> Result<()> { - let access = self.listener.RequestAccessAsync()?.get()?; - if access != UserNotificationListenerAccessStatus::Allowed { - return Err("Failed to get notification access".into()); - } - - if let Err(err) = self.listener.NotificationChanged(&self.event_handler) { - log::debug!( - "Failed to use NotificationChanged: {:?}, spawning thread instead", - err - ); - std::thread::spawn(|| -> Result<()> { - RELEASED.store(false, Ordering::SeqCst); - let listener = UserNotificationListener::Current()?; - while !RELEASED.load(Ordering::Acquire) { - log_error!(Self::internal_notifications_change( - &Some(listener.clone()), - &None - )); - std::thread::sleep(std::time::Duration::from_secs(1)); - } - Ok(()) - }); - } - - let u_notifications = self - .listener - .GetNotificationsAsync(NotificationKinds::Toast)? - .get()?; - - for u_notification in u_notifications { - log_error!(self.load_notification(u_notification)); - } - - Ok(()) - } - - pub fn release(&mut self) -> Result<()> { - if let Some(token) = self.event_token.take() { - self.listener.RemoveNotificationChanged(token)?; - } - RELEASED.store(true, Ordering::Release); - Ok(()) - } - - fn internal_notifications_change( - listener: &Option, - _args: &Option, - ) -> windows_core::Result<()> { - if let Some(listener) = listener { - let mut manager = NOTIFICATION_MANAGER.lock(); - let mut current_list = manager.notifications_ids.clone(); - - for u_notification in listener - .GetNotificationsAsync(NotificationKinds::Toast)? - .get()? - { - let id = u_notification.Id()?; - if !current_list.contains(&id) { - manager.emit_event(NotificationEvent::Added(id)); - } - current_list.retain(|x| *x != id); - } - - for id in current_list { - manager.emit_event(NotificationEvent::Removed(id)); - } - } - Ok(()) - } - - pub fn notify_changes(&self) { - for callback in &self.callbacks { - callback(self.notifications()); - } - } - - fn emit_event(&mut self, event: NotificationEvent) { - log_error!(self.process_event(event)); - self.notify_changes(); - } - - fn process_event(&mut self, event: NotificationEvent) -> Result<()> { - match event { - NotificationEvent::Added(id) => { - let u_notification = self.listener.GetNotification(id)?; - self.load_notification(u_notification)?; - } - NotificationEvent::Removed(id) => { - self.notifications.retain(|n| n.id != id); - self.notifications_ids.retain(|x| *x != id); - } - } - Ok(()) - } - - pub fn on_notifications_change(&mut self, callback: F) - where - F: Fn(&Vec) + Send + Sync + 'static, - { - self.callbacks.push(Box::new(callback)); - } - - fn load_notification(&mut self, u_notification: UserNotification) -> Result<()> { - let notification = u_notification.Notification()?; - - let app_info = u_notification.AppInfo()?; - let display_info = app_info.DisplayInfo()?; - - let visuals = notification.Visual()?; - - let text_sequence = visuals - .GetBinding(&KnownNotificationBindings::ToastGeneric()?)? - .GetTextElements()?; - - let mut body = Vec::new(); - for text in text_sequence { - body.push(text.Text()?.to_string()); - } - - self.notifications.push(AppNotification { - id: u_notification.Id()?, - app_logo: None, - app_name: display_info.DisplayName()?.to_string(), - app_description: display_info.Description()?.to_string(), - body, - date: u_notification.CreationTime()?.UniversalTime, - }); - self.notifications_ids.push(u_notification.Id()?); - Ok(()) - } -} +use std::{ + path::PathBuf, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, +}; + +use lazy_static::lazy_static; +use parking_lot::Mutex; +use serde::Serialize; +use windows::{ + Foundation::{EventRegistrationToken, TypedEventHandler}, + UI::Notifications::{ + KnownNotificationBindings, + Management::{UserNotificationListener, UserNotificationListenerAccessStatus}, + NotificationKinds, UserNotification, UserNotificationChangedEventArgs, + }, +}; + +use crate::{error_handler::Result, log_error}; + +lazy_static! { + pub static ref NOTIFICATION_MANAGER: Arc> = Arc::new(Mutex::new( + NotificationManager::new().expect("Failed to create notification manager") + )); +} + +#[derive(Debug, Serialize)] +#[allow(dead_code)] +pub struct AppNotification { + pub id: u32, + app_name: String, + app_description: String, + app_logo: Option, + body: Vec, + date: i64, +} + +enum NotificationEvent { + Added(u32), + Removed(u32), +} + +type OnNotificationsChange = Box) + Send + Sync>; + +pub struct NotificationManager { + listener: UserNotificationListener, + notifications: Vec, + notifications_ids: Vec, + callbacks: Vec, + event_handler: TypedEventHandler, + event_token: Option, +} + +unsafe impl Send for NotificationManager {} + +impl NotificationManager { + pub fn notifications(&self) -> &Vec { + &self.notifications + } +} + +static RELEASED: AtomicBool = AtomicBool::new(true); + +impl NotificationManager { + fn new() -> Result { + let mut manager = Self { + listener: UserNotificationListener::Current()?, + callbacks: Vec::new(), + notifications: Vec::new(), + notifications_ids: Vec::new(), + event_handler: TypedEventHandler::new(Self::internal_notifications_change), + event_token: None, + }; + manager.initialize()?; + Ok(manager) + } + + pub fn remove_notification(&mut self, id: u32) -> Result<()> { + self.notifications.retain(|n| n.id != id); + self.notify_changes(); + self.listener.RemoveNotification(id)?; + Ok(()) + } + + pub fn clear_notifications(&mut self) -> Result<()> { + self.notifications.clear(); + self.notify_changes(); + for notification in self.notifications() { + self.listener.RemoveNotification(notification.id)?; + } + Ok(()) + } + + fn initialize(&mut self) -> Result<()> { + let access = self.listener.RequestAccessAsync()?.get()?; + if access != UserNotificationListenerAccessStatus::Allowed { + return Err("Failed to get notification access".into()); + } + + if let Err(err) = self.listener.NotificationChanged(&self.event_handler) { + log::debug!( + "Failed to use NotificationChanged: {:?}, spawning thread instead", + err + ); + std::thread::spawn(|| -> Result<()> { + RELEASED.store(false, Ordering::SeqCst); + let listener = UserNotificationListener::Current()?; + while !RELEASED.load(Ordering::Acquire) { + log_error!(Self::internal_notifications_change( + &Some(listener.clone()), + &None + )); + std::thread::sleep(std::time::Duration::from_secs(1)); + } + Ok(()) + }); + } + + let u_notifications = self + .listener + .GetNotificationsAsync(NotificationKinds::Toast)? + .get()?; + + for u_notification in u_notifications { + log_error!(self.load_notification(u_notification)); + } + + Ok(()) + } + + pub fn release(&mut self) -> Result<()> { + if let Some(token) = self.event_token.take() { + self.listener.RemoveNotificationChanged(token)?; + } + RELEASED.store(true, Ordering::Release); + Ok(()) + } + + fn internal_notifications_change( + listener: &Option, + _args: &Option, + ) -> windows_core::Result<()> { + if let Some(listener) = listener { + let mut manager = NOTIFICATION_MANAGER.lock(); + let mut current_list = manager.notifications_ids.clone(); + + for u_notification in listener + .GetNotificationsAsync(NotificationKinds::Toast)? + .get()? + { + let id = u_notification.Id()?; + if !current_list.contains(&id) { + manager.emit_event(NotificationEvent::Added(id)); + } + current_list.retain(|x| *x != id); + } + + for id in current_list { + manager.emit_event(NotificationEvent::Removed(id)); + } + } + Ok(()) + } + + pub fn notify_changes(&self) { + for callback in &self.callbacks { + callback(self.notifications()); + } + } + + fn emit_event(&mut self, event: NotificationEvent) { + log_error!(self.process_event(event)); + self.notify_changes(); + } + + fn process_event(&mut self, event: NotificationEvent) -> Result<()> { + match event { + NotificationEvent::Added(id) => { + let u_notification = self.listener.GetNotification(id)?; + self.load_notification(u_notification)?; + } + NotificationEvent::Removed(id) => { + self.notifications.retain(|n| n.id != id); + self.notifications_ids.retain(|x| *x != id); + } + } + Ok(()) + } + + pub fn on_notifications_change(&mut self, callback: F) + where + F: Fn(&Vec) + Send + Sync + 'static, + { + self.callbacks.push(Box::new(callback)); + } + + fn load_notification(&mut self, u_notification: UserNotification) -> Result<()> { + let notification = u_notification.Notification()?; + + let app_info = u_notification.AppInfo()?; + let display_info = app_info.DisplayInfo()?; + + let visuals = notification.Visual()?; + + let text_sequence = visuals + .GetBinding(&KnownNotificationBindings::ToastGeneric()?)? + .GetTextElements()?; + + let mut body = Vec::new(); + for text in text_sequence { + body.push(text.Text()?.to_string()); + } + + self.notifications.push(AppNotification { + id: u_notification.Id()?, + app_logo: None, + app_name: display_info.DisplayName()?.to_string(), + app_description: display_info.Description()?.to_string(), + body, + date: u_notification.CreationTime()?.UniversalTime, + }); + self.notifications_ids.push(u_notification.Id()?); + Ok(()) + } +} diff --git a/src/background/modules/notifications/infrastructure.rs b/src/background/modules/notifications/infrastructure.rs index e4db6cdb..f90c22fd 100644 --- a/src/background/modules/notifications/infrastructure.rs +++ b/src/background/modules/notifications/infrastructure.rs @@ -1,46 +1,46 @@ -use std::sync::atomic::{AtomicBool, Ordering}; - -use tauri::Emitter; - -use crate::{error_handler::Result, log_error, seelen::get_app_handle, trace_lock}; - -use super::application::{AppNotification, NOTIFICATION_MANAGER}; - -fn emit_notifications(notifications: &Vec) { - get_app_handle() - .emit("notifications", notifications) - .expect("failed to emit"); -} - -static REGISTERED: AtomicBool = AtomicBool::new(false); -pub fn register_notification_events() { - let was_registered = REGISTERED.load(Ordering::Acquire); - if !was_registered { - REGISTERED.store(true, Ordering::Release); - } - std::thread::spawn(move || { - let mut manager = trace_lock!(NOTIFICATION_MANAGER); - if !was_registered { - log::trace!("Registering notifications events"); - manager.on_notifications_change(emit_notifications); - } - emit_notifications(manager.notifications()); - }); -} - -pub fn release_notification_events() { - if REGISTERED.load(Ordering::Acquire) { - log_error!(trace_lock!(NOTIFICATION_MANAGER).release()); - } -} - -#[tauri::command] -pub fn notifications_close(id: u32) -> Result<()> { - trace_lock!(NOTIFICATION_MANAGER).remove_notification(id)?; - Ok(()) -} - -#[tauri::command] -pub fn notifications_close_all() -> Result<()> { - trace_lock!(NOTIFICATION_MANAGER).clear_notifications() -} +use std::sync::atomic::{AtomicBool, Ordering}; + +use tauri::Emitter; + +use crate::{error_handler::Result, log_error, seelen::get_app_handle, trace_lock}; + +use super::application::{AppNotification, NOTIFICATION_MANAGER}; + +fn emit_notifications(notifications: &Vec) { + get_app_handle() + .emit("notifications", notifications) + .expect("failed to emit"); +} + +static REGISTERED: AtomicBool = AtomicBool::new(false); +pub fn register_notification_events() { + let was_registered = REGISTERED.load(Ordering::Acquire); + if !was_registered { + REGISTERED.store(true, Ordering::Release); + } + std::thread::spawn(move || { + let mut manager = trace_lock!(NOTIFICATION_MANAGER); + if !was_registered { + log::trace!("Registering notifications events"); + manager.on_notifications_change(emit_notifications); + } + emit_notifications(manager.notifications()); + }); +} + +pub fn release_notification_events() { + if REGISTERED.load(Ordering::Acquire) { + log_error!(trace_lock!(NOTIFICATION_MANAGER).release()); + } +} + +#[tauri::command] +pub fn notifications_close(id: u32) -> Result<()> { + trace_lock!(NOTIFICATION_MANAGER).remove_notification(id)?; + Ok(()) +} + +#[tauri::command] +pub fn notifications_close_all() -> Result<()> { + trace_lock!(NOTIFICATION_MANAGER).clear_notifications() +} diff --git a/src/background/modules/notifications/mod.rs b/src/background/modules/notifications/mod.rs index 83bfcc33..7d6a69bb 100644 --- a/src/background/modules/notifications/mod.rs +++ b/src/background/modules/notifications/mod.rs @@ -1,2 +1,2 @@ -mod application; -pub mod infrastructure; +mod application; +pub mod infrastructure; diff --git a/src/background/modules/power/domain.rs b/src/background/modules/power/domain.rs index ad555272..a58257f6 100644 --- a/src/background/modules/power/domain.rs +++ b/src/background/modules/power/domain.rs @@ -1,85 +1,85 @@ -use serde::Serialize; -use windows::Win32::System::Power::SYSTEM_POWER_STATUS; - -use crate::error_handler::{AppError, Result}; - -#[allow(non_snake_case)] -#[derive(Debug, Clone, Serialize)] -pub struct PowerStatus { - pub ACLineStatus: u8, - pub BatteryFlag: u8, - pub BatteryLifePercent: u8, - pub SystemStatusFlag: u8, - pub BatteryLifeTime: u32, - pub BatteryFullLifeTime: u32, -} - -impl From for PowerStatus { - fn from(power_status: SYSTEM_POWER_STATUS) -> Self { - Self { - ACLineStatus: power_status.ACLineStatus, - BatteryFlag: power_status.BatteryFlag, - BatteryLifePercent: power_status.BatteryLifePercent, - SystemStatusFlag: power_status.SystemStatusFlag, - BatteryLifeTime: power_status.BatteryLifeTime, - BatteryFullLifeTime: power_status.BatteryFullLifeTime, - } - } -} - -#[derive(Debug, Clone, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct Battery { - // static info - vendor: Option, - model: Option, - serial_number: Option, - technology: String, - // common information - state: String, - capacity: f32, - temperature: Option, - percentage: f32, - cycle_count: Option, - smart_charging: bool, // this is triggered by windows idk how but this is a simulation of that - // energy stats - energy: f32, - energy_full: f32, - energy_full_design: f32, - energy_rate: f32, - voltage: f32, - // charge stats - time_to_full: Option, - time_to_empty: Option, -} - -impl TryFrom for Battery { - type Error = AppError; - fn try_from(battery: battery::Battery) -> Result { - let percentage = (battery.state_of_charge().value * 100.0).round(); - - Ok(Self { - vendor: battery.vendor().map(|v| v.to_string()), - model: battery.model().map(|v| v.to_string()), - serial_number: battery.serial_number().map(|v| v.to_string()), - technology: battery.technology().to_string(), - - state: battery.state().to_string(), - capacity: battery.state_of_health().value, - temperature: battery.temperature().map(|t| t.value), - percentage, - cycle_count: battery.cycle_count(), - // smart charging means that battery wont be fully charged. - smart_charging: battery.state() == battery::State::Full && percentage < 100.0, - - energy: battery.energy().value, - energy_full: battery.energy_full().value, - energy_full_design: battery.energy_full_design().value, - energy_rate: battery.energy_rate().value, - voltage: battery.voltage().value, - - time_to_full: battery.time_to_full().map(|t| t.value), - time_to_empty: battery.time_to_empty().map(|t| t.value), - }) - } -} +use serde::Serialize; +use windows::Win32::System::Power::SYSTEM_POWER_STATUS; + +use crate::error_handler::{AppError, Result}; + +#[allow(non_snake_case)] +#[derive(Debug, Clone, Serialize)] +pub struct PowerStatus { + pub ACLineStatus: u8, + pub BatteryFlag: u8, + pub BatteryLifePercent: u8, + pub SystemStatusFlag: u8, + pub BatteryLifeTime: u32, + pub BatteryFullLifeTime: u32, +} + +impl From for PowerStatus { + fn from(power_status: SYSTEM_POWER_STATUS) -> Self { + Self { + ACLineStatus: power_status.ACLineStatus, + BatteryFlag: power_status.BatteryFlag, + BatteryLifePercent: power_status.BatteryLifePercent, + SystemStatusFlag: power_status.SystemStatusFlag, + BatteryLifeTime: power_status.BatteryLifeTime, + BatteryFullLifeTime: power_status.BatteryFullLifeTime, + } + } +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Battery { + // static info + vendor: Option, + model: Option, + serial_number: Option, + technology: String, + // common information + state: String, + capacity: f32, + temperature: Option, + percentage: f32, + cycle_count: Option, + smart_charging: bool, // this is triggered by windows idk how but this is a simulation of that + // energy stats + energy: f32, + energy_full: f32, + energy_full_design: f32, + energy_rate: f32, + voltage: f32, + // charge stats + time_to_full: Option, + time_to_empty: Option, +} + +impl TryFrom for Battery { + type Error = AppError; + fn try_from(battery: battery::Battery) -> Result { + let percentage = (battery.state_of_charge().value * 100.0).round(); + + Ok(Self { + vendor: battery.vendor().map(|v| v.to_string()), + model: battery.model().map(|v| v.to_string()), + serial_number: battery.serial_number().map(|v| v.to_string()), + technology: battery.technology().to_string(), + + state: battery.state().to_string(), + capacity: battery.state_of_health().value, + temperature: battery.temperature().map(|t| t.value), + percentage, + cycle_count: battery.cycle_count(), + // smart charging means that battery wont be fully charged. + smart_charging: battery.state() == battery::State::Full && percentage < 100.0, + + energy: battery.energy().value, + energy_full: battery.energy_full().value, + energy_full_design: battery.energy_full_design().value, + energy_rate: battery.energy_rate().value, + voltage: battery.voltage().value, + + time_to_full: battery.time_to_full().map(|t| t.value), + time_to_empty: battery.time_to_empty().map(|t| t.value), + }) + } +} diff --git a/src/background/modules/power/infrastructure.rs b/src/background/modules/power/infrastructure.rs index 90530b9d..0d5c9e32 100644 --- a/src/background/modules/power/infrastructure.rs +++ b/src/background/modules/power/infrastructure.rs @@ -1,177 +1,177 @@ -use std::sync::atomic::{AtomicBool, Ordering}; - -use tauri::Emitter; -use windows::{ - core::PCWSTR, - Win32::{ - Foundation::{FALSE, HWND, LPARAM, LRESULT, WPARAM}, - Security::{ - AdjustTokenPrivileges, SE_PRIVILEGE_ENABLED, SE_SHUTDOWN_NAME, TOKEN_PRIVILEGES, - }, - System::Shutdown::{EWX_LOGOFF, EWX_REBOOT, EWX_SHUTDOWN, SHTDN_REASON_NONE}, - UI::WindowsAndMessaging::{ - CreateWindowExW, DefWindowProcW, DispatchMessageW, GetMessageW, PostQuitMessage, - RegisterClassW, TranslateMessage, MSG, PBT_APMPOWERSTATUSCHANGE, WINDOW_EX_STYLE, - WINDOW_STYLE, WM_DESTROY, WM_POWERBROADCAST, WNDCLASSW, - }, - }, -}; - -use crate::{ - error_handler::Result, log_error, modules::power::domain::Battery, seelen::get_app_handle, - windows_api::WindowsApi, -}; - -use super::domain::PowerStatus; - -static REGISTERED: AtomicBool = AtomicBool::new(false); - -pub struct PowerManager; -impl PowerManager { - unsafe extern "system" fn window_proc( - hwnd: HWND, - msg: u32, - w_param: WPARAM, - l_param: LPARAM, - ) -> LRESULT { - match msg { - WM_POWERBROADCAST => { - if PBT_APMPOWERSTATUSCHANGE == w_param.0 as u32 { - log_error!(PowerManager::emit_system_power_info()); - } - LRESULT(1) - } - WM_DESTROY => { - PostQuitMessage(0); - LRESULT(0) - } - _ => DefWindowProcW(hwnd, msg, w_param, l_param), - } - } - - pub fn register_power_events() -> Result<()> { - if REGISTERED.load(Ordering::Acquire) { - return Ok(()); - } - log::trace!("Registering system power events"); - - let wide_name: Vec = "Seelen Power Manager" - .encode_utf16() - .chain(Some(0)) - .collect(); - let wide_class: Vec = "SeelenPowerManager".encode_utf16().chain(Some(0)).collect(); - - let h_module = WindowsApi::module_handle_w()?; - - let wnd_class = WNDCLASSW { - lpfnWndProc: Some(Self::window_proc), - hInstance: h_module.into(), - lpszClassName: PCWSTR(wide_class.as_ptr()), - ..Default::default() - }; - - unsafe { - RegisterClassW(&wnd_class); - } - - std::thread::spawn(move || unsafe { - let hwnd = CreateWindowExW( - WINDOW_EX_STYLE::default(), - PCWSTR(wide_class.as_ptr()), - PCWSTR(wide_name.as_ptr()), - WINDOW_STYLE::default(), - 0, - 0, - 0, - 0, - None, - None, - h_module, - None, - ); - - let mut msg = MSG::default(); - while GetMessageW(&mut msg, hwnd, 0, 0).into() { - let _ = TranslateMessage(&msg); - DispatchMessageW(&msg); - } - }); - - // TODO search for a better way to do this, WM_POWERBROADCAST only register status events - // like charging, discharging, battery low, etc. - std::thread::spawn(move || loop { - log_error!(PowerManager::emit_system_power_info()); - std::thread::sleep(std::time::Duration::from_secs(60)); - }); - - REGISTERED.store(true, Ordering::Release); - Ok(()) - } - - pub fn emit_system_power_info() -> Result<()> { - let handle = get_app_handle(); - - let power_status: PowerStatus = WindowsApi::get_system_power_status()?.into(); - handle.emit("power-status", power_status)?; - - let mut batteries: Vec = Vec::new(); - let manager = battery::Manager::new()?; - for battery in manager.batteries()?.flatten() { - batteries.push(battery.try_into()?); - } - - handle.emit("batteries-status", batteries)?; - - Ok(()) - } -} - -#[tauri::command] -pub fn log_out() { - log_error!(WindowsApi::exit_windows(EWX_LOGOFF, SHTDN_REASON_NONE)); -} - -#[tauri::command] -pub fn suspend() { - log_error!(WindowsApi::set_suspend_state()); -} - -#[tauri::command] -pub fn restart() -> Result<(), String> { - let token_handle = WindowsApi::open_process_token()?; - let mut tkp = TOKEN_PRIVILEGES { - PrivilegeCount: 1, - ..Default::default() - }; - - tkp.Privileges[0].Luid = WindowsApi::get_luid(PCWSTR::null(), SE_SHUTDOWN_NAME)?; - tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - - unsafe { - AdjustTokenPrivileges(token_handle, FALSE, Some(&tkp), 0, None, None) - .expect("Could not adjust token privileges"); - } - - WindowsApi::exit_windows(EWX_REBOOT, SHTDN_REASON_NONE)?; - Ok(()) -} - -#[tauri::command] -pub fn shutdown() -> Result<(), String> { - let token_handle = WindowsApi::open_process_token()?; - let mut tkp = TOKEN_PRIVILEGES { - PrivilegeCount: 1, - ..Default::default() - }; - - tkp.Privileges[0].Luid = WindowsApi::get_luid(PCWSTR::null(), SE_SHUTDOWN_NAME)?; - tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - - unsafe { - AdjustTokenPrivileges(token_handle, FALSE, Some(&tkp), 0, None, None) - .expect("Could not adjust token privileges"); - } - - WindowsApi::exit_windows(EWX_SHUTDOWN, SHTDN_REASON_NONE)?; - Ok(()) -} +use std::sync::atomic::{AtomicBool, Ordering}; + +use tauri::Emitter; +use windows::{ + core::PCWSTR, + Win32::{ + Foundation::{FALSE, HWND, LPARAM, LRESULT, WPARAM}, + Security::{ + AdjustTokenPrivileges, SE_PRIVILEGE_ENABLED, SE_SHUTDOWN_NAME, TOKEN_PRIVILEGES, + }, + System::Shutdown::{EWX_LOGOFF, EWX_REBOOT, EWX_SHUTDOWN, SHTDN_REASON_NONE}, + UI::WindowsAndMessaging::{ + CreateWindowExW, DefWindowProcW, DispatchMessageW, GetMessageW, PostQuitMessage, + RegisterClassW, TranslateMessage, MSG, PBT_APMPOWERSTATUSCHANGE, WINDOW_EX_STYLE, + WINDOW_STYLE, WM_DESTROY, WM_POWERBROADCAST, WNDCLASSW, + }, + }, +}; + +use crate::{ + error_handler::Result, log_error, modules::power::domain::Battery, seelen::get_app_handle, + windows_api::WindowsApi, +}; + +use super::domain::PowerStatus; + +static REGISTERED: AtomicBool = AtomicBool::new(false); + +pub struct PowerManager; +impl PowerManager { + unsafe extern "system" fn window_proc( + hwnd: HWND, + msg: u32, + w_param: WPARAM, + l_param: LPARAM, + ) -> LRESULT { + match msg { + WM_POWERBROADCAST => { + if PBT_APMPOWERSTATUSCHANGE == w_param.0 as u32 { + log_error!(PowerManager::emit_system_power_info()); + } + LRESULT(1) + } + WM_DESTROY => { + PostQuitMessage(0); + LRESULT(0) + } + _ => DefWindowProcW(hwnd, msg, w_param, l_param), + } + } + + pub fn register_power_events() -> Result<()> { + if REGISTERED.load(Ordering::Acquire) { + return Ok(()); + } + log::trace!("Registering system power events"); + + let wide_name: Vec = "Seelen Power Manager" + .encode_utf16() + .chain(Some(0)) + .collect(); + let wide_class: Vec = "SeelenPowerManager".encode_utf16().chain(Some(0)).collect(); + + let h_module = WindowsApi::module_handle_w()?; + + let wnd_class = WNDCLASSW { + lpfnWndProc: Some(Self::window_proc), + hInstance: h_module.into(), + lpszClassName: PCWSTR(wide_class.as_ptr()), + ..Default::default() + }; + + unsafe { + RegisterClassW(&wnd_class); + } + + std::thread::spawn(move || unsafe { + let hwnd = CreateWindowExW( + WINDOW_EX_STYLE::default(), + PCWSTR(wide_class.as_ptr()), + PCWSTR(wide_name.as_ptr()), + WINDOW_STYLE::default(), + 0, + 0, + 0, + 0, + None, + None, + h_module, + None, + ); + + let mut msg = MSG::default(); + while GetMessageW(&mut msg, hwnd, 0, 0).into() { + let _ = TranslateMessage(&msg); + DispatchMessageW(&msg); + } + }); + + // TODO search for a better way to do this, WM_POWERBROADCAST only register status events + // like charging, discharging, battery low, etc. + std::thread::spawn(move || loop { + log_error!(PowerManager::emit_system_power_info()); + std::thread::sleep(std::time::Duration::from_secs(60)); + }); + + REGISTERED.store(true, Ordering::Release); + Ok(()) + } + + pub fn emit_system_power_info() -> Result<()> { + let handle = get_app_handle(); + + let power_status: PowerStatus = WindowsApi::get_system_power_status()?.into(); + handle.emit("power-status", power_status)?; + + let mut batteries: Vec = Vec::new(); + let manager = battery::Manager::new()?; + for battery in manager.batteries()?.flatten() { + batteries.push(battery.try_into()?); + } + + handle.emit("batteries-status", batteries)?; + + Ok(()) + } +} + +#[tauri::command] +pub fn log_out() { + log_error!(WindowsApi::exit_windows(EWX_LOGOFF, SHTDN_REASON_NONE)); +} + +#[tauri::command] +pub fn suspend() { + log_error!(WindowsApi::set_suspend_state()); +} + +#[tauri::command] +pub fn restart() -> Result<(), String> { + let token_handle = WindowsApi::open_process_token()?; + let mut tkp = TOKEN_PRIVILEGES { + PrivilegeCount: 1, + ..Default::default() + }; + + tkp.Privileges[0].Luid = WindowsApi::get_luid(PCWSTR::null(), SE_SHUTDOWN_NAME)?; + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + unsafe { + AdjustTokenPrivileges(token_handle, FALSE, Some(&tkp), 0, None, None) + .expect("Could not adjust token privileges"); + } + + WindowsApi::exit_windows(EWX_REBOOT, SHTDN_REASON_NONE)?; + Ok(()) +} + +#[tauri::command] +pub fn shutdown() -> Result<(), String> { + let token_handle = WindowsApi::open_process_token()?; + let mut tkp = TOKEN_PRIVILEGES { + PrivilegeCount: 1, + ..Default::default() + }; + + tkp.Privileges[0].Luid = WindowsApi::get_luid(PCWSTR::null(), SE_SHUTDOWN_NAME)?; + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + unsafe { + AdjustTokenPrivileges(token_handle, FALSE, Some(&tkp), 0, None, None) + .expect("Could not adjust token privileges"); + } + + WindowsApi::exit_windows(EWX_SHUTDOWN, SHTDN_REASON_NONE)?; + Ok(()) +} diff --git a/src/background/modules/power/mod.rs b/src/background/modules/power/mod.rs index 4f06c0ea..b22955aa 100644 --- a/src/background/modules/power/mod.rs +++ b/src/background/modules/power/mod.rs @@ -1,2 +1,2 @@ -pub mod domain; -pub mod infrastructure; +pub mod domain; +pub mod infrastructure; diff --git a/src/background/modules/system_settings/application.rs b/src/background/modules/system_settings/application.rs index c1891b97..ccbb3e5c 100644 --- a/src/background/modules/system_settings/application.rs +++ b/src/background/modules/system_settings/application.rs @@ -1,110 +1,110 @@ -use std::sync::Arc; - -use crate::{error_handler::Result, log_error, trace_lock}; -use lazy_static::lazy_static; -use parking_lot::Mutex; -use windows::{ - Foundation::{EventRegistrationToken, TypedEventHandler}, - UI::ViewManagement::{UIColorType, UISettings}, -}; -use windows_core::IInspectable; - -use super::domain::UIColors; - -lazy_static! { - pub static ref SYSTEM_SETTINGS: Arc> = Arc::new(Mutex::new( - SystemSettings::new().expect("Failed to create settings manager") - )); -} - -fn color_to_string(color: windows::UI::Color) -> String { - format!( - "#{:02X}{:02X}{:02X}{:02X}", - color.R, color.G, color.B, color.A - ) -} - -enum SettingsEvent { - ColorChanged, -} - -type ColorChangeCallback = Box; - -pub struct SystemSettings { - settings: UISettings, - color_event_handler: TypedEventHandler, - color_event_token: Option, - color_client_callbacks: Vec, -} - -unsafe impl Send for SystemSettings {} - -impl SystemSettings { - fn new() -> Result { - let mut settings = Self { - settings: UISettings::new()?, - color_event_handler: TypedEventHandler::new(Self::internal_on_colors_change), - color_event_token: None, - color_client_callbacks: Vec::new(), - }; - settings.init()?; - Ok(settings) - } - - fn init(&mut self) -> Result<()> { - self.color_event_token = Some( - self.settings - .ColorValuesChanged(&self.color_event_handler)?, - ); - Ok(()) - } - - pub fn release(&mut self) -> Result<()> { - self.color_client_callbacks.clear(); - if let Some(token) = self.color_event_token.take() { - self.settings.RemoveColorValuesChanged(token)?; - } - Ok(()) - } - - fn internal_on_colors_change( - _listener: &Option, - _args: &Option, - ) -> windows_core::Result<()> { - log_error!(trace_lock!(SYSTEM_SETTINGS).on_change(SettingsEvent::ColorChanged)); - Ok(()) - } - - pub fn get_colors(&self) -> Result { - let settings = &self.settings; - Ok(UIColors { - background: color_to_string(settings.GetColorValue(UIColorType::Background)?), - foreground: color_to_string(settings.GetColorValue(UIColorType::Foreground)?), - accent_darkest: color_to_string(settings.GetColorValue(UIColorType::AccentDark3)?), - accent_darker: color_to_string(settings.GetColorValue(UIColorType::AccentDark2)?), - accent_dark: color_to_string(settings.GetColorValue(UIColorType::AccentDark1)?), - accent: color_to_string(settings.GetColorValue(UIColorType::Accent)?), - accent_light: color_to_string(settings.GetColorValue(UIColorType::AccentLight1)?), - accent_lighter: color_to_string(settings.GetColorValue(UIColorType::AccentLight2)?), - accent_lightest: color_to_string(settings.GetColorValue(UIColorType::AccentLight3)?), - // https://learn.microsoft.com/is-is/uwp/api/windows.ui.viewmanagement.uisettings.getcolorvalue?view=winrt-19041#remarks - complement: None, - }) - } - - pub fn on_colors_change(&mut self, callback: ColorChangeCallback) { - self.color_client_callbacks.push(callback); - } - - fn on_change(&mut self, event: SettingsEvent) -> Result<()> { - match event { - SettingsEvent::ColorChanged => { - let colors = self.get_colors()?; - for callback in self.color_client_callbacks.iter() { - callback(&colors); - } - } - } - Ok(()) - } -} +use std::sync::Arc; + +use crate::{error_handler::Result, log_error, trace_lock}; +use lazy_static::lazy_static; +use parking_lot::Mutex; +use windows::{ + Foundation::{EventRegistrationToken, TypedEventHandler}, + UI::ViewManagement::{UIColorType, UISettings}, +}; +use windows_core::IInspectable; + +use super::domain::UIColors; + +lazy_static! { + pub static ref SYSTEM_SETTINGS: Arc> = Arc::new(Mutex::new( + SystemSettings::new().expect("Failed to create settings manager") + )); +} + +fn color_to_string(color: windows::UI::Color) -> String { + format!( + "#{:02X}{:02X}{:02X}{:02X}", + color.R, color.G, color.B, color.A + ) +} + +enum SettingsEvent { + ColorChanged, +} + +type ColorChangeCallback = Box; + +pub struct SystemSettings { + settings: UISettings, + color_event_handler: TypedEventHandler, + color_event_token: Option, + color_client_callbacks: Vec, +} + +unsafe impl Send for SystemSettings {} + +impl SystemSettings { + fn new() -> Result { + let mut settings = Self { + settings: UISettings::new()?, + color_event_handler: TypedEventHandler::new(Self::internal_on_colors_change), + color_event_token: None, + color_client_callbacks: Vec::new(), + }; + settings.init()?; + Ok(settings) + } + + fn init(&mut self) -> Result<()> { + self.color_event_token = Some( + self.settings + .ColorValuesChanged(&self.color_event_handler)?, + ); + Ok(()) + } + + pub fn release(&mut self) -> Result<()> { + self.color_client_callbacks.clear(); + if let Some(token) = self.color_event_token.take() { + self.settings.RemoveColorValuesChanged(token)?; + } + Ok(()) + } + + fn internal_on_colors_change( + _listener: &Option, + _args: &Option, + ) -> windows_core::Result<()> { + log_error!(trace_lock!(SYSTEM_SETTINGS).on_change(SettingsEvent::ColorChanged)); + Ok(()) + } + + pub fn get_colors(&self) -> Result { + let settings = &self.settings; + Ok(UIColors { + background: color_to_string(settings.GetColorValue(UIColorType::Background)?), + foreground: color_to_string(settings.GetColorValue(UIColorType::Foreground)?), + accent_darkest: color_to_string(settings.GetColorValue(UIColorType::AccentDark3)?), + accent_darker: color_to_string(settings.GetColorValue(UIColorType::AccentDark2)?), + accent_dark: color_to_string(settings.GetColorValue(UIColorType::AccentDark1)?), + accent: color_to_string(settings.GetColorValue(UIColorType::Accent)?), + accent_light: color_to_string(settings.GetColorValue(UIColorType::AccentLight1)?), + accent_lighter: color_to_string(settings.GetColorValue(UIColorType::AccentLight2)?), + accent_lightest: color_to_string(settings.GetColorValue(UIColorType::AccentLight3)?), + // https://learn.microsoft.com/is-is/uwp/api/windows.ui.viewmanagement.uisettings.getcolorvalue?view=winrt-19041#remarks + complement: None, + }) + } + + pub fn on_colors_change(&mut self, callback: ColorChangeCallback) { + self.color_client_callbacks.push(callback); + } + + fn on_change(&mut self, event: SettingsEvent) -> Result<()> { + match event { + SettingsEvent::ColorChanged => { + let colors = self.get_colors()?; + for callback in self.color_client_callbacks.iter() { + callback(&colors); + } + } + } + Ok(()) + } +} diff --git a/src/background/modules/system_settings/domain.rs b/src/background/modules/system_settings/domain.rs index 2dd6affd..27b92e5c 100644 --- a/src/background/modules/system_settings/domain.rs +++ b/src/background/modules/system_settings/domain.rs @@ -1,16 +1,16 @@ -use serde::Serialize; - -/// https://learn.microsoft.com/is-is/uwp/api/windows.ui.viewmanagement.uicolortype?view=winrt-19041 -#[derive(Debug, Default, Serialize)] -pub struct UIColors { - pub background: String, - pub foreground: String, - pub accent_darkest: String, - pub accent_darker: String, - pub accent_dark: String, - pub accent: String, - pub accent_light: String, - pub accent_lighter: String, - pub accent_lightest: String, - pub complement: Option, -} +use serde::Serialize; + +/// https://learn.microsoft.com/is-is/uwp/api/windows.ui.viewmanagement.uicolortype?view=winrt-19041 +#[derive(Debug, Default, Serialize)] +pub struct UIColors { + pub background: String, + pub foreground: String, + pub accent_darkest: String, + pub accent_darker: String, + pub accent_dark: String, + pub accent: String, + pub accent_light: String, + pub accent_lighter: String, + pub accent_lightest: String, + pub complement: Option, +} diff --git a/src/background/modules/system_settings/infrastructure.rs b/src/background/modules/system_settings/infrastructure.rs index 1fee71e0..a8922bbc 100644 --- a/src/background/modules/system_settings/infrastructure.rs +++ b/src/background/modules/system_settings/infrastructure.rs @@ -1,35 +1,35 @@ -use std::sync::atomic::{AtomicBool, Ordering}; - -use tauri::Emitter; - -use crate::{log_error, seelen::get_app_handle, trace_lock}; - -use super::{application::SYSTEM_SETTINGS, domain::UIColors}; - -fn emit_colors(colors: &UIColors) { - get_app_handle() - .emit("colors", colors) - .expect("failed to emit"); -} - -static REGISTERED: AtomicBool = AtomicBool::new(false); -pub fn register_colors_events() { - let was_registered = REGISTERED.load(Ordering::Acquire); - if !was_registered { - REGISTERED.store(true, Ordering::Release); - } - std::thread::spawn(move || { - let mut manager = trace_lock!(SYSTEM_SETTINGS); - if !was_registered { - log::trace!("Registering colors events"); - manager.on_colors_change(Box::new(emit_colors)); - } - emit_colors(&manager.get_colors().expect("Failed to get colors")); - }); -} - -pub fn release_colors_events() { - if REGISTERED.load(Ordering::Acquire) { - log_error!(trace_lock!(SYSTEM_SETTINGS).release()); - } -} +use std::sync::atomic::{AtomicBool, Ordering}; + +use tauri::Emitter; + +use crate::{log_error, seelen::get_app_handle, trace_lock}; + +use super::{application::SYSTEM_SETTINGS, domain::UIColors}; + +fn emit_colors(colors: &UIColors) { + get_app_handle() + .emit("colors", colors) + .expect("failed to emit"); +} + +static REGISTERED: AtomicBool = AtomicBool::new(false); +pub fn register_colors_events() { + let was_registered = REGISTERED.load(Ordering::Acquire); + if !was_registered { + REGISTERED.store(true, Ordering::Release); + } + std::thread::spawn(move || { + let mut manager = trace_lock!(SYSTEM_SETTINGS); + if !was_registered { + log::trace!("Registering colors events"); + manager.on_colors_change(Box::new(emit_colors)); + } + emit_colors(&manager.get_colors().expect("Failed to get colors")); + }); +} + +pub fn release_colors_events() { + if REGISTERED.load(Ordering::Acquire) { + log_error!(trace_lock!(SYSTEM_SETTINGS).release()); + } +} diff --git a/src/background/modules/system_settings/mod.rs b/src/background/modules/system_settings/mod.rs index 426629b8..522b894c 100644 --- a/src/background/modules/system_settings/mod.rs +++ b/src/background/modules/system_settings/mod.rs @@ -1,3 +1,3 @@ -mod application; -mod domain; -pub mod infrastructure; +mod application; +mod domain; +pub mod infrastructure; diff --git a/src/background/modules/tray/application.rs b/src/background/modules/tray/application.rs index 77612a43..966acb7c 100644 --- a/src/background/modules/tray/application.rs +++ b/src/background/modules/tray/application.rs @@ -1,266 +1,266 @@ -use itertools::Itertools; -use windows::Win32::{ - Foundation::{HWND, POINT, RECT}, - UI::{ - Accessibility::{ - CUIAutomation, IUIAutomation, IUIAutomationCondition, IUIAutomationElement, - IUIAutomationInvokePattern, TreeScope, TreeScope_Descendants, TreeScope_Subtree, - UIA_InvokePatternId, - }, - WindowsAndMessaging::{FindWindowA, FindWindowExA, GetCursorPos, SW_SHOW}, - }, -}; -use winreg::{ - enums::{HKEY_CURRENT_USER, KEY_ALL_ACCESS}, - RegKey, -}; - -use crate::{ - error_handler::Result, - modules::input::Keyboard, - pcstr, - seelen::get_app_handle, - seelen_weg::icon_extractor::extract_and_save_icon, - utils::{is_windows_10, is_windows_11, resolve_guid_path, sleep_millis}, - windows_api::{AppBarData, AppBarDataState, Com, WindowsApi}, -}; - -use super::domain::{RegistryNotifyIcon, TrayIcon, TrayIconInfo}; - -pub fn get_sub_tree( - element: &IUIAutomationElement, - condition: &IUIAutomationCondition, - scope: TreeScope, -) -> Result> { - let mut elements = Vec::new(); - unsafe { - let element_array = element.FindAll(scope, condition)?; - for index in 0..element_array.Length()? { - let element = element_array.GetElement(index)?; - elements.push(element); - } - } - Ok(elements) -} - -// force_tray_overflow_creation should be called before get_tray_handle -// https://learn.microsoft.com/en-us/answers/questions/1483214/win11-22h2-(10-0-22621)-cant-support-tb-buttoncount -pub fn get_tray_overflow_handle() -> HWND { - unsafe { - if is_windows_10() { - let tray_overflow = FindWindowA(pcstr!("NotifyIconOverFlowWindow"), None); - FindWindowExA(tray_overflow, HWND(0), pcstr!("ToolbarWindow32"), None) - } else { - let tray_overflow = FindWindowA(pcstr!("TopLevelWindowForOverflowXamlIsland"), None); - FindWindowExA( - tray_overflow, - HWND(0), - None, - pcstr!("DesktopWindowXamlSource"), - ) - } - } -} - -pub fn ensure_tray_overflow_creation() -> Result<()> { - if !is_windows_11() { - return Ok(()); - } - - let tray_overflow_hwnd = get_tray_overflow_handle(); - if tray_overflow_hwnd.0 != 0 { - return Ok(()); - } - - Com::run_with_context(|| unsafe { - let tray_hwnd = FindWindowA(pcstr!("Shell_TrayWnd"), None); - - let tray_bar = AppBarData::from_handle(tray_hwnd); - let tray_bar_state = tray_bar.state(); - // This function will fail if taskbar is hidden - tray_bar.set_state(AppBarDataState::AlwaysOnTop); - WindowsApi::show_window(tray_hwnd, SW_SHOW)?; - - let automation: IUIAutomation = Com::create_instance(&CUIAutomation)?; - let condition = automation.CreateTrueCondition()?; - let element: IUIAutomationElement = automation.ElementFromHandle(tray_hwnd)?; - - let element_array = element.FindAll(TreeScope_Subtree, &condition)?; - for index in 0..element_array.Length().unwrap_or(0) { - let element = element_array.GetElement(index)?; - if element.CurrentName()? == "Show Hidden Icons" - && element.CurrentAutomationId()? == "SystemTrayIcon" - { - let invoker = element - .GetCurrentPatternAs::(UIA_InvokePatternId)?; - // open and close the tray to force the creation of the overflow list - invoker.Invoke()?; - sleep_millis(10); - invoker.Invoke()?; - - tray_bar.set_state(tray_bar_state); - return Ok(()); - } - } - - tray_bar.set_state(tray_bar_state); - Err("Failed to force tray overflow creation".into()) - }) -} - -pub fn get_tray_icons() -> Result> { - ensure_tray_overflow_creation()?; - let tray_from_registry = TrayIcon::enum_from_registry().unwrap_or_default(); - - Com::run_with_context(|| unsafe { - let mut tray_elements = Vec::new(); - - let automation: IUIAutomation = Com::create_instance(&CUIAutomation)?; - let condition = automation.CreateTrueCondition()?; - - let mut children = Vec::new(); - - let tray_overflow = get_tray_overflow_handle(); - if tray_overflow.0 != 0 { - let element: IUIAutomationElement = automation.ElementFromHandle(tray_overflow)?; - children.extend(get_sub_tree(&element, &condition, TreeScope_Descendants)?); - } - - let is_win10 = is_windows_10(); - for element in children { - let name = element.CurrentName()?.to_string(); - if !name.is_empty() && (is_win10 || element.CurrentAutomationId()? == "NotifyItemIcon") - { - let registry = tray_from_registry.iter().find(|t| { - let trimmed = name.trim(); - t.initial_tooltip == trimmed - || t.executable_path - .to_lowercase() - .contains(&trimmed.to_lowercase()) - }); - - tray_elements.push(TrayIcon { - ui_automation: element, - registry: registry.cloned(), - }); - } - } - - Ok(tray_elements) - }) -} - -impl TrayIcon { - pub fn info(&self) -> TrayIconInfo { - TrayIconInfo { - icon: self.icon().ok(), - label: self.name().unwrap_or("Unknown".to_string()), - } - } - - pub fn name(&self) -> Result { - Ok(unsafe { self.ui_automation.CurrentName() }?.to_string()) - } - - pub fn icon(&self) -> Result { - if self.registry.is_none() { - return Err("Registry icon not found".into()); - } - - let path = self.registry.as_ref().unwrap().executable_path.clone(); - let icon = extract_and_save_icon(&get_app_handle(), &path)?; - Ok(icon - .to_string_lossy() - .trim_start_matches("\\\\?\\") - .to_string()) - } - - pub fn invoke(&self) -> Result<()> { - unsafe { - let invoker = self - .ui_automation - .GetCurrentPatternAs::(UIA_InvokePatternId)?; - invoker.Invoke()?; - } - Ok(()) - } - - pub fn context_menu(&self) -> Result<()> { - let element = &self.ui_automation; - let mut cursor_pos = POINT::default(); - unsafe { GetCursorPos(&mut cursor_pos as *mut POINT)? }; - - let hwnd = unsafe { FindWindowA(None, pcstr!("System tray overflow window.")) }; - - WindowsApi::show_window(hwnd, SW_SHOW)?; - WindowsApi::move_window( - hwnd, - &RECT { - top: cursor_pos.y, - left: cursor_pos.x, - right: 0, - bottom: 0, - }, - )?; - - unsafe { element.SetFocus()? }; - Keyboard::new().send_keys("{apps}")?; - - Ok(()) - } - - pub fn enum_from_registry() -> Result> { - let hkcr = RegKey::predef(HKEY_CURRENT_USER); - let settings = hkcr.open_subkey("Control Panel\\NotifyIconSettings")?; - let list = settings.get_raw_value("UIOrderList")?; - - // the order in this list is the order in which the icons will be displayed on the Win Taskbar and Win Tray Overflow - let ids = list - .bytes - .chunks_exact(8) - .map(|chunk| { - u64::from_le_bytes(chunk.try_into().expect("Registry value is not 8 bytes")) - }) - .collect_vec(); - - let mut registers = Vec::new(); - - let sys = sysinfo::System::new_all(); - let mut processes_string = Vec::new(); - sys.processes().values().for_each(|p| { - if let Some(exe) = p.exe() { - processes_string.push(exe.to_string_lossy().to_string().to_lowercase()); - } - }); - - for id in ids { - let key = settings.open_subkey_with_flags(id.to_string(), KEY_ALL_ACCESS)?; - - let promoted: u32 = key.get_value("IsPromoted").unwrap_or_default(); - if promoted == 1 && WindowsApi::is_elevated()? { - // avoid show tray icons directly on taskbar - // all icons should be in the tray overflow window - key.set_value("IsPromoted", &0u32)?; - } - - if key.get_raw_value("IconGuid").is_ok() { - // TODO: Handle Tray Icons like USB devices, Security tray, etc - continue; - }; - - // executable path should always exist in registry - let path: String = key.get_value("ExecutablePath")?; - let executable_path = resolve_guid_path(path)?.to_string_lossy().to_string(); - - let is_executing = processes_string.contains(&executable_path.to_lowercase()); - if is_executing { - registers.push(RegistryNotifyIcon { - executable_path, - initial_tooltip: key.get_value("InitialTooltip").unwrap_or_default(), - }) - } - } - - Ok(registers) - } -} +use itertools::Itertools; +use windows::Win32::{ + Foundation::{HWND, POINT, RECT}, + UI::{ + Accessibility::{ + CUIAutomation, IUIAutomation, IUIAutomationCondition, IUIAutomationElement, + IUIAutomationInvokePattern, TreeScope, TreeScope_Descendants, TreeScope_Subtree, + UIA_InvokePatternId, + }, + WindowsAndMessaging::{FindWindowA, FindWindowExA, GetCursorPos, SW_SHOW}, + }, +}; +use winreg::{ + enums::{HKEY_CURRENT_USER, KEY_ALL_ACCESS}, + RegKey, +}; + +use crate::{ + error_handler::Result, + modules::input::Keyboard, + pcstr, + seelen::get_app_handle, + seelen_weg::icon_extractor::extract_and_save_icon, + utils::{is_windows_10, is_windows_11, resolve_guid_path, sleep_millis}, + windows_api::{AppBarData, AppBarDataState, Com, WindowsApi}, +}; + +use super::domain::{RegistryNotifyIcon, TrayIcon, TrayIconInfo}; + +pub fn get_sub_tree( + element: &IUIAutomationElement, + condition: &IUIAutomationCondition, + scope: TreeScope, +) -> Result> { + let mut elements = Vec::new(); + unsafe { + let element_array = element.FindAll(scope, condition)?; + for index in 0..element_array.Length()? { + let element = element_array.GetElement(index)?; + elements.push(element); + } + } + Ok(elements) +} + +// force_tray_overflow_creation should be called before get_tray_handle +// https://learn.microsoft.com/en-us/answers/questions/1483214/win11-22h2-(10-0-22621)-cant-support-tb-buttoncount +pub fn get_tray_overflow_handle() -> HWND { + unsafe { + if is_windows_10() { + let tray_overflow = FindWindowA(pcstr!("NotifyIconOverFlowWindow"), None); + FindWindowExA(tray_overflow, HWND(0), pcstr!("ToolbarWindow32"), None) + } else { + let tray_overflow = FindWindowA(pcstr!("TopLevelWindowForOverflowXamlIsland"), None); + FindWindowExA( + tray_overflow, + HWND(0), + None, + pcstr!("DesktopWindowXamlSource"), + ) + } + } +} + +pub fn ensure_tray_overflow_creation() -> Result<()> { + if !is_windows_11() { + return Ok(()); + } + + let tray_overflow_hwnd = get_tray_overflow_handle(); + if tray_overflow_hwnd.0 != 0 { + return Ok(()); + } + + Com::run_with_context(|| unsafe { + let tray_hwnd = FindWindowA(pcstr!("Shell_TrayWnd"), None); + + let tray_bar = AppBarData::from_handle(tray_hwnd); + let tray_bar_state = tray_bar.state(); + // This function will fail if taskbar is hidden + tray_bar.set_state(AppBarDataState::AlwaysOnTop); + WindowsApi::show_window(tray_hwnd, SW_SHOW)?; + + let automation: IUIAutomation = Com::create_instance(&CUIAutomation)?; + let condition = automation.CreateTrueCondition()?; + let element: IUIAutomationElement = automation.ElementFromHandle(tray_hwnd)?; + + let element_array = element.FindAll(TreeScope_Subtree, &condition)?; + for index in 0..element_array.Length().unwrap_or(0) { + let element = element_array.GetElement(index)?; + if element.CurrentName()? == "Show Hidden Icons" + && element.CurrentAutomationId()? == "SystemTrayIcon" + { + let invoker = element + .GetCurrentPatternAs::(UIA_InvokePatternId)?; + // open and close the tray to force the creation of the overflow list + invoker.Invoke()?; + sleep_millis(10); + invoker.Invoke()?; + + tray_bar.set_state(tray_bar_state); + return Ok(()); + } + } + + tray_bar.set_state(tray_bar_state); + Err("Failed to force tray overflow creation".into()) + }) +} + +pub fn get_tray_icons() -> Result> { + ensure_tray_overflow_creation()?; + let tray_from_registry = TrayIcon::enum_from_registry().unwrap_or_default(); + + Com::run_with_context(|| unsafe { + let mut tray_elements = Vec::new(); + + let automation: IUIAutomation = Com::create_instance(&CUIAutomation)?; + let condition = automation.CreateTrueCondition()?; + + let mut children = Vec::new(); + + let tray_overflow = get_tray_overflow_handle(); + if tray_overflow.0 != 0 { + let element: IUIAutomationElement = automation.ElementFromHandle(tray_overflow)?; + children.extend(get_sub_tree(&element, &condition, TreeScope_Descendants)?); + } + + let is_win10 = is_windows_10(); + for element in children { + let name = element.CurrentName()?.to_string(); + if !name.is_empty() && (is_win10 || element.CurrentAutomationId()? == "NotifyItemIcon") + { + let registry = tray_from_registry.iter().find(|t| { + let trimmed = name.trim(); + t.initial_tooltip == trimmed + || t.executable_path + .to_lowercase() + .contains(&trimmed.to_lowercase()) + }); + + tray_elements.push(TrayIcon { + ui_automation: element, + registry: registry.cloned(), + }); + } + } + + Ok(tray_elements) + }) +} + +impl TrayIcon { + pub fn info(&self) -> TrayIconInfo { + TrayIconInfo { + icon: self.icon().ok(), + label: self.name().unwrap_or("Unknown".to_string()), + } + } + + pub fn name(&self) -> Result { + Ok(unsafe { self.ui_automation.CurrentName() }?.to_string()) + } + + pub fn icon(&self) -> Result { + if self.registry.is_none() { + return Err("Registry icon not found".into()); + } + + let path = self.registry.as_ref().unwrap().executable_path.clone(); + let icon = extract_and_save_icon(&get_app_handle(), &path)?; + Ok(icon + .to_string_lossy() + .trim_start_matches("\\\\?\\") + .to_string()) + } + + pub fn invoke(&self) -> Result<()> { + unsafe { + let invoker = self + .ui_automation + .GetCurrentPatternAs::(UIA_InvokePatternId)?; + invoker.Invoke()?; + } + Ok(()) + } + + pub fn context_menu(&self) -> Result<()> { + let element = &self.ui_automation; + let mut cursor_pos = POINT::default(); + unsafe { GetCursorPos(&mut cursor_pos as *mut POINT)? }; + + let hwnd = unsafe { FindWindowA(None, pcstr!("System tray overflow window.")) }; + + WindowsApi::show_window(hwnd, SW_SHOW)?; + WindowsApi::move_window( + hwnd, + &RECT { + top: cursor_pos.y, + left: cursor_pos.x, + right: 0, + bottom: 0, + }, + )?; + + unsafe { element.SetFocus()? }; + Keyboard::new().send_keys("{apps}")?; + + Ok(()) + } + + pub fn enum_from_registry() -> Result> { + let hkcr = RegKey::predef(HKEY_CURRENT_USER); + let settings = hkcr.open_subkey("Control Panel\\NotifyIconSettings")?; + let list = settings.get_raw_value("UIOrderList")?; + + // the order in this list is the order in which the icons will be displayed on the Win Taskbar and Win Tray Overflow + let ids = list + .bytes + .chunks_exact(8) + .map(|chunk| { + u64::from_le_bytes(chunk.try_into().expect("Registry value is not 8 bytes")) + }) + .collect_vec(); + + let mut registers = Vec::new(); + + let sys = sysinfo::System::new_all(); + let mut processes_string = Vec::new(); + sys.processes().values().for_each(|p| { + if let Some(exe) = p.exe() { + processes_string.push(exe.to_string_lossy().to_string().to_lowercase()); + } + }); + + for id in ids { + let key = settings.open_subkey_with_flags(id.to_string(), KEY_ALL_ACCESS)?; + + let promoted: u32 = key.get_value("IsPromoted").unwrap_or_default(); + if promoted == 1 && WindowsApi::is_elevated()? { + // avoid show tray icons directly on taskbar + // all icons should be in the tray overflow window + key.set_value("IsPromoted", &0u32)?; + } + + if key.get_raw_value("IconGuid").is_ok() { + // TODO: Handle Tray Icons like USB devices, Security tray, etc + continue; + }; + + // executable path should always exist in registry + let path: String = key.get_value("ExecutablePath")?; + let executable_path = resolve_guid_path(path)?.to_string_lossy().to_string(); + + let is_executing = processes_string.contains(&executable_path.to_lowercase()); + if is_executing { + registers.push(RegistryNotifyIcon { + executable_path, + initial_tooltip: key.get_value("InitialTooltip").unwrap_or_default(), + }) + } + } + + Ok(registers) + } +} diff --git a/src/background/modules/tray/domain.rs b/src/background/modules/tray/domain.rs index 6394df85..ed38c5d3 100644 --- a/src/background/modules/tray/domain.rs +++ b/src/background/modules/tray/domain.rs @@ -1,19 +1,19 @@ -use serde::Serialize; -use windows::Win32::UI::Accessibility::IUIAutomationElement; - -#[derive(Debug, Clone, Serialize)] -pub struct TrayIconInfo { - pub icon: Option, - pub label: String, -} - -pub struct TrayIcon { - pub ui_automation: IUIAutomationElement, - pub registry: Option, -} - -#[derive(Debug, Clone)] -pub struct RegistryNotifyIcon { - pub executable_path: String, - pub initial_tooltip: String, -} +use serde::Serialize; +use windows::Win32::UI::Accessibility::IUIAutomationElement; + +#[derive(Debug, Clone, Serialize)] +pub struct TrayIconInfo { + pub icon: Option, + pub label: String, +} + +pub struct TrayIcon { + pub ui_automation: IUIAutomationElement, + pub registry: Option, +} + +#[derive(Debug, Clone)] +pub struct RegistryNotifyIcon { + pub executable_path: String, + pub initial_tooltip: String, +} diff --git a/src/background/modules/tray/infrastructure.rs b/src/background/modules/tray/infrastructure.rs index 6d9798a5..9669ede6 100644 --- a/src/background/modules/tray/infrastructure.rs +++ b/src/background/modules/tray/infrastructure.rs @@ -1,49 +1,49 @@ -use std::sync::atomic::{AtomicBool, Ordering}; - -use itertools::Itertools; -use tauri::Emitter; - -use crate::{ - error_handler::Result, log_error, modules::tray::application::get_tray_icons, - seelen::get_app_handle, -}; - -fn emit_tray_info() -> Result<()> { - let handle = get_app_handle(); - let payload = get_tray_icons()?.iter().map(|t| t.info()).collect_vec(); - handle.emit("tray-info", payload)?; - Ok(()) -} - -static REGISTERED: AtomicBool = AtomicBool::new(false); -pub fn register_tray_events() -> Result<()> { - if !REGISTERED.load(Ordering::Acquire) { - log::trace!("Registering tray events"); - // TODO: add event listener for tray events - REGISTERED.store(true, Ordering::Release); - } - emit_tray_info()?; - Ok(()) -} - -// TODO: remove when add event listener for tray events -#[tauri::command] -pub fn temp_get_by_event_tray_info() { - log_error!(emit_tray_info()); -} - -#[tauri::command] -pub fn on_click_tray_icon(idx: usize) -> Result<()> { - let icons = get_tray_icons()?; - let icon = icons.get(idx).ok_or("tray icon index out of bounds")?; - icon.invoke()?; - Ok(()) -} - -#[tauri::command] -pub fn on_context_menu_tray_icon(idx: usize) -> Result<()> { - let icons = get_tray_icons()?; - let icon = icons.get(idx).ok_or("tray icon index out of bounds")?; - icon.context_menu()?; - Ok(()) -} +use std::sync::atomic::{AtomicBool, Ordering}; + +use itertools::Itertools; +use tauri::Emitter; + +use crate::{ + error_handler::Result, log_error, modules::tray::application::get_tray_icons, + seelen::get_app_handle, +}; + +fn emit_tray_info() -> Result<()> { + let handle = get_app_handle(); + let payload = get_tray_icons()?.iter().map(|t| t.info()).collect_vec(); + handle.emit("tray-info", payload)?; + Ok(()) +} + +static REGISTERED: AtomicBool = AtomicBool::new(false); +pub fn register_tray_events() -> Result<()> { + if !REGISTERED.load(Ordering::Acquire) { + log::trace!("Registering tray events"); + // TODO: add event listener for tray events + REGISTERED.store(true, Ordering::Release); + } + emit_tray_info()?; + Ok(()) +} + +// TODO: remove when add event listener for tray events +#[tauri::command] +pub fn temp_get_by_event_tray_info() { + log_error!(emit_tray_info()); +} + +#[tauri::command] +pub fn on_click_tray_icon(idx: usize) -> Result<()> { + let icons = get_tray_icons()?; + let icon = icons.get(idx).ok_or("tray icon index out of bounds")?; + icon.invoke()?; + Ok(()) +} + +#[tauri::command] +pub fn on_context_menu_tray_icon(idx: usize) -> Result<()> { + let icons = get_tray_icons()?; + let icon = icons.get(idx).ok_or("tray icon index out of bounds")?; + icon.context_menu()?; + Ok(()) +} diff --git a/src/background/modules/tray/mod.rs b/src/background/modules/tray/mod.rs index 50d07953..c347d7e3 100644 --- a/src/background/modules/tray/mod.rs +++ b/src/background/modules/tray/mod.rs @@ -1,3 +1,3 @@ -pub mod application; -pub mod domain; -pub mod infrastructure; +pub mod application; +pub mod domain; +pub mod infrastructure; diff --git a/src/background/modules/uwp/load_uwp_apps.ps1 b/src/background/modules/uwp/load_uwp_apps.ps1 index b5339105..7d7aa28a 100644 --- a/src/background/modules/uwp/load_uwp_apps.ps1 +++ b/src/background/modules/uwp/load_uwp_apps.ps1 @@ -1,59 +1,59 @@ -$packages = Get-AppxPackage -$output = @() - -foreach ($package in $packages) { - $manifest = Get-AppxPackageManifest -Package $package.PackageFullName - - $applications = @() - foreach ($app in $manifest.Package.Applications.Application) { - if ($null -eq $app.Executable) { - continue - } - - $alias = $null - if ($app.Extensions.Extension) { - foreach ($extension in $app.Extensions.Extension) { - if ($extension.Category -eq "windows.appExecutionAlias" -and $extension.AppExecutionAlias) { - foreach ($executionAlias in $extension.AppExecutionAlias.ExecutionAlias) { - if ($executionAlias.Alias) { - $alias = $executionAlias.Alias - break - } - } - } - } - } - - $applications += [PSCustomObject]@{ - AppId = $app.Id - Executable = $app.Executable - Alias = $alias - Square150x150Logo = $app.VisualElements.Square150x150Logo - Square44x44Logo = $app.VisualElements.Square44x44Logo - } - } - - if ($applications.Count -eq 0) { - continue - } - - # Resolve install location in case it's a symlink - $resolvedInstallLocation = (Get-Item -Path $package.InstallLocation).Target[0] - if ($null -eq $resolvedInstallLocation) { - $resolvedInstallLocation = $package.InstallLocation - } - - $selected = [PSCustomObject]@{ - Name = $package.Name - Version = $package.Version - PublisherId = $package.PublisherId - PackageFullName = $package.PackageFullName - InstallLocation = $resolvedInstallLocation.TrimEnd('\') - StoreLogo = $manifest.Package.Properties.Logo - Applications = $applications - } - - $output += $selected -} - +$packages = Get-AppxPackage +$output = @() + +foreach ($package in $packages) { + $manifest = Get-AppxPackageManifest -Package $package.PackageFullName + + $applications = @() + foreach ($app in $manifest.Package.Applications.Application) { + if ($null -eq $app.Executable) { + continue + } + + $alias = $null + if ($app.Extensions.Extension) { + foreach ($extension in $app.Extensions.Extension) { + if ($extension.Category -eq "windows.appExecutionAlias" -and $extension.AppExecutionAlias) { + foreach ($executionAlias in $extension.AppExecutionAlias.ExecutionAlias) { + if ($executionAlias.Alias) { + $alias = $executionAlias.Alias + break + } + } + } + } + } + + $applications += [PSCustomObject]@{ + AppId = $app.Id + Executable = $app.Executable + Alias = $alias + Square150x150Logo = $app.VisualElements.Square150x150Logo + Square44x44Logo = $app.VisualElements.Square44x44Logo + } + } + + if ($applications.Count -eq 0) { + continue + } + + # Resolve install location in case it's a symlink + $resolvedInstallLocation = (Get-Item -Path $package.InstallLocation).Target[0] + if ($null -eq $resolvedInstallLocation) { + $resolvedInstallLocation = $package.InstallLocation + } + + $selected = [PSCustomObject]@{ + Name = $package.Name + Version = $package.Version + PublisherId = $package.PublisherId + PackageFullName = $package.PackageFullName + InstallLocation = $resolvedInstallLocation.TrimEnd('\') + StoreLogo = $manifest.Package.Properties.Logo + Applications = $applications + } + + $output += $selected +} + $output | ConvertTo-Json -Depth 3 -Compress \ No newline at end of file diff --git a/src/background/modules/uwp/mod.rs b/src/background/modules/uwp/mod.rs index 75b539e5..1fc4c46f 100644 --- a/src/background/modules/uwp/mod.rs +++ b/src/background/modules/uwp/mod.rs @@ -1,174 +1,174 @@ -use lazy_static::lazy_static; -use parking_lot::Mutex; -use serde::Deserialize; -use std::{ - path::{Path, PathBuf}, - sync::Arc, -}; -use tauri::Manager; - -use crate::{error_handler::Result, seelen::get_app_handle, utils::pwsh::PwshScript}; - -pub static UWP_LIGHTUNPLATED_POSTFIX: &str = "_altform-lightunplated"; -#[allow(dead_code)] -pub static UWP_UNPLATED_POSTFIX: &str = "_altform-unplated"; - -lazy_static! { - pub static ref UWP_MANAGER: Arc> = Arc::new(Mutex::new({ - let mut manager = WindowsAppsManager::default(); - manager.refresh().expect("Failed to refresh UWP manager"); - manager - })); - pub static ref UWP_TARGET_SIZE_POSTFIXES: Vec<&'static str> = vec![ - ".targetsize-256", - ".targetsize-96", - ".targetsize-64", - ".targetsize-48", - ".targetsize-32", - ]; - pub static ref UWP_SCALE_POSTFIXES: Vec<&'static str> = vec![ - ".scale-400", - ".scale-200", - ".scale-150", - ".scale-125", - ".scale-100", - ]; -} - -#[derive(Deserialize, Debug, Default)] -#[serde(rename_all = "PascalCase")] -#[allow(dead_code)] -pub struct UWPPackage { - name: String, - version: String, - publisher_id: String, - package_full_name: String, - install_location: PathBuf, - store_logo: Option, - applications: Vec, -} - -#[derive(Deserialize, Debug, Default)] -#[serde(rename_all = "PascalCase")] -pub struct UWPApplication { - app_id: String, - /// subpath from UWPPackage.install_location - executable: String, - alias: Option, - /// subpath from UWPPackage.install_location - square150x150_logo: Option, - // subpath from UWPPackage.install_location - square44x44_logo: Option, -} - -impl UWPApplication { - pub fn get_44_icon(&self) -> Option<&String> { - self.square44x44_logo.as_ref() - } - - pub fn get_150_icon(&self) -> Option<&String> { - self.square150x150_logo.as_ref() - } -} - -impl UWPPackage { - pub fn get_store_logo(&self) -> Option<&String> { - self.store_logo.as_ref() - } - - pub fn get_app(&self, exe: &str) -> Option<&UWPApplication> { - self.applications - .iter() - .find(|app| app.executable.ends_with(exe) || app.alias.as_deref() == Some(exe)) - } - - pub fn get_light_icon_path(icon_path: &Path) -> Option { - let filename = icon_path.file_stem()?.to_str()?; - let extension = icon_path.extension()?.to_str()?; - - let postfixes = (*UWP_TARGET_SIZE_POSTFIXES) - .iter() - .chain((*UWP_SCALE_POSTFIXES).iter()); - - for postfix in postfixes { - let maybe_icon_path = icon_path.with_file_name(format!( - "{}{}{}.{}", - filename, postfix, UWP_LIGHTUNPLATED_POSTFIX, extension - )); - if maybe_icon_path.exists() { - return Some(maybe_icon_path); - } - - let maybe_icon_path = - icon_path.with_file_name(format!("{}{}.{}", filename, postfix, extension)); - if maybe_icon_path.exists() { - return Some(maybe_icon_path); - } - } - - // Some apps only adds one icon and without any postfix - // but we prefer the light/dark specific icon - if icon_path.exists() { - return Some(icon_path.to_path_buf()); - } - - None - } - - pub fn get_light_icon(&self, exe: &str) -> Option { - let app = self.get_app(exe)?; - - app.get_44_icon() - .and_then(|sub_path| Self::get_light_icon_path(&self.install_location.join(sub_path))) - .or_else(|| { - app.get_150_icon().and_then(|sub_path| { - Self::get_light_icon_path(&self.install_location.join(sub_path)) - }) - }) - .or_else(|| { - self.get_store_logo().and_then(|sub_path| { - Self::get_light_icon_path(&self.install_location.join(sub_path)) - }) - }) - } - - pub fn get_shell_path(&self, exe: &str) -> Option { - let app = self.get_app(exe)?; - Some(format!( - "shell:AppsFolder\\{}_{}!{}", - self.name, self.publisher_id, app.app_id - )) - } -} - -#[derive(Debug, Default)] -pub struct WindowsAppsManager { - packages: Vec, -} - -impl WindowsAppsManager { - fn get_save_path() -> Result { - Ok(get_app_handle() - .path() - .app_data_dir()? - .join("uwp_manifests.json")) - } - - pub fn refresh(&mut self) -> Result<()> { - let script = PwshScript::new(include_str!("load_uwp_apps.ps1")); - let contents = tauri::async_runtime::block_on(script.execute())?; - self.packages = serde_json::from_str(&contents)?; - std::fs::write(Self::get_save_path()?, &contents)?; - Ok(()) - } - - pub fn get_from_path(&self, exe_path: &Path) -> Option<&UWPPackage> { - let exe = exe_path.file_name()?.to_str()?; - self.packages.iter().find(|p| { - exe_path.starts_with(&p.install_location) - && p.applications - .iter() - .any(|app| app.executable.ends_with(exe) || app.alias.as_deref() == Some(exe)) - }) - } -} +use lazy_static::lazy_static; +use parking_lot::Mutex; +use serde::Deserialize; +use std::{ + path::{Path, PathBuf}, + sync::Arc, +}; +use tauri::Manager; + +use crate::{error_handler::Result, seelen::get_app_handle, utils::pwsh::PwshScript}; + +pub static UWP_LIGHTUNPLATED_POSTFIX: &str = "_altform-lightunplated"; +#[allow(dead_code)] +pub static UWP_UNPLATED_POSTFIX: &str = "_altform-unplated"; + +lazy_static! { + pub static ref UWP_MANAGER: Arc> = Arc::new(Mutex::new({ + let mut manager = WindowsAppsManager::default(); + manager.refresh().expect("Failed to refresh UWP manager"); + manager + })); + pub static ref UWP_TARGET_SIZE_POSTFIXES: Vec<&'static str> = vec![ + ".targetsize-256", + ".targetsize-96", + ".targetsize-64", + ".targetsize-48", + ".targetsize-32", + ]; + pub static ref UWP_SCALE_POSTFIXES: Vec<&'static str> = vec![ + ".scale-400", + ".scale-200", + ".scale-150", + ".scale-125", + ".scale-100", + ]; +} + +#[derive(Deserialize, Debug, Default)] +#[serde(rename_all = "PascalCase")] +#[allow(dead_code)] +pub struct UWPPackage { + name: String, + version: String, + publisher_id: String, + package_full_name: String, + install_location: PathBuf, + store_logo: Option, + applications: Vec, +} + +#[derive(Deserialize, Debug, Default)] +#[serde(rename_all = "PascalCase")] +pub struct UWPApplication { + app_id: String, + /// subpath from UWPPackage.install_location + executable: String, + alias: Option, + /// subpath from UWPPackage.install_location + square150x150_logo: Option, + // subpath from UWPPackage.install_location + square44x44_logo: Option, +} + +impl UWPApplication { + pub fn get_44_icon(&self) -> Option<&String> { + self.square44x44_logo.as_ref() + } + + pub fn get_150_icon(&self) -> Option<&String> { + self.square150x150_logo.as_ref() + } +} + +impl UWPPackage { + pub fn get_store_logo(&self) -> Option<&String> { + self.store_logo.as_ref() + } + + pub fn get_app(&self, exe: &str) -> Option<&UWPApplication> { + self.applications + .iter() + .find(|app| app.executable.ends_with(exe) || app.alias.as_deref() == Some(exe)) + } + + pub fn get_light_icon_path(icon_path: &Path) -> Option { + let filename = icon_path.file_stem()?.to_str()?; + let extension = icon_path.extension()?.to_str()?; + + let postfixes = (*UWP_TARGET_SIZE_POSTFIXES) + .iter() + .chain((*UWP_SCALE_POSTFIXES).iter()); + + for postfix in postfixes { + let maybe_icon_path = icon_path.with_file_name(format!( + "{}{}{}.{}", + filename, postfix, UWP_LIGHTUNPLATED_POSTFIX, extension + )); + if maybe_icon_path.exists() { + return Some(maybe_icon_path); + } + + let maybe_icon_path = + icon_path.with_file_name(format!("{}{}.{}", filename, postfix, extension)); + if maybe_icon_path.exists() { + return Some(maybe_icon_path); + } + } + + // Some apps only adds one icon and without any postfix + // but we prefer the light/dark specific icon + if icon_path.exists() { + return Some(icon_path.to_path_buf()); + } + + None + } + + pub fn get_light_icon(&self, exe: &str) -> Option { + let app = self.get_app(exe)?; + + app.get_44_icon() + .and_then(|sub_path| Self::get_light_icon_path(&self.install_location.join(sub_path))) + .or_else(|| { + app.get_150_icon().and_then(|sub_path| { + Self::get_light_icon_path(&self.install_location.join(sub_path)) + }) + }) + .or_else(|| { + self.get_store_logo().and_then(|sub_path| { + Self::get_light_icon_path(&self.install_location.join(sub_path)) + }) + }) + } + + pub fn get_shell_path(&self, exe: &str) -> Option { + let app = self.get_app(exe)?; + Some(format!( + "shell:AppsFolder\\{}_{}!{}", + self.name, self.publisher_id, app.app_id + )) + } +} + +#[derive(Debug, Default)] +pub struct WindowsAppsManager { + packages: Vec, +} + +impl WindowsAppsManager { + fn get_save_path() -> Result { + Ok(get_app_handle() + .path() + .app_data_dir()? + .join("uwp_manifests.json")) + } + + pub fn refresh(&mut self) -> Result<()> { + let script = PwshScript::new(include_str!("load_uwp_apps.ps1")); + let contents = tauri::async_runtime::block_on(script.execute())?; + self.packages = serde_json::from_str(&contents)?; + std::fs::write(Self::get_save_path()?, &contents)?; + Ok(()) + } + + pub fn get_from_path(&self, exe_path: &Path) -> Option<&UWPPackage> { + let exe = exe_path.file_name()?.to_str()?; + self.packages.iter().find(|p| { + exe_path.starts_with(&p.install_location) + && p.applications + .iter() + .any(|app| app.executable.ends_with(exe) || app.alias.as_deref() == Some(exe)) + }) + } +} diff --git a/src/background/monitor.rs b/src/background/monitor.rs index 79b17497..44e9137d 100644 --- a/src/background/monitor.rs +++ b/src/background/monitor.rs @@ -1,131 +1,131 @@ -use color_eyre::eyre::eyre; -use getset::{Getters, MutGetters}; - -use crate::{ - error_handler::Result, log_error, seelen_bar::FancyToolbar, seelen_weg::SeelenWeg, - seelen_wm::WindowManager, state::application::FullState, utils::sleep_millis, - windows_api::WindowsApi, -}; - -use windows::Win32::Graphics::Gdi::HMONITOR; - -#[derive(Getters, MutGetters)] -#[getset(get = "pub", get_mut = "pub")] -pub struct Monitor { - handle: HMONITOR, - name: String, - toolbar: Option, - weg: Option, - wm: Option, -} - -impl Monitor { - pub fn update_handle(&mut self, id: HMONITOR) { - self.handle = id; - log_error!(self.ensure_positions()); - } - - pub fn ensure_positions(&mut self) -> Result<()> { - if let Some(bar) = &mut self.toolbar { - bar.set_positions(self.handle.0)?; - } - if let Some(weg) = &mut self.weg { - weg.set_positions(self.handle.0)?; - } - Ok(()) - } - - fn add_toolbar(&mut self) -> Result<()> { - if self.toolbar.is_none() { - // Tauri can fail the on creation of the first window, thats's why we only should retry - // for the first window created, the next windows should work normally. - // Update(08/13/2024): I think this can be removed on recent tauri versions - for attempt in 1..4 { - match FancyToolbar::new(&self.name) { - Ok(bar) => { - self.toolbar = Some(bar); - break; - } - Err(e) => { - log::error!("Failed to create Toolbar (attempt {}): {}", attempt, e); - sleep_millis(30); - } - } - } - } - Ok(()) - } - - fn add_weg(&mut self) -> Result<()> { - if self.weg.is_none() { - self.weg = Some(SeelenWeg::new(&self.name)?) - } - Ok(()) - } - - fn add_wm(&mut self) -> Result<()> { - if self.wm.is_none() { - self.wm = Some(WindowManager::new(self.handle.0)?) - } - Ok(()) - } - - pub fn load_settings(&mut self, settings: &FullState) -> Result<()> { - if settings.is_bar_enabled() { - self.add_toolbar()?; - } else { - self.toolbar = None; - } - - if settings.is_weg_enabled() { - self.add_weg()?; - } else { - self.weg = None; - } - - if settings.is_window_manager_enabled() && self.handle == WindowsApi::primary_monitor() { - self.add_wm()?; - } else { - self.wm = None; - } - - self.ensure_positions()?; - Ok(()) - } - - pub fn new(hmonitor: HMONITOR, settings: &FullState) -> Result { - if hmonitor.is_invalid() { - return Err(eyre!("Invalid Monitor").into()); - } - let mut monitor = Self { - handle: hmonitor, - name: WindowsApi::monitor_name(hmonitor)?, - toolbar: None, - weg: None, - wm: None, - }; - monitor.load_settings(settings)?; - Ok(monitor) - } - - pub fn is_focused(&self) -> bool { - let hwnd = WindowsApi::get_foreground_window(); - self.handle == WindowsApi::monitor_from_window(hwnd) - } - - pub fn is_ready(&self) -> bool { - if let Some(weg) = &self.weg { - if !weg.ready() { - return false; - } - } - - if let Some(wm) = &self.wm { - if !wm.ready() { - return false; - } - } - - true - } -} +use color_eyre::eyre::eyre; +use getset::{Getters, MutGetters}; + +use crate::{ + error_handler::Result, log_error, seelen_bar::FancyToolbar, seelen_weg::SeelenWeg, + seelen_wm::WindowManager, state::application::FullState, utils::sleep_millis, + windows_api::WindowsApi, +}; + +use windows::Win32::Graphics::Gdi::HMONITOR; + +#[derive(Getters, MutGetters)] +#[getset(get = "pub", get_mut = "pub")] +pub struct Monitor { + handle: HMONITOR, + name: String, + toolbar: Option, + weg: Option, + wm: Option, +} + +impl Monitor { + pub fn update_handle(&mut self, id: HMONITOR) { + self.handle = id; + log_error!(self.ensure_positions()); + } + + pub fn ensure_positions(&mut self) -> Result<()> { + if let Some(bar) = &mut self.toolbar { + bar.set_positions(self.handle.0)?; + } + if let Some(weg) = &mut self.weg { + weg.set_positions(self.handle.0)?; + } + Ok(()) + } + + fn add_toolbar(&mut self) -> Result<()> { + if self.toolbar.is_none() { + // Tauri can fail the on creation of the first window, thats's why we only should retry + // for the first window created, the next windows should work normally. + // Update(08/13/2024): I think this can be removed on recent tauri versions + for attempt in 1..4 { + match FancyToolbar::new(&self.name) { + Ok(bar) => { + self.toolbar = Some(bar); + break; + } + Err(e) => { + log::error!("Failed to create Toolbar (attempt {}): {}", attempt, e); + sleep_millis(30); + } + } + } + } + Ok(()) + } + + fn add_weg(&mut self) -> Result<()> { + if self.weg.is_none() { + self.weg = Some(SeelenWeg::new(&self.name)?) + } + Ok(()) + } + + fn add_wm(&mut self) -> Result<()> { + if self.wm.is_none() { + self.wm = Some(WindowManager::new(self.handle.0)?) + } + Ok(()) + } + + pub fn load_settings(&mut self, settings: &FullState) -> Result<()> { + if settings.is_bar_enabled() { + self.add_toolbar()?; + } else { + self.toolbar = None; + } + + if settings.is_weg_enabled() { + self.add_weg()?; + } else { + self.weg = None; + } + + if settings.is_window_manager_enabled() && self.handle == WindowsApi::primary_monitor() { + self.add_wm()?; + } else { + self.wm = None; + } + + self.ensure_positions()?; + Ok(()) + } + + pub fn new(hmonitor: HMONITOR, settings: &FullState) -> Result { + if hmonitor.is_invalid() { + return Err(eyre!("Invalid Monitor").into()); + } + let mut monitor = Self { + handle: hmonitor, + name: WindowsApi::monitor_name(hmonitor)?, + toolbar: None, + weg: None, + wm: None, + }; + monitor.load_settings(settings)?; + Ok(monitor) + } + + pub fn is_focused(&self) -> bool { + let hwnd = WindowsApi::get_foreground_window(); + self.handle == WindowsApi::monitor_from_window(hwnd) + } + + pub fn is_ready(&self) -> bool { + if let Some(weg) = &self.weg { + if !weg.ready() { + return false; + } + } + + if let Some(wm) = &self.wm { + if !wm.ready() { + return false; + } + } + + true + } +} diff --git a/src/background/plugins.rs b/src/background/plugins.rs index d887e52b..706d9acd 100644 --- a/src/background/plugins.rs +++ b/src/background/plugins.rs @@ -1,62 +1,62 @@ -use color_eyre::owo_colors::OwoColorize; -use tauri::{Builder, Wry}; -use tauri_plugin_autostart::MacosLauncher; -use tauri_plugin_log::{Target, TargetKind}; - -pub fn register_plugins(app_builder: Builder) -> Builder { - let mut log_plugin_builder = tauri_plugin_log::Builder::new() - .targets([ - Target::new(TargetKind::Stdout), - Target::new(TargetKind::LogDir { file_name: None }), - Target::new(TargetKind::Webview), - ]) - .level_for("tao", log::LevelFilter::Off) - .level_for("os_info", log::LevelFilter::Off) - .level_for("notify", log::LevelFilter::Off); - - if tauri::is_dev() { - log_plugin_builder = log_plugin_builder.format(move |out, message, record| { - out.finish(format_args!( - "[{}][{}] {}", - match record.level() { - log::Level::Trace => "TRACE".bright_black().to_string(), - log::Level::Info => "INFO~".bright_blue().to_string(), - log::Level::Warn => "WARN~".yellow().to_string(), - log::Level::Error => "ERROR".red().to_string(), - log::Level::Debug => "DEBUG".bright_green().to_string(), - }, - if record.level() == log::Level::Error { - record - .file() - .map(|file| { - format!( - "{}:{}", - file.replace("\\", "/"), - record.line().unwrap_or_default() - ) - }) - .unwrap_or_else(|| record.target().to_owned()) - .bright_red() - .to_string() - } else { - record.target().bright_black().to_string() - }, - message - )) - }); - } - - app_builder - .plugin(tauri_plugin_fs::init()) - .plugin(tauri_plugin_shell::init()) - .plugin(tauri_plugin_dialog::init()) - .plugin(tauri_plugin_process::init()) - .plugin(tauri_plugin_updater::Builder::new().build()) - .plugin(tauri_plugin_autostart::init( - MacosLauncher::LaunchAgent, - Some(vec!["--silent"]), - )) - .plugin(log_plugin_builder.build()) - .plugin(tauri_plugin_deep_link::init()) - .plugin(tauri_plugin_http::init()) -} +use color_eyre::owo_colors::OwoColorize; +use tauri::{Builder, Wry}; +use tauri_plugin_autostart::MacosLauncher; +use tauri_plugin_log::{Target, TargetKind}; + +pub fn register_plugins(app_builder: Builder) -> Builder { + let mut log_plugin_builder = tauri_plugin_log::Builder::new() + .targets([ + Target::new(TargetKind::Stdout), + Target::new(TargetKind::LogDir { file_name: None }), + Target::new(TargetKind::Webview), + ]) + .level_for("tao", log::LevelFilter::Off) + .level_for("os_info", log::LevelFilter::Off) + .level_for("notify", log::LevelFilter::Off); + + if tauri::is_dev() { + log_plugin_builder = log_plugin_builder.format(move |out, message, record| { + out.finish(format_args!( + "[{}][{}] {}", + match record.level() { + log::Level::Trace => "TRACE".bright_black().to_string(), + log::Level::Info => "INFO~".bright_blue().to_string(), + log::Level::Warn => "WARN~".yellow().to_string(), + log::Level::Error => "ERROR".red().to_string(), + log::Level::Debug => "DEBUG".bright_green().to_string(), + }, + if record.level() == log::Level::Error { + record + .file() + .map(|file| { + format!( + "{}:{}", + file.replace("\\", "/"), + record.line().unwrap_or_default() + ) + }) + .unwrap_or_else(|| record.target().to_owned()) + .bright_red() + .to_string() + } else { + record.target().bright_black().to_string() + }, + message + )) + }); + } + + app_builder + .plugin(tauri_plugin_fs::init()) + .plugin(tauri_plugin_shell::init()) + .plugin(tauri_plugin_dialog::init()) + .plugin(tauri_plugin_process::init()) + .plugin(tauri_plugin_updater::Builder::new().build()) + .plugin(tauri_plugin_autostart::init( + MacosLauncher::LaunchAgent, + Some(vec!["--silent"]), + )) + .plugin(log_plugin_builder.build()) + .plugin(tauri_plugin_deep_link::init()) + .plugin(tauri_plugin_http::init()) +} diff --git a/src/background/schedule.ps1 b/src/background/schedule.ps1 index 63db7c92..d275c87c 100644 --- a/src/background/schedule.ps1 +++ b/src/background/schedule.ps1 @@ -1,34 +1,34 @@ -param ( - [string]$ExeRoute, - [string]$Enabled -) - -$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) -if (-not $isAdmin) { - $ownRoute = $MyInvocation.MyCommand.Definition - $arguments = @( - "-NoProfile" - "-ExecutionPolicy Bypass" - "-File `"$ownRoute`"" - "-ExeRoute `"$ExeRoute`"" - "-Enabled `"$Enabled`"" - ) - Start-Process powershell -ArgumentList $arguments -Verb RunAs -WindowStyle Hidden - Exit -} - -$taskName = "\Seelen\Seelen-UI" - -if ($Enabled -eq "true") { - $action = New-ScheduledTaskAction -Execute "$ExeRoute" -Argument "--silent" - $trigger = New-ScheduledTaskTrigger -AtLogon - $settings = New-ScheduledTaskSettingsSet -Priority 2 -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -Hidden - - Register-ScheduledTask -Force -Action $action -Trigger $trigger -Settings $settings -TaskName $taskName -User $env:USERNAME -RunLevel Highest -} -else { - $existingTask = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue - if ($null -ne $existingTask) { - Unregister-ScheduledTask -TaskName $taskName -Confirm:$false - } -} +param ( + [string]$ExeRoute, + [string]$Enabled +) + +$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) +if (-not $isAdmin) { + $ownRoute = $MyInvocation.MyCommand.Definition + $arguments = @( + "-NoProfile" + "-ExecutionPolicy Bypass" + "-File `"$ownRoute`"" + "-ExeRoute `"$ExeRoute`"" + "-Enabled `"$Enabled`"" + ) + Start-Process powershell -ArgumentList $arguments -Verb RunAs -WindowStyle Hidden + Exit +} + +$taskName = "\Seelen\Seelen-UI" + +if ($Enabled -eq "true") { + $action = New-ScheduledTaskAction -Execute "$ExeRoute" -Argument "--silent" + $trigger = New-ScheduledTaskTrigger -AtLogon + $settings = New-ScheduledTaskSettingsSet -Priority 2 -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -Hidden + + Register-ScheduledTask -Force -Action $action -Trigger $trigger -Settings $settings -TaskName $taskName -User $env:USERNAME -RunLevel Highest +} +else { + $existingTask = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue + if ($null -ne $existingTask) { + Unregister-ScheduledTask -TaskName $taskName -Confirm:$false + } +} diff --git a/src/background/seelen.rs b/src/background/seelen.rs index e9e0a8a9..0f466ecb 100644 --- a/src/background/seelen.rs +++ b/src/background/seelen.rs @@ -1,412 +1,412 @@ -use std::{env::temp_dir, sync::Arc}; - -use arc_swap::ArcSwap; -use getset::{Getters, MutGetters}; -use lazy_static::lazy_static; -use parking_lot::Mutex; -use tauri::{path::BaseDirectory, AppHandle, Manager, Wry}; -use tauri_plugin_shell::ShellExt; -use windows::Win32::{ - Foundation::{BOOL, HWND, LPARAM}, - Graphics::Gdi::HMONITOR, -}; - -use crate::{ - error_handler::Result, - hook::register_win_hook, - log_error, - modules::monitors::{MonitorManagerEvent, MONITOR_MANAGER}, - monitor::Monitor, - seelen_shell::SeelenShell, - seelen_weg::SeelenWeg, - seelen_wm::WindowManager, - state::application::{FullState, FULL_STATE}, - system::{declare_system_events_handlers, release_system_events_handlers}, - trace_lock, - utils::{ahk::AutoHotKey, sleep_millis, PERFORMANCE_HELPER}, - windows_api::WindowsApi, -}; - -lazy_static! { - pub static ref SEELEN: Arc> = Arc::new(Mutex::new(Seelen::default())); - pub static ref APP_HANDLE: Arc>>> = Arc::new(Mutex::new(None)); -} - -pub fn get_app_handle() -> AppHandle { - APP_HANDLE - .lock() - .clone() - .expect("get_app_handle called but app is still not initialized") -} - -/** Struct should be initialized first before calling any other methods */ -#[derive(Getters, MutGetters, Default)] -pub struct Seelen { - handle: Option>, - #[getset(get = "pub", get_mut = "pub")] - monitors: Vec, - shell: Option, - state: Option>>, -} - -/* ============== Getters ============== */ -impl Seelen { - /** Ensure Seelen is initialized first before calling */ - pub fn handle(&self) -> &AppHandle { - self.handle.as_ref().unwrap() - } - - pub fn focused_monitor(&self) -> Option<&Monitor> { - self.monitors.iter().find(|m| m.is_focused()) - } - - pub fn focused_monitor_mut(&mut self) -> Option<&mut Monitor> { - self.monitors.iter_mut().find(|m| m.is_focused()) - } - - pub fn monitor_by_id_mut(&mut self, id: isize) -> Option<&mut Monitor> { - self.monitors.iter_mut().find(|m| m.handle().0 == id) - } - - pub fn monitor_by_name_mut(&mut self, name: &str) -> Option<&mut Monitor> { - self.monitors.iter_mut().find(|m| m.name() == name) - } - - pub fn state(&self) -> Arc { - self.state - .as_ref() - .expect("Seelen State not initialized") - .load_full() - } -} - -/* ============== Methods ============== */ -impl Seelen { - pub fn on_state_changed(&mut self) -> Result<()> { - let state = self.state(); - for monitor in &mut self.monitors { - monitor.load_settings(&state)?; - } - Ok(()) - } - - pub fn init(&mut self, app: AppHandle) -> Result<()> { - Self::ensure_folders(&app)?; - - log::trace!("Initializing Seelen"); - { - *APP_HANDLE.lock() = Some(app.clone()); - self.handle = Some(app.clone()); - self.state = Some(Arc::clone(&FULL_STATE)); - } - - if self.state().is_shell_enabled() { - self.shell = Some(SeelenShell::new(app.clone())); - } - - Ok(()) - } - - fn on_monitor_event(event: MonitorManagerEvent) { - std::thread::spawn(move || { - log::trace!("Monitor event: {:?}", event); - let mut seelen = trace_lock!(SEELEN); - match event { - MonitorManagerEvent::Added(_name, id) => { - log_error!(seelen.add_monitor(id)); - } - MonitorManagerEvent::Removed(_name, id) => { - log_error!(seelen.remove_monitor(id)); - } - MonitorManagerEvent::Updated(name, id) => { - if let Some(m) = seelen.monitor_by_name_mut(&name) { - m.update_handle(id); - } - } - } - }); - } - - fn start_async() -> Result<()> { - log_error!(Self::start_ahk_shortcuts()); - - let mut all_ready = false; - while !all_ready { - sleep_millis(10); - all_ready = SEELEN.lock().monitors().iter().all(|m| m.is_ready()); - } - - log::debug!( - "Seelen UI ready in: {:.2}s", - PERFORMANCE_HELPER.lock().elapsed().as_secs_f64() - ); - - log::trace!("Enumerating windows"); - WindowsApi::enum_windows(Some(Self::enum_windows_proc), 0)?; - register_win_hook()?; - Ok(()) - } - - pub fn start(&mut self) -> Result<()> { - declare_system_events_handlers()?; - - if self.state().is_weg_enabled() { - SeelenWeg::hide_taskbar(); - } - - log::trace!("Enumerating Monitors"); - let mut monitor_manager = trace_lock!(MONITOR_MANAGER); - for (_name, id) in &monitor_manager.monitors { - log_error!(self.add_monitor(*id)); - } - monitor_manager.listen_changes(Self::on_monitor_event); - - std::thread::spawn(|| log_error!(Self::start_async())); - std::thread::spawn(|| log_error!(Self::refresh_auto_start_path())); - Ok(()) - } - - /// Stop and release all resources - pub fn stop(&self) { - release_system_events_handlers(); - if self.state().is_weg_enabled() { - log_error!(SeelenWeg::show_taskbar()); - } - if self.state().is_ahk_enabled() { - Self::kill_ahk_shortcuts(); - } - } - - fn add_monitor(&mut self, hmonitor: HMONITOR) -> Result<()> { - self.monitors.push(Monitor::new(hmonitor, &self.state())?); - Ok(()) - } - - fn remove_monitor(&mut self, hmonitor: HMONITOR) -> Result<()> { - self.monitors.retain(|m| m.handle() != &hmonitor); - Ok(()) - } - - fn ensure_folders(handle: &AppHandle) -> Result<()> { - log::trace!("Ensuring folders"); - let path = handle.path(); - let data_path = path.app_data_dir()?; - - // migration of user settings files below v1.8.3 - let old_path = path.resolve(".config/seelen", BaseDirectory::Home)?; - if old_path.exists() { - log::trace!("Migrating user settings from {:?}", old_path); - for entry in std::fs::read_dir(&old_path)?.flatten() { - if entry.file_type()?.is_dir() { - continue; - } - std::fs::copy(entry.path(), data_path.join(entry.file_name()))?; - } - std::fs::remove_dir_all(&old_path)?; - } - - // user data folder - std::fs::create_dir_all(data_path.join("placeholders"))?; - std::fs::create_dir_all(data_path.join("themes"))?; - std::fs::create_dir_all(data_path.join("layouts"))?; - std::fs::create_dir_all(data_path.join("icons"))?; - std::fs::create_dir_all(data_path.join("wallpapers"))?; - - Ok(()) - } - - pub fn is_auto_start_enabled() -> Result { - let handle = get_app_handle(); - let output = tauri::async_runtime::block_on(async move { - handle - .shell() - .command("powershell") - .args([ - "-ExecutionPolicy", - "Bypass", - "-NoProfile", - "-Command", - "[bool](Get-ScheduledTask -TaskName Seelen-UI -ErrorAction SilentlyContinue)", - ]) - .output() - .await - })?; - let stdout = String::from_utf8(output.stdout)?.trim().to_lowercase(); - Ok(stdout == "true") - } - - /// override auto-start task in case of location change, normally this happen on MSIX update - fn refresh_auto_start_path() -> Result<()> { - if WindowsApi::is_elevated()? && Self::is_auto_start_enabled()? { - Self::set_auto_start(true)?; - } - Ok(()) - } - - pub fn set_auto_start(enabled: bool) -> Result<()> { - let pwsh_script = include_str!("schedule.ps1"); - let pwsh_script_path = temp_dir().join("schedule.ps1"); - std::fs::write(&pwsh_script_path, pwsh_script).expect("Failed to write temp script file"); - - let exe_path = std::env::current_exe()?; - - tauri::async_runtime::block_on(async move { - let result = get_app_handle() - .shell() - .command("powershell") - .args([ - "-ExecutionPolicy", - "Bypass", - "-NoProfile", - "-File", - &pwsh_script_path.to_string_lossy(), - "-ExeRoute", - &exe_path.to_string_lossy(), - "-Enabled", - if enabled { "true" } else { "false" }, - ]) - .output() - .await; - - match result { - Ok(output) => { - if !output.status.success() { - let stderr = std::str::from_utf8(&output.stderr) - .unwrap_or_default() - .trim(); - - log::error!("schedule auto start failed: {}", stderr); - } - } - Err(err) => log::error!("schedule auto start Failed to wait for process: {}", err), - }; - }); - - Ok(()) - } - - pub fn start_ahk_shortcuts() -> Result<()> { - // kill all running shortcuts before starting again - Self::kill_ahk_shortcuts(); - - let state = FULL_STATE.load(); - if state.is_ahk_enabled() { - log::trace!("Starting seelen.ahk"); - AutoHotKey::new(include_str!("utils/ahk/mocks/seelen.ahk")) - .with_lib() - .execute()?; - - if state.is_window_manager_enabled() { - log::trace!("Starting seelen.wm.ahk"); - AutoHotKey::from_template( - include_str!("utils/ahk/mocks/seelen.wm.ahk"), - state.get_ahk_variables(), - ) - .with_lib() - .execute()?; - } - } - - Ok(()) - } - - pub fn kill_ahk_shortcuts() { - log::trace!("Killing AHK shortcuts"); - get_app_handle() - .shell() - .command("powershell") - .args([ - "-ExecutionPolicy", - "Bypass", - "-NoProfile", - "-Command", - r"Get-WmiObject Win32_Process | Where-Object { $_.CommandLine -like '*static\redis\AutoHotkey.exe*' } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }", - ]) - .spawn() - .expect("Failed to close ahk"); - } - - pub fn show_settings() -> Result<()> { - log::trace!("Show settings window"); - let handle = get_app_handle(); - let window = handle.get_webview_window("settings").or_else(|| { - tauri::WebviewWindowBuilder::new( - &handle, - "settings", - tauri::WebviewUrl::App("settings/index.html".into()), - ) - .title("Settings") - .inner_size(720.0, 480.0) - .maximizable(false) - .minimizable(true) - .resizable(false) - .visible(false) - .decorations(false) - .center() - .build() - .ok() - }); - - match window { - Some(window) => { - window.unminimize()?; - window.set_focus()?; - Ok(()) - } - None => Err("Failed to create settings window".into()), - } - } - - pub fn show_update_modal() -> Result<()> { - log::trace!("Showing update notification window"); - let handle = get_app_handle(); - // check if path is in windows apps folder - let installation_path = handle.path().resource_dir()?; - if installation_path - .to_string_lossy() - .contains(r"\Program Files\WindowsApps\") - { - log::trace!("Skipping update notification because it is installed as MSIX"); - return Ok(()); - } - - tauri::WebviewWindowBuilder::new( - &handle, - "updater", - tauri::WebviewUrl::App("update/index.html".into()), - ) - .inner_size(500.0, 240.0) - .maximizable(false) - .minimizable(true) - .resizable(false) - .title("Update Available") - .visible(false) - .decorations(false) - .transparent(true) - .shadow(false) - .center() - .always_on_top(true) - .build()?; - - Ok(()) - } -} - -impl Seelen { - unsafe extern "system" fn enum_windows_proc(hwnd: HWND, _: LPARAM) -> BOOL { - let mut seelen = trace_lock!(SEELEN); - - if SeelenWeg::is_real_window(hwnd, false) { - SeelenWeg::add_hwnd(hwnd); - } - - for monitor in seelen.monitors_mut() { - if let Some(wm) = monitor.wm_mut() { - if WindowManager::is_manageable_window(hwnd, true) { - log_error!(wm.add_hwnd(hwnd)); - } - } - } - true.into() - } -} +use std::{env::temp_dir, sync::Arc}; + +use arc_swap::ArcSwap; +use getset::{Getters, MutGetters}; +use lazy_static::lazy_static; +use parking_lot::Mutex; +use tauri::{path::BaseDirectory, AppHandle, Manager, Wry}; +use tauri_plugin_shell::ShellExt; +use windows::Win32::{ + Foundation::{BOOL, HWND, LPARAM}, + Graphics::Gdi::HMONITOR, +}; + +use crate::{ + error_handler::Result, + hook::register_win_hook, + log_error, + modules::monitors::{MonitorManagerEvent, MONITOR_MANAGER}, + monitor::Monitor, + seelen_shell::SeelenShell, + seelen_weg::SeelenWeg, + seelen_wm::WindowManager, + state::application::{FullState, FULL_STATE}, + system::{declare_system_events_handlers, release_system_events_handlers}, + trace_lock, + utils::{ahk::AutoHotKey, sleep_millis, PERFORMANCE_HELPER}, + windows_api::WindowsApi, +}; + +lazy_static! { + pub static ref SEELEN: Arc> = Arc::new(Mutex::new(Seelen::default())); + pub static ref APP_HANDLE: Arc>>> = Arc::new(Mutex::new(None)); +} + +pub fn get_app_handle() -> AppHandle { + APP_HANDLE + .lock() + .clone() + .expect("get_app_handle called but app is still not initialized") +} + +/** Struct should be initialized first before calling any other methods */ +#[derive(Getters, MutGetters, Default)] +pub struct Seelen { + handle: Option>, + #[getset(get = "pub", get_mut = "pub")] + monitors: Vec, + shell: Option, + state: Option>>, +} + +/* ============== Getters ============== */ +impl Seelen { + /** Ensure Seelen is initialized first before calling */ + pub fn handle(&self) -> &AppHandle { + self.handle.as_ref().unwrap() + } + + pub fn focused_monitor(&self) -> Option<&Monitor> { + self.monitors.iter().find(|m| m.is_focused()) + } + + pub fn focused_monitor_mut(&mut self) -> Option<&mut Monitor> { + self.monitors.iter_mut().find(|m| m.is_focused()) + } + + pub fn monitor_by_id_mut(&mut self, id: isize) -> Option<&mut Monitor> { + self.monitors.iter_mut().find(|m| m.handle().0 == id) + } + + pub fn monitor_by_name_mut(&mut self, name: &str) -> Option<&mut Monitor> { + self.monitors.iter_mut().find(|m| m.name() == name) + } + + pub fn state(&self) -> Arc { + self.state + .as_ref() + .expect("Seelen State not initialized") + .load_full() + } +} + +/* ============== Methods ============== */ +impl Seelen { + pub fn on_state_changed(&mut self) -> Result<()> { + let state = self.state(); + for monitor in &mut self.monitors { + monitor.load_settings(&state)?; + } + Ok(()) + } + + pub fn init(&mut self, app: AppHandle) -> Result<()> { + Self::ensure_folders(&app)?; + + log::trace!("Initializing Seelen"); + { + *APP_HANDLE.lock() = Some(app.clone()); + self.handle = Some(app.clone()); + self.state = Some(Arc::clone(&FULL_STATE)); + } + + if self.state().is_shell_enabled() { + self.shell = Some(SeelenShell::new(app.clone())); + } + + Ok(()) + } + + fn on_monitor_event(event: MonitorManagerEvent) { + std::thread::spawn(move || { + log::trace!("Monitor event: {:?}", event); + let mut seelen = trace_lock!(SEELEN); + match event { + MonitorManagerEvent::Added(_name, id) => { + log_error!(seelen.add_monitor(id)); + } + MonitorManagerEvent::Removed(_name, id) => { + log_error!(seelen.remove_monitor(id)); + } + MonitorManagerEvent::Updated(name, id) => { + if let Some(m) = seelen.monitor_by_name_mut(&name) { + m.update_handle(id); + } + } + } + }); + } + + fn start_async() -> Result<()> { + log_error!(Self::start_ahk_shortcuts()); + + let mut all_ready = false; + while !all_ready { + sleep_millis(10); + all_ready = SEELEN.lock().monitors().iter().all(|m| m.is_ready()); + } + + log::debug!( + "Seelen UI ready in: {:.2}s", + PERFORMANCE_HELPER.lock().elapsed().as_secs_f64() + ); + + log::trace!("Enumerating windows"); + WindowsApi::enum_windows(Some(Self::enum_windows_proc), 0)?; + register_win_hook()?; + Ok(()) + } + + pub fn start(&mut self) -> Result<()> { + declare_system_events_handlers()?; + + if self.state().is_weg_enabled() { + SeelenWeg::hide_taskbar(); + } + + log::trace!("Enumerating Monitors"); + let mut monitor_manager = trace_lock!(MONITOR_MANAGER); + for (_name, id) in &monitor_manager.monitors { + log_error!(self.add_monitor(*id)); + } + monitor_manager.listen_changes(Self::on_monitor_event); + + std::thread::spawn(|| log_error!(Self::start_async())); + std::thread::spawn(|| log_error!(Self::refresh_auto_start_path())); + Ok(()) + } + + /// Stop and release all resources + pub fn stop(&self) { + release_system_events_handlers(); + if self.state().is_weg_enabled() { + log_error!(SeelenWeg::show_taskbar()); + } + if self.state().is_ahk_enabled() { + Self::kill_ahk_shortcuts(); + } + } + + fn add_monitor(&mut self, hmonitor: HMONITOR) -> Result<()> { + self.monitors.push(Monitor::new(hmonitor, &self.state())?); + Ok(()) + } + + fn remove_monitor(&mut self, hmonitor: HMONITOR) -> Result<()> { + self.monitors.retain(|m| m.handle() != &hmonitor); + Ok(()) + } + + fn ensure_folders(handle: &AppHandle) -> Result<()> { + log::trace!("Ensuring folders"); + let path = handle.path(); + let data_path = path.app_data_dir()?; + + // migration of user settings files below v1.8.3 + let old_path = path.resolve(".config/seelen", BaseDirectory::Home)?; + if old_path.exists() { + log::trace!("Migrating user settings from {:?}", old_path); + for entry in std::fs::read_dir(&old_path)?.flatten() { + if entry.file_type()?.is_dir() { + continue; + } + std::fs::copy(entry.path(), data_path.join(entry.file_name()))?; + } + std::fs::remove_dir_all(&old_path)?; + } + + // user data folder + std::fs::create_dir_all(data_path.join("placeholders"))?; + std::fs::create_dir_all(data_path.join("themes"))?; + std::fs::create_dir_all(data_path.join("layouts"))?; + std::fs::create_dir_all(data_path.join("icons"))?; + std::fs::create_dir_all(data_path.join("wallpapers"))?; + + Ok(()) + } + + pub fn is_auto_start_enabled() -> Result { + let handle = get_app_handle(); + let output = tauri::async_runtime::block_on(async move { + handle + .shell() + .command("powershell") + .args([ + "-ExecutionPolicy", + "Bypass", + "-NoProfile", + "-Command", + "[bool](Get-ScheduledTask -TaskName Seelen-UI -ErrorAction SilentlyContinue)", + ]) + .output() + .await + })?; + let stdout = String::from_utf8(output.stdout)?.trim().to_lowercase(); + Ok(stdout == "true") + } + + /// override auto-start task in case of location change, normally this happen on MSIX update + fn refresh_auto_start_path() -> Result<()> { + if WindowsApi::is_elevated()? && Self::is_auto_start_enabled()? { + Self::set_auto_start(true)?; + } + Ok(()) + } + + pub fn set_auto_start(enabled: bool) -> Result<()> { + let pwsh_script = include_str!("schedule.ps1"); + let pwsh_script_path = temp_dir().join("schedule.ps1"); + std::fs::write(&pwsh_script_path, pwsh_script).expect("Failed to write temp script file"); + + let exe_path = std::env::current_exe()?; + + tauri::async_runtime::block_on(async move { + let result = get_app_handle() + .shell() + .command("powershell") + .args([ + "-ExecutionPolicy", + "Bypass", + "-NoProfile", + "-File", + &pwsh_script_path.to_string_lossy(), + "-ExeRoute", + &exe_path.to_string_lossy(), + "-Enabled", + if enabled { "true" } else { "false" }, + ]) + .output() + .await; + + match result { + Ok(output) => { + if !output.status.success() { + let stderr = std::str::from_utf8(&output.stderr) + .unwrap_or_default() + .trim(); + + log::error!("schedule auto start failed: {}", stderr); + } + } + Err(err) => log::error!("schedule auto start Failed to wait for process: {}", err), + }; + }); + + Ok(()) + } + + pub fn start_ahk_shortcuts() -> Result<()> { + // kill all running shortcuts before starting again + Self::kill_ahk_shortcuts(); + + let state = FULL_STATE.load(); + if state.is_ahk_enabled() { + log::trace!("Starting seelen.ahk"); + AutoHotKey::new(include_str!("utils/ahk/mocks/seelen.ahk")) + .with_lib() + .execute()?; + + if state.is_window_manager_enabled() { + log::trace!("Starting seelen.wm.ahk"); + AutoHotKey::from_template( + include_str!("utils/ahk/mocks/seelen.wm.ahk"), + state.get_ahk_variables(), + ) + .with_lib() + .execute()?; + } + } + + Ok(()) + } + + pub fn kill_ahk_shortcuts() { + log::trace!("Killing AHK shortcuts"); + get_app_handle() + .shell() + .command("powershell") + .args([ + "-ExecutionPolicy", + "Bypass", + "-NoProfile", + "-Command", + r"Get-WmiObject Win32_Process | Where-Object { $_.CommandLine -like '*static\redis\AutoHotkey.exe*' } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }", + ]) + .spawn() + .expect("Failed to close ahk"); + } + + pub fn show_settings() -> Result<()> { + log::trace!("Show settings window"); + let handle = get_app_handle(); + let window = handle.get_webview_window("settings").or_else(|| { + tauri::WebviewWindowBuilder::new( + &handle, + "settings", + tauri::WebviewUrl::App("settings/index.html".into()), + ) + .title("Settings") + .inner_size(720.0, 480.0) + .maximizable(false) + .minimizable(true) + .resizable(false) + .visible(false) + .decorations(false) + .center() + .build() + .ok() + }); + + match window { + Some(window) => { + window.unminimize()?; + window.set_focus()?; + Ok(()) + } + None => Err("Failed to create settings window".into()), + } + } + + pub fn show_update_modal() -> Result<()> { + log::trace!("Showing update notification window"); + let handle = get_app_handle(); + // check if path is in windows apps folder + let installation_path = handle.path().resource_dir()?; + if installation_path + .to_string_lossy() + .contains(r"\Program Files\WindowsApps\") + { + log::trace!("Skipping update notification because it is installed as MSIX"); + return Ok(()); + } + + tauri::WebviewWindowBuilder::new( + &handle, + "updater", + tauri::WebviewUrl::App("update/index.html".into()), + ) + .inner_size(500.0, 240.0) + .maximizable(false) + .minimizable(true) + .resizable(false) + .title("Update Available") + .visible(false) + .decorations(false) + .transparent(true) + .shadow(false) + .center() + .always_on_top(true) + .build()?; + + Ok(()) + } +} + +impl Seelen { + unsafe extern "system" fn enum_windows_proc(hwnd: HWND, _: LPARAM) -> BOOL { + let mut seelen = trace_lock!(SEELEN); + + if SeelenWeg::is_real_window(hwnd, false) { + SeelenWeg::add_hwnd(hwnd); + } + + for monitor in seelen.monitors_mut() { + if let Some(wm) = monitor.wm_mut() { + if WindowManager::is_manageable_window(hwnd, true) { + log_error!(wm.add_hwnd(hwnd)); + } + } + } + true.into() + } +} diff --git a/src/background/seelen_bar/cli.rs b/src/background/seelen_bar/cli.rs index fdfbecaa..bc1b923a 100644 --- a/src/background/seelen_bar/cli.rs +++ b/src/background/seelen_bar/cli.rs @@ -1,33 +1,33 @@ -use clap::Command; - -use crate::{error_handler::Result, get_subcommands}; - -use super::FancyToolbar; - -get_subcommands![ - /** Open Dev Tools (only works if the app is running in dev mode) */ - Debug, -]; - -impl FancyToolbar { - pub const CLI_IDENTIFIER: &'static str = "toolbar"; - - pub fn get_cli() -> Command { - Command::new(Self::CLI_IDENTIFIER) - .about("Seelen's Fancy Toolbar") - .visible_alias("tb") - .arg_required_else_help(true) - .subcommands(SubCommand::commands()) - } - - pub fn process(&mut self, matches: &clap::ArgMatches) -> Result<()> { - let subcommand = SubCommand::try_from(matches)?; - match subcommand { - SubCommand::Debug => { - #[cfg(any(debug_assertions, feature = "devtools"))] - self.window.open_devtools(); - } - }; - Ok(()) - } -} +use clap::Command; + +use crate::{error_handler::Result, get_subcommands}; + +use super::FancyToolbar; + +get_subcommands![ + /** Open Dev Tools (only works if the app is running in dev mode) */ + Debug, +]; + +impl FancyToolbar { + pub const CLI_IDENTIFIER: &'static str = "toolbar"; + + pub fn get_cli() -> Command { + Command::new(Self::CLI_IDENTIFIER) + .about("Seelen's Fancy Toolbar") + .visible_alias("tb") + .arg_required_else_help(true) + .subcommands(SubCommand::commands()) + } + + pub fn process(&mut self, matches: &clap::ArgMatches) -> Result<()> { + let subcommand = SubCommand::try_from(matches)?; + match subcommand { + SubCommand::Debug => { + #[cfg(any(debug_assertions, feature = "devtools"))] + self.window.open_devtools(); + } + }; + Ok(()) + } +} diff --git a/src/background/seelen_bar/hook.rs b/src/background/seelen_bar/hook.rs index cdd7d33d..c0f25fda 100644 --- a/src/background/seelen_bar/hook.rs +++ b/src/background/seelen_bar/hook.rs @@ -1,46 +1,46 @@ -use windows::Win32::Foundation::HWND; - -use crate::{error_handler::Result, windows_api::WindowsApi, winevent::WinEvent}; - -use super::FancyToolbar; - -impl FancyToolbar { - pub fn process_win_event(&mut self, event: WinEvent, origin: HWND) -> Result<()> { - match event { - WinEvent::ObjectNameChange => { - if self.last_focus == Some(origin.0) { - self.focus_changed(origin)?; - } - } - WinEvent::SystemForeground | WinEvent::ObjectFocus => { - self.focus_changed(origin)?; - } - WinEvent::SyntheticFullscreenStart(event_data) => { - let monitor = WindowsApi::monitor_from_window(self.window.hwnd()?); - if monitor == event_data.monitor { - log::trace!( - "Fullscreen on {} || {} || {}", - WindowsApi::exe(origin).unwrap_or_default(), - WindowsApi::get_class(origin).unwrap_or_default(), - WindowsApi::get_window_text(origin) - ); - self.hide()?; - } - } - WinEvent::SyntheticFullscreenEnd(event_data) => { - let monitor = WindowsApi::monitor_from_window(self.window.hwnd()?); - if monitor == event_data.monitor { - log::trace!( - "Exit Fullscreen on {} || {} || {}", - WindowsApi::exe(origin).unwrap_or_default(), - WindowsApi::get_class(origin).unwrap_or_default(), - WindowsApi::get_window_text(origin) - ); - self.show()?; - } - } - _ => {} - }; - Ok(()) - } -} +use windows::Win32::Foundation::HWND; + +use crate::{error_handler::Result, windows_api::WindowsApi, winevent::WinEvent}; + +use super::FancyToolbar; + +impl FancyToolbar { + pub fn process_win_event(&mut self, event: WinEvent, origin: HWND) -> Result<()> { + match event { + WinEvent::ObjectNameChange => { + if self.last_focus == Some(origin.0) { + self.focus_changed(origin)?; + } + } + WinEvent::SystemForeground | WinEvent::ObjectFocus => { + self.focus_changed(origin)?; + } + WinEvent::SyntheticFullscreenStart(event_data) => { + let monitor = WindowsApi::monitor_from_window(self.window.hwnd()?); + if monitor == event_data.monitor { + log::trace!( + "Fullscreen on {} || {} || {}", + WindowsApi::exe(origin).unwrap_or_default(), + WindowsApi::get_class(origin).unwrap_or_default(), + WindowsApi::get_window_text(origin) + ); + self.hide()?; + } + } + WinEvent::SyntheticFullscreenEnd(event_data) => { + let monitor = WindowsApi::monitor_from_window(self.window.hwnd()?); + if monitor == event_data.monitor { + log::trace!( + "Exit Fullscreen on {} || {} || {}", + WindowsApi::exe(origin).unwrap_or_default(), + WindowsApi::get_class(origin).unwrap_or_default(), + WindowsApi::get_window_text(origin) + ); + self.show()?; + } + } + _ => {} + }; + Ok(()) + } +} diff --git a/src/background/seelen_bar/mod.rs b/src/background/seelen_bar/mod.rs index d55b5a0b..71adc411 100644 --- a/src/background/seelen_bar/mod.rs +++ b/src/background/seelen_bar/mod.rs @@ -1,229 +1,229 @@ -pub mod cli; -pub mod hook; - -use std::sync::atomic::Ordering; - -use crate::{ - error_handler::Result, - log_error, - seelen::get_app_handle, - state::{IS_TOOLBAR_ENABLED, TOOLBAR_HEIGHT}, - windows_api::{AppBarData, AppBarDataEdge, WindowsApi}, -}; -use serde::Serialize; -use tauri::{Emitter, Listener, Manager, WebviewWindow}; -use windows::Win32::{ - Foundation::{HWND, RECT}, - Graphics::Gdi::HMONITOR, - UI::WindowsAndMessaging::{HWND_TOPMOST, SWP_NOACTIVATE, SW_HIDE, SW_SHOWNOACTIVATE}, -}; - -pub struct FancyToolbar { - window: WebviewWindow, - hitbox: WebviewWindow, - // -- -- -- -- - last_focus: Option, - hidden: bool, -} - -#[derive(Serialize, Clone)] -pub struct ActiveApp { - title: String, - name: String, - exe: Option, -} - -impl Drop for FancyToolbar { - fn drop(&mut self) { - log::info!("Dropping {}", self.window.label()); - if let Ok(hwnd) = self.hitbox.hwnd() { - AppBarData::from_handle(hwnd).unregister_bar(); - } - log_error!(self.window.destroy()); - log_error!(self.hitbox.destroy()); - } -} - -impl FancyToolbar { - pub fn new(postfix: &str) -> Result { - log::info!("Creating {}/{}", Self::TARGET, postfix); - let (window, hitbox) = Self::create_window(postfix)?; - Ok(Self { - window, - hitbox, - last_focus: None, - hidden: false, - }) - } - - pub fn emit(&self, event: &str, payload: S) -> Result<()> { - self.window.emit_to(self.window.label(), event, payload)?; - Ok(()) - } - - pub fn hide(&mut self) -> Result<()> { - WindowsApi::show_window_async(self.window.hwnd()?, SW_HIDE)?; - WindowsApi::show_window_async(self.hitbox.hwnd()?, SW_HIDE)?; - self.hidden = true; - Ok(()) - } - - pub fn show(&mut self) -> Result<()> { - WindowsApi::show_window_async(self.window.hwnd()?, SW_SHOWNOACTIVATE)?; - WindowsApi::show_window_async(self.hitbox.hwnd()?, SW_SHOWNOACTIVATE)?; - self.hidden = false; - Ok(()) - } - - pub fn focus_changed(&mut self, hwnd: HWND) -> Result<()> { - let title = WindowsApi::get_window_text(hwnd); - self.last_focus = Some(hwnd.0); - self.emit( - "focus-changed", - ActiveApp { - title, - name: WindowsApi::get_window_display_name(hwnd) - .unwrap_or(String::from("Error on App Name")), - exe: WindowsApi::exe_path(hwnd).ok(), - }, - )?; - Ok(()) - } - - pub fn ensure_hitbox_zorder(&self) -> Result<()> { - let hitbox = HWND(self.hitbox.hwnd()?.0); - WindowsApi::bring_to(hitbox, HWND_TOPMOST)?; - self.set_positions(WindowsApi::monitor_from_window(hitbox).0)?; - Ok(()) - } -} - -// statics -impl FancyToolbar { - const TARGET: &'static str = "fancy-toolbar"; - const TARGET_HITBOX: &'static str = "fancy-toolbar-hitbox"; - - /// Work area no works fine on multiple monitors - /// so we use this functions that only takes the toolbar in account - pub fn get_work_area_by_monitor(monitor: isize) -> Result { - let monitor_info = WindowsApi::monitor_info(HMONITOR(monitor))?; - - let dpi = WindowsApi::get_device_pixel_ratio(HMONITOR(monitor))?; - let mut rect = monitor_info.monitorInfo.rcMonitor; - - if IS_TOOLBAR_ENABLED.load(Ordering::Acquire) { - let toolbar_height = TOOLBAR_HEIGHT.load(Ordering::Acquire); - rect.top += (toolbar_height as f32 * dpi) as i32; - } - - Ok(rect) - } - - pub fn set_positions(&self, monitor: isize) -> Result<()> { - let hmonitor = HMONITOR(monitor); - if hmonitor.is_invalid() { - return Err("Invalid Monitor".into()); - } - - let monitor_info = WindowsApi::monitor_info(hmonitor)?; - let rc_monitor = monitor_info.monitorInfo.rcMonitor; - - let main_hwnd = HWND(self.window.hwnd()?.0); - let hitbox_hwnd = HWND(self.hitbox.hwnd()?.0); - - let dpi = WindowsApi::get_device_pixel_ratio(hmonitor)?; - let toolbar_height = TOOLBAR_HEIGHT.load(Ordering::Acquire); - - let mut abd = AppBarData::from_handle(hitbox_hwnd); - - let mut abd_rect = rc_monitor; - abd_rect.bottom = abd_rect.top + (toolbar_height as f32 * dpi) as i32; - - abd.set_edge(AppBarDataEdge::Top); - abd.set_rect(abd_rect); - - abd.register_as_new_bar(); - - // pre set position for resize in case of multiples dpi - WindowsApi::move_window(hitbox_hwnd, &rc_monitor)?; - WindowsApi::set_position(hitbox_hwnd, None, &abd_rect, SWP_NOACTIVATE)?; - - WindowsApi::move_window(main_hwnd, &rc_monitor)?; - WindowsApi::set_position(main_hwnd, None, &rc_monitor, SWP_NOACTIVATE)?; - Ok(()) - } - - fn create_window(postfix: &str) -> Result<(WebviewWindow, WebviewWindow)> { - let manager = get_app_handle(); - - let label = format!("{}/{}", Self::TARGET_HITBOX, postfix); - let hitbox = match manager.get_webview_window(&label) { - Some(window) => window, - None => tauri::WebviewWindowBuilder::new( - &manager, - label, - tauri::WebviewUrl::App("toolbar-hitbox/index.html".into()), - ) - .title("Seelen Fancy Toolbar Hitbox") - .maximizable(false) - .minimizable(false) - .resizable(false) - .visible(false) - .decorations(false) - .transparent(true) - .shadow(false) - .skip_taskbar(true) - .always_on_top(true) - .build()?, - }; - - let label = format!("{}/{}", Self::TARGET, postfix); - let window = match manager.get_webview_window(&label) { - Some(window) => window, - None => tauri::WebviewWindowBuilder::new( - &manager, - label, - tauri::WebviewUrl::App("toolbar/index.html".into()), - ) - .title("Seelen Fancy Toolbar") - .maximizable(false) - .minimizable(false) - .resizable(false) - .visible(false) - .decorations(false) - .transparent(true) - .shadow(false) - .skip_taskbar(true) - .always_on_top(true) - .owner(&hitbox)? - .build()?, - }; - - window.set_ignore_cursor_events(true)?; - - window.once("store-events-ready", Self::on_store_events_ready); - Ok((window, hitbox)) - } - - fn on_store_events_ready(_: tauri::Event) { - std::thread::spawn(|| -> Result<()> { - let handler = get_app_handle(); - - let desktops = winvd::get_desktops()?; - let current_desktop = winvd::get_current_desktop()?; - - let mut desktops_names = Vec::new(); - for (i, d) in desktops.iter().enumerate() { - if let Ok(name) = d.get_name() { - desktops_names.push(name); - } else { - desktops_names.push(format!("Desktop {}", i + 1)) - } - } - - handler.emit("workspaces-changed", desktops_names)?; - handler.emit("active-workspace-changed", current_desktop.get_index()?)?; - Ok(()) - }); - } -} +pub mod cli; +pub mod hook; + +use std::sync::atomic::Ordering; + +use crate::{ + error_handler::Result, + log_error, + seelen::get_app_handle, + state::{IS_TOOLBAR_ENABLED, TOOLBAR_HEIGHT}, + windows_api::{AppBarData, AppBarDataEdge, WindowsApi}, +}; +use serde::Serialize; +use tauri::{Emitter, Listener, Manager, WebviewWindow}; +use windows::Win32::{ + Foundation::{HWND, RECT}, + Graphics::Gdi::HMONITOR, + UI::WindowsAndMessaging::{HWND_TOPMOST, SWP_NOACTIVATE, SW_HIDE, SW_SHOWNOACTIVATE}, +}; + +pub struct FancyToolbar { + window: WebviewWindow, + hitbox: WebviewWindow, + // -- -- -- -- + last_focus: Option, + hidden: bool, +} + +#[derive(Serialize, Clone)] +pub struct ActiveApp { + title: String, + name: String, + exe: Option, +} + +impl Drop for FancyToolbar { + fn drop(&mut self) { + log::info!("Dropping {}", self.window.label()); + if let Ok(hwnd) = self.hitbox.hwnd() { + AppBarData::from_handle(hwnd).unregister_bar(); + } + log_error!(self.window.destroy()); + log_error!(self.hitbox.destroy()); + } +} + +impl FancyToolbar { + pub fn new(postfix: &str) -> Result { + log::info!("Creating {}/{}", Self::TARGET, postfix); + let (window, hitbox) = Self::create_window(postfix)?; + Ok(Self { + window, + hitbox, + last_focus: None, + hidden: false, + }) + } + + pub fn emit(&self, event: &str, payload: S) -> Result<()> { + self.window.emit_to(self.window.label(), event, payload)?; + Ok(()) + } + + pub fn hide(&mut self) -> Result<()> { + WindowsApi::show_window_async(self.window.hwnd()?, SW_HIDE)?; + WindowsApi::show_window_async(self.hitbox.hwnd()?, SW_HIDE)?; + self.hidden = true; + Ok(()) + } + + pub fn show(&mut self) -> Result<()> { + WindowsApi::show_window_async(self.window.hwnd()?, SW_SHOWNOACTIVATE)?; + WindowsApi::show_window_async(self.hitbox.hwnd()?, SW_SHOWNOACTIVATE)?; + self.hidden = false; + Ok(()) + } + + pub fn focus_changed(&mut self, hwnd: HWND) -> Result<()> { + let title = WindowsApi::get_window_text(hwnd); + self.last_focus = Some(hwnd.0); + self.emit( + "focus-changed", + ActiveApp { + title, + name: WindowsApi::get_window_display_name(hwnd) + .unwrap_or(String::from("Error on App Name")), + exe: WindowsApi::exe_path(hwnd).ok(), + }, + )?; + Ok(()) + } + + pub fn ensure_hitbox_zorder(&self) -> Result<()> { + let hitbox = HWND(self.hitbox.hwnd()?.0); + WindowsApi::bring_to(hitbox, HWND_TOPMOST)?; + self.set_positions(WindowsApi::monitor_from_window(hitbox).0)?; + Ok(()) + } +} + +// statics +impl FancyToolbar { + const TARGET: &'static str = "fancy-toolbar"; + const TARGET_HITBOX: &'static str = "fancy-toolbar-hitbox"; + + /// Work area no works fine on multiple monitors + /// so we use this functions that only takes the toolbar in account + pub fn get_work_area_by_monitor(monitor: isize) -> Result { + let monitor_info = WindowsApi::monitor_info(HMONITOR(monitor))?; + + let dpi = WindowsApi::get_device_pixel_ratio(HMONITOR(monitor))?; + let mut rect = monitor_info.monitorInfo.rcMonitor; + + if IS_TOOLBAR_ENABLED.load(Ordering::Acquire) { + let toolbar_height = TOOLBAR_HEIGHT.load(Ordering::Acquire); + rect.top += (toolbar_height as f32 * dpi) as i32; + } + + Ok(rect) + } + + pub fn set_positions(&self, monitor: isize) -> Result<()> { + let hmonitor = HMONITOR(monitor); + if hmonitor.is_invalid() { + return Err("Invalid Monitor".into()); + } + + let monitor_info = WindowsApi::monitor_info(hmonitor)?; + let rc_monitor = monitor_info.monitorInfo.rcMonitor; + + let main_hwnd = HWND(self.window.hwnd()?.0); + let hitbox_hwnd = HWND(self.hitbox.hwnd()?.0); + + let dpi = WindowsApi::get_device_pixel_ratio(hmonitor)?; + let toolbar_height = TOOLBAR_HEIGHT.load(Ordering::Acquire); + + let mut abd = AppBarData::from_handle(hitbox_hwnd); + + let mut abd_rect = rc_monitor; + abd_rect.bottom = abd_rect.top + (toolbar_height as f32 * dpi) as i32; + + abd.set_edge(AppBarDataEdge::Top); + abd.set_rect(abd_rect); + + abd.register_as_new_bar(); + + // pre set position for resize in case of multiples dpi + WindowsApi::move_window(hitbox_hwnd, &rc_monitor)?; + WindowsApi::set_position(hitbox_hwnd, None, &abd_rect, SWP_NOACTIVATE)?; + + WindowsApi::move_window(main_hwnd, &rc_monitor)?; + WindowsApi::set_position(main_hwnd, None, &rc_monitor, SWP_NOACTIVATE)?; + Ok(()) + } + + fn create_window(postfix: &str) -> Result<(WebviewWindow, WebviewWindow)> { + let manager = get_app_handle(); + + let label = format!("{}/{}", Self::TARGET_HITBOX, postfix); + let hitbox = match manager.get_webview_window(&label) { + Some(window) => window, + None => tauri::WebviewWindowBuilder::new( + &manager, + label, + tauri::WebviewUrl::App("toolbar-hitbox/index.html".into()), + ) + .title("Seelen Fancy Toolbar Hitbox") + .maximizable(false) + .minimizable(false) + .resizable(false) + .visible(false) + .decorations(false) + .transparent(true) + .shadow(false) + .skip_taskbar(true) + .always_on_top(true) + .build()?, + }; + + let label = format!("{}/{}", Self::TARGET, postfix); + let window = match manager.get_webview_window(&label) { + Some(window) => window, + None => tauri::WebviewWindowBuilder::new( + &manager, + label, + tauri::WebviewUrl::App("toolbar/index.html".into()), + ) + .title("Seelen Fancy Toolbar") + .maximizable(false) + .minimizable(false) + .resizable(false) + .visible(false) + .decorations(false) + .transparent(true) + .shadow(false) + .skip_taskbar(true) + .always_on_top(true) + .owner(&hitbox)? + .build()?, + }; + + window.set_ignore_cursor_events(true)?; + + window.once("store-events-ready", Self::on_store_events_ready); + Ok((window, hitbox)) + } + + fn on_store_events_ready(_: tauri::Event) { + std::thread::spawn(|| -> Result<()> { + let handler = get_app_handle(); + + let desktops = winvd::get_desktops()?; + let current_desktop = winvd::get_current_desktop()?; + + let mut desktops_names = Vec::new(); + for (i, d) in desktops.iter().enumerate() { + if let Ok(name) = d.get_name() { + desktops_names.push(name); + } else { + desktops_names.push(format!("Desktop {}", i + 1)) + } + } + + handler.emit("workspaces-changed", desktops_names)?; + handler.emit("active-workspace-changed", current_desktop.get_index()?)?; + Ok(()) + }); + } +} diff --git a/src/background/seelen_shell/mod.rs b/src/background/seelen_shell/mod.rs index 920b86d3..a26aa436 100644 --- a/src/background/seelen_shell/mod.rs +++ b/src/background/seelen_shell/mod.rs @@ -1,12 +1,12 @@ -use tauri::{AppHandle, Wry}; - -pub struct SeelenShell { - #[allow(dead_code)] - handle: AppHandle, -} - -impl SeelenShell { - pub fn new(handle: AppHandle) -> Self { - Self { handle } - } -} +use tauri::{AppHandle, Wry}; + +pub struct SeelenShell { + #[allow(dead_code)] + handle: AppHandle, +} + +impl SeelenShell { + pub fn new(handle: AppHandle) -> Self { + Self { handle } + } +} diff --git a/src/background/seelen_weg/handler.rs b/src/background/seelen_weg/handler.rs index efdd8e61..b5ed995b 100644 --- a/src/background/seelen_weg/handler.rs +++ b/src/background/seelen_weg/handler.rs @@ -1,83 +1,83 @@ -use image::ImageFormat; -use serde::Deserialize; -use tauri::{command, Emitter}; -use tauri_plugin_shell::ShellExt; - -use crate::{error_handler::Result, seelen::get_app_handle, windows_api::WindowsApi}; -use windows::Win32::{ - Foundation::{HWND, LPARAM, WPARAM}, - UI::WindowsAndMessaging::{PostMessageW, SW_MINIMIZE, SW_RESTORE, WM_CLOSE}, -}; - -use super::SeelenWeg; - -#[derive(Deserialize)] -pub struct Args { - hwnd: isize, - process_hwnd: isize, -} -#[command] -pub fn weg_request_update_previews(hwnds: Vec) -> Result<(), String> { - std::thread::spawn(move || { - for app in hwnds { - if WindowsApi::is_iconic(HWND(app.hwnd)) { - continue; - } - - let temp_dir = std::env::temp_dir(); - let hwnd = HWND(app.process_hwnd); - let image = SeelenWeg::capture_window(hwnd); - if let Some(image) = image { - let mut output_path = temp_dir.clone(); - output_path.push(format!("{}.png", hwnd.0)); - image - .save_with_format(&output_path, ImageFormat::Png) - .expect("could not save image"); - get_app_handle() - .emit(format!("weg-preview-update-{}", hwnd.0).as_str(), ()) - .expect("could not emit event"); - } - } - }); - Ok(()) -} - -#[command] -pub fn weg_close_app(hwnd: isize) -> Result<(), String> { - let hwnd = HWND(hwnd); - unsafe { - match PostMessageW(hwnd, WM_CLOSE, WPARAM(0), LPARAM(0)) { - Ok(()) => Ok(()), - Err(_) => Err("could not close window".to_owned()), - } - } -} - -#[command] -pub fn weg_toggle_window_state(hwnd: isize, exe_path: String) { - std::thread::spawn(move || -> Result<()> { - let hwnd = HWND(hwnd); - - if WindowsApi::is_window(hwnd) { - if WindowsApi::is_cloaked(hwnd)? { - WindowsApi::force_set_foreground(hwnd)?; - return Ok(()); - } - - if WindowsApi::is_iconic(hwnd) { - WindowsApi::show_window(hwnd, SW_RESTORE)?; - } else { - WindowsApi::show_window(hwnd, SW_MINIMIZE)?; - } - } else { - get_app_handle() - .shell() - .command("explorer") - .arg(&exe_path) - .spawn() - .expect("Could not spawn explorer on Opening App Action"); - } - - Ok(()) - }); -} +use image::ImageFormat; +use serde::Deserialize; +use tauri::{command, Emitter}; +use tauri_plugin_shell::ShellExt; + +use crate::{error_handler::Result, seelen::get_app_handle, windows_api::WindowsApi}; +use windows::Win32::{ + Foundation::{HWND, LPARAM, WPARAM}, + UI::WindowsAndMessaging::{PostMessageW, SW_MINIMIZE, SW_RESTORE, WM_CLOSE}, +}; + +use super::SeelenWeg; + +#[derive(Deserialize)] +pub struct Args { + hwnd: isize, + process_hwnd: isize, +} +#[command] +pub fn weg_request_update_previews(hwnds: Vec) -> Result<(), String> { + std::thread::spawn(move || { + for app in hwnds { + if WindowsApi::is_iconic(HWND(app.hwnd)) { + continue; + } + + let temp_dir = std::env::temp_dir(); + let hwnd = HWND(app.process_hwnd); + let image = SeelenWeg::capture_window(hwnd); + if let Some(image) = image { + let mut output_path = temp_dir.clone(); + output_path.push(format!("{}.png", hwnd.0)); + image + .save_with_format(&output_path, ImageFormat::Png) + .expect("could not save image"); + get_app_handle() + .emit(format!("weg-preview-update-{}", hwnd.0).as_str(), ()) + .expect("could not emit event"); + } + } + }); + Ok(()) +} + +#[command] +pub fn weg_close_app(hwnd: isize) -> Result<(), String> { + let hwnd = HWND(hwnd); + unsafe { + match PostMessageW(hwnd, WM_CLOSE, WPARAM(0), LPARAM(0)) { + Ok(()) => Ok(()), + Err(_) => Err("could not close window".to_owned()), + } + } +} + +#[command] +pub fn weg_toggle_window_state(hwnd: isize, exe_path: String) { + std::thread::spawn(move || -> Result<()> { + let hwnd = HWND(hwnd); + + if WindowsApi::is_window(hwnd) { + if WindowsApi::is_cloaked(hwnd)? { + WindowsApi::force_set_foreground(hwnd)?; + return Ok(()); + } + + if WindowsApi::is_iconic(hwnd) { + WindowsApi::show_window(hwnd, SW_RESTORE)?; + } else { + WindowsApi::show_window(hwnd, SW_MINIMIZE)?; + } + } else { + get_app_handle() + .shell() + .command("explorer") + .arg(&exe_path) + .spawn() + .expect("Could not spawn explorer on Opening App Action"); + } + + Ok(()) + }); +} diff --git a/src/background/seelen_weg/hook.rs b/src/background/seelen_weg/hook.rs index 99a93d0e..83bc64c5 100644 --- a/src/background/seelen_weg/hook.rs +++ b/src/background/seelen_weg/hook.rs @@ -1,129 +1,129 @@ -use windows::Win32::{ - Foundation::HWND, - UI::WindowsAndMessaging::{FindWindowExA, EVENT_OBJECT_CREATE, EVENT_OBJECT_SHOW, SW_HIDE}, -}; - -use crate::{error_handler::Result, pcstr, windows_api::WindowsApi, winevent::WinEvent}; - -use super::{SeelenWeg, TASKBAR_CLASS}; - -impl SeelenWeg { - pub fn process_global_win_event(event: WinEvent, origin: HWND) -> Result<()> { - match event { - WinEvent::ObjectShow | WinEvent::ObjectCreate => { - if Self::is_real_window(origin, false) { - Self::add_hwnd(origin); - } - } - WinEvent::ObjectDestroy => { - if Self::contains_app(origin) { - Self::remove_hwnd(origin); - } - } - WinEvent::ObjectHide => { - if Self::contains_app(origin) { - // We filter apps with parents but UWP apps using ApplicationFrameHost.exe are initialized without - // parent so we can't filter it on open event but these are immediately hidden when the ApplicationFrameHost.exe parent - // is assigned to the window. After that we replace the window hwnd to its parent and remove child from the list - let parent = WindowsApi::get_parent(origin); - if parent.0 != 0 { - Self::replace_hwnd(origin, parent)?; - } else { - Self::remove_hwnd(origin); - } - } - } - WinEvent::ObjectNameChange => { - if Self::contains_app(origin) { - Self::update_app(origin); - } else if Self::is_real_window(origin, false) { - Self::add_hwnd(origin); - } - } - WinEvent::SystemForeground | WinEvent::ObjectFocus => { - Self::set_active_window(origin)?; - } - _ => {} - } - Ok(()) - } - - pub fn process_individual_win_event(&mut self, event: WinEvent, origin: HWND) -> Result<()> { - match event { - WinEvent::SystemForeground | WinEvent::ObjectFocus => { - self.handle_overlaped_status(origin)?; - } - WinEvent::ObjectLocationChange => { - if origin == WindowsApi::get_foreground_window() { - self.handle_overlaped_status(origin)?; - } - } - WinEvent::SyntheticFullscreenStart(event_data) => { - let monitor = WindowsApi::monitor_from_window(self.window.hwnd()?); - if monitor == event_data.monitor { - self.hide()?; - } - } - WinEvent::SyntheticFullscreenEnd(event_data) => { - let monitor = WindowsApi::monitor_from_window(self.window.hwnd()?); - if monitor == event_data.monitor { - self.show()?; - self.set_overlaped_status(false)?; - } - } - _ => {} - }; - Ok(()) - } - - pub fn process_raw_win_event(event: u32, origin_hwnd: HWND) -> Result<()> { - match event { - EVENT_OBJECT_SHOW | EVENT_OBJECT_CREATE => { - let class = WindowsApi::get_class(origin_hwnd)?; - let parent_class = - WindowsApi::get_class(WindowsApi::get_parent(origin_hwnd)).unwrap_or_default(); - - if TASKBAR_CLASS - .iter() - .any(|t| t == &class || t == &parent_class) - { - Self::hide_taskbar(); - return Ok(()); - } - - if class.eq("XamlExplorerHostIslandWindow") - && WindowsApi::get_window_text(origin_hwnd).is_empty() - { - let content_hwnd = unsafe { - FindWindowExA( - origin_hwnd, - HWND(0), - pcstr!("Windows.UI.Composition.DesktopWindowContentBridge"), - pcstr!("DesktopWindowXamlSource"), - ) - }; - - if content_hwnd.0 != 0 { - let input_hwnd = unsafe { - FindWindowExA( - content_hwnd, - HWND(0), - pcstr!("Windows.UI.Input.InputSite.WindowClass"), - None, - ) - }; - if input_hwnd.0 != 0 { - // can fail on volume window island - let _ = WindowsApi::show_window(input_hwnd, SW_HIDE); - } - // can fail on volume window island - let _ = WindowsApi::show_window(content_hwnd, SW_HIDE); - } - WindowsApi::show_window(origin_hwnd, SW_HIDE)?; - } - } - _ => {} - } - Ok(()) - } -} +use windows::Win32::{ + Foundation::HWND, + UI::WindowsAndMessaging::{FindWindowExA, EVENT_OBJECT_CREATE, EVENT_OBJECT_SHOW, SW_HIDE}, +}; + +use crate::{error_handler::Result, pcstr, windows_api::WindowsApi, winevent::WinEvent}; + +use super::{SeelenWeg, TASKBAR_CLASS}; + +impl SeelenWeg { + pub fn process_global_win_event(event: WinEvent, origin: HWND) -> Result<()> { + match event { + WinEvent::ObjectShow | WinEvent::ObjectCreate => { + if Self::is_real_window(origin, false) { + Self::add_hwnd(origin); + } + } + WinEvent::ObjectDestroy => { + if Self::contains_app(origin) { + Self::remove_hwnd(origin); + } + } + WinEvent::ObjectHide => { + if Self::contains_app(origin) { + // We filter apps with parents but UWP apps using ApplicationFrameHost.exe are initialized without + // parent so we can't filter it on open event but these are immediately hidden when the ApplicationFrameHost.exe parent + // is assigned to the window. After that we replace the window hwnd to its parent and remove child from the list + let parent = WindowsApi::get_parent(origin); + if parent.0 != 0 { + Self::replace_hwnd(origin, parent)?; + } else { + Self::remove_hwnd(origin); + } + } + } + WinEvent::ObjectNameChange => { + if Self::contains_app(origin) { + Self::update_app(origin); + } else if Self::is_real_window(origin, false) { + Self::add_hwnd(origin); + } + } + WinEvent::SystemForeground | WinEvent::ObjectFocus => { + Self::set_active_window(origin)?; + } + _ => {} + } + Ok(()) + } + + pub fn process_individual_win_event(&mut self, event: WinEvent, origin: HWND) -> Result<()> { + match event { + WinEvent::SystemForeground | WinEvent::ObjectFocus => { + self.handle_overlaped_status(origin)?; + } + WinEvent::ObjectLocationChange => { + if origin == WindowsApi::get_foreground_window() { + self.handle_overlaped_status(origin)?; + } + } + WinEvent::SyntheticFullscreenStart(event_data) => { + let monitor = WindowsApi::monitor_from_window(self.window.hwnd()?); + if monitor == event_data.monitor { + self.hide()?; + } + } + WinEvent::SyntheticFullscreenEnd(event_data) => { + let monitor = WindowsApi::monitor_from_window(self.window.hwnd()?); + if monitor == event_data.monitor { + self.show()?; + self.set_overlaped_status(false)?; + } + } + _ => {} + }; + Ok(()) + } + + pub fn process_raw_win_event(event: u32, origin_hwnd: HWND) -> Result<()> { + match event { + EVENT_OBJECT_SHOW | EVENT_OBJECT_CREATE => { + let class = WindowsApi::get_class(origin_hwnd)?; + let parent_class = + WindowsApi::get_class(WindowsApi::get_parent(origin_hwnd)).unwrap_or_default(); + + if TASKBAR_CLASS + .iter() + .any(|t| t == &class || t == &parent_class) + { + Self::hide_taskbar(); + return Ok(()); + } + + if class.eq("XamlExplorerHostIslandWindow") + && WindowsApi::get_window_text(origin_hwnd).is_empty() + { + let content_hwnd = unsafe { + FindWindowExA( + origin_hwnd, + HWND(0), + pcstr!("Windows.UI.Composition.DesktopWindowContentBridge"), + pcstr!("DesktopWindowXamlSource"), + ) + }; + + if content_hwnd.0 != 0 { + let input_hwnd = unsafe { + FindWindowExA( + content_hwnd, + HWND(0), + pcstr!("Windows.UI.Input.InputSite.WindowClass"), + None, + ) + }; + if input_hwnd.0 != 0 { + // can fail on volume window island + let _ = WindowsApi::show_window(input_hwnd, SW_HIDE); + } + // can fail on volume window island + let _ = WindowsApi::show_window(content_hwnd, SW_HIDE); + } + WindowsApi::show_window(origin_hwnd, SW_HIDE)?; + } + } + _ => {} + } + Ok(()) + } +} diff --git a/src/background/seelen_weg/icon_extractor.rs b/src/background/seelen_weg/icon_extractor.rs index 53c17b84..50e676dd 100644 --- a/src/background/seelen_weg/icon_extractor.rs +++ b/src/background/seelen_weg/icon_extractor.rs @@ -1,205 +1,205 @@ -use color_eyre::eyre::eyre; -use image::ImageBuffer; -use image::RgbaImage; -use itertools::Itertools; -use tauri::AppHandle; -use widestring::U16CString; -use windows::core::PCWSTR; -use windows::Win32::Graphics::Gdi::CreateCompatibleDC; -use windows::Win32::Graphics::Gdi::DeleteDC; -use windows::Win32::Graphics::Gdi::DeleteObject; -use windows::Win32::Graphics::Gdi::GetDIBits; -use windows::Win32::Graphics::Gdi::SelectObject; -use windows::Win32::Graphics::Gdi::BITMAPINFO; -use windows::Win32::Graphics::Gdi::BITMAPINFOHEADER; -use windows::Win32::Graphics::Gdi::DIB_RGB_COLORS; -use windows::Win32::UI::Shell::ExtractIconExW; -use windows::Win32::UI::WindowsAndMessaging::DestroyIcon; -use windows::Win32::UI::WindowsAndMessaging::GetIconInfoExW; -use windows::Win32::UI::WindowsAndMessaging::HICON; -use windows::Win32::UI::WindowsAndMessaging::ICONINFOEXW; - -use std::arch::x86_64::__m128i; -use std::arch::x86_64::_mm_loadu_si128; -use std::arch::x86_64::_mm_setr_epi8; -#[cfg(target_arch = "x86_64")] -use std::arch::x86_64::_mm_shuffle_epi8; -use std::arch::x86_64::_mm_storeu_si128; -use std::path::PathBuf; - -use crate::error_handler::Result; -use crate::modules::uwp::UWP_MANAGER; -use crate::trace_lock; -use crate::utils::app_data_path; - -/// Convert BGRA to RGBA -/// -/// Uses SIMD to go fast -pub fn bgra_to_rgba(data: &mut [u8]) { - // The shuffle mask for converting BGRA -> RGBA - let mask: __m128i = unsafe { - _mm_setr_epi8( - 2, 1, 0, 3, // First pixel - 6, 5, 4, 7, // Second pixel - 10, 9, 8, 11, // Third pixel - 14, 13, 12, 15, // Fourth pixel - ) - }; - // For each 16-byte chunk in your data - for chunk in data.chunks_exact_mut(16) { - let mut vector = unsafe { _mm_loadu_si128(chunk.as_ptr() as *const __m128i) }; - vector = unsafe { _mm_shuffle_epi8(vector, mask) }; - unsafe { _mm_storeu_si128(chunk.as_mut_ptr() as *mut __m128i, vector) }; - } -} - -pub fn get_images_from_exe(executable_path: &str) -> Result> { - unsafe { - let path_cstr = U16CString::from_str(executable_path).map_err(|_| eyre!("Invalid path"))?; - let path_pcwstr = PCWSTR(path_cstr.as_ptr()); - let num_icons_total = ExtractIconExW(path_pcwstr, -1, None, None, 0); - if num_icons_total == 0 { - return Ok(Vec::new()); // No icons extracted - } - - let mut large_icons = vec![HICON::default(); num_icons_total as usize]; - let mut small_icons = vec![HICON::default(); num_icons_total as usize]; - let num_icons_fetched = ExtractIconExW( - path_pcwstr, - 0, - Some(large_icons.as_mut_ptr()), - Some(small_icons.as_mut_ptr()), - num_icons_total, - ); - - if num_icons_fetched == 0 { - return Ok(Vec::new()); // No icons extracted - } - - let images = large_icons - .iter() - .chain(small_icons.iter()) - .map(convert_hicon_to_rgba_image) - .filter_map(|r| match r { - Ok(img) => Some(img), - Err(e) => { - log::error!("Failed to convert HICON to RgbaImage: {:?}", e); - None - } - }) - .collect_vec(); - - large_icons - .iter() - .chain(small_icons.iter()) - .filter(|icon| !icon.is_invalid()) - .map(|icon| DestroyIcon(*icon)) - .filter_map(|r| r.err()) - .for_each(|e| { - log::error!("Failed to destroy icon: {:?}", e); - }); - - Ok(images) - } -} - -pub fn convert_hicon_to_rgba_image(hicon: &HICON) -> Result { - unsafe { - let mut icon_info = ICONINFOEXW { - cbSize: std::mem::size_of::() as u32, - ..Default::default() - }; - - if !GetIconInfoExW(*hicon, &mut icon_info).as_bool() { - return Err(eyre!("Failed to get icon info").into()); - } - let hdc_screen = CreateCompatibleDC(None); - let hdc_mem = CreateCompatibleDC(hdc_screen); - let hbm_old = SelectObject(hdc_mem, icon_info.hbmColor); - - let mut bmp_info = BITMAPINFO { - bmiHeader: BITMAPINFOHEADER { - biSize: std::mem::size_of::() as u32, - biWidth: icon_info.xHotspot as i32 * 2, - biHeight: -(icon_info.yHotspot as i32 * 2), - biPlanes: 1, - biBitCount: 32, - biCompression: DIB_RGB_COLORS.0, - ..Default::default() - }, - ..Default::default() - }; - - let mut buffer: Vec = - vec![0; (icon_info.xHotspot * 2 * icon_info.yHotspot * 2 * 4) as usize]; - - if GetDIBits( - hdc_mem, - icon_info.hbmColor, - 0, - icon_info.yHotspot * 2, - Some(buffer.as_mut_ptr() as *mut _), - &mut bmp_info, - DIB_RGB_COLORS, - ) == 0 - { - return Err(eyre!("Failed to get dibits").into()); - } - // Clean up - SelectObject(hdc_mem, hbm_old); - DeleteDC(hdc_mem).ok()?; - DeleteDC(hdc_screen).ok()?; - DeleteObject(icon_info.hbmColor).ok()?; - DeleteObject(icon_info.hbmMask).ok()?; - - bgra_to_rgba(buffer.as_mut_slice()); - - let image = ImageBuffer::from_raw(icon_info.xHotspot * 2, icon_info.yHotspot * 2, buffer) - .expect("Failed to create image buffer"); - Ok(image) - } -} - -/// returns the path of the icon extracted from the executable or copied if is an UWP app. -/// -/// If the icon already exists, it returns the path instead overriding, this is needed for allow user custom icons. -pub fn extract_and_save_icon(handle: &AppHandle, exe_path: &str) -> Result { - let gen_icons_paths = app_data_path(handle).join("icons"); - if !gen_icons_paths.exists() { - std::fs::create_dir_all(&gen_icons_paths)?; - } - - let path = PathBuf::from(exe_path); - let filename = path - .file_name() - .unwrap_or_default() - .to_string_lossy() - .to_string(); - let saved_icon_path = gen_icons_paths.join(filename.replace(".exe", ".png")); - - if saved_icon_path.exists() { - return Ok(saved_icon_path); - } - - log::trace!("Extracting icon for \"{}\"", filename); - - if let Some(package) = trace_lock!(UWP_MANAGER).get_from_path(&path) { - if let Some(uwp_icon_path) = package.get_light_icon(&filename) { - log::debug!("Copying UWP icon from \"{}\"", uwp_icon_path.display()); - - std::fs::copy(uwp_icon_path, &saved_icon_path)?; - return Ok(saved_icon_path); - } - } - - let images = get_images_from_exe(exe_path); - if let Ok(images) = images { - // icon on index 0 always is the app showed icon - if let Some(icon) = images.first() { - icon.save(&saved_icon_path)?; - return Ok(saved_icon_path); - } - } - - Err("Failed to extract icon".into()) -} +use color_eyre::eyre::eyre; +use image::ImageBuffer; +use image::RgbaImage; +use itertools::Itertools; +use tauri::AppHandle; +use widestring::U16CString; +use windows::core::PCWSTR; +use windows::Win32::Graphics::Gdi::CreateCompatibleDC; +use windows::Win32::Graphics::Gdi::DeleteDC; +use windows::Win32::Graphics::Gdi::DeleteObject; +use windows::Win32::Graphics::Gdi::GetDIBits; +use windows::Win32::Graphics::Gdi::SelectObject; +use windows::Win32::Graphics::Gdi::BITMAPINFO; +use windows::Win32::Graphics::Gdi::BITMAPINFOHEADER; +use windows::Win32::Graphics::Gdi::DIB_RGB_COLORS; +use windows::Win32::UI::Shell::ExtractIconExW; +use windows::Win32::UI::WindowsAndMessaging::DestroyIcon; +use windows::Win32::UI::WindowsAndMessaging::GetIconInfoExW; +use windows::Win32::UI::WindowsAndMessaging::HICON; +use windows::Win32::UI::WindowsAndMessaging::ICONINFOEXW; + +use std::arch::x86_64::__m128i; +use std::arch::x86_64::_mm_loadu_si128; +use std::arch::x86_64::_mm_setr_epi8; +#[cfg(target_arch = "x86_64")] +use std::arch::x86_64::_mm_shuffle_epi8; +use std::arch::x86_64::_mm_storeu_si128; +use std::path::PathBuf; + +use crate::error_handler::Result; +use crate::modules::uwp::UWP_MANAGER; +use crate::trace_lock; +use crate::utils::app_data_path; + +/// Convert BGRA to RGBA +/// +/// Uses SIMD to go fast +pub fn bgra_to_rgba(data: &mut [u8]) { + // The shuffle mask for converting BGRA -> RGBA + let mask: __m128i = unsafe { + _mm_setr_epi8( + 2, 1, 0, 3, // First pixel + 6, 5, 4, 7, // Second pixel + 10, 9, 8, 11, // Third pixel + 14, 13, 12, 15, // Fourth pixel + ) + }; + // For each 16-byte chunk in your data + for chunk in data.chunks_exact_mut(16) { + let mut vector = unsafe { _mm_loadu_si128(chunk.as_ptr() as *const __m128i) }; + vector = unsafe { _mm_shuffle_epi8(vector, mask) }; + unsafe { _mm_storeu_si128(chunk.as_mut_ptr() as *mut __m128i, vector) }; + } +} + +pub fn get_images_from_exe(executable_path: &str) -> Result> { + unsafe { + let path_cstr = U16CString::from_str(executable_path).map_err(|_| eyre!("Invalid path"))?; + let path_pcwstr = PCWSTR(path_cstr.as_ptr()); + let num_icons_total = ExtractIconExW(path_pcwstr, -1, None, None, 0); + if num_icons_total == 0 { + return Ok(Vec::new()); // No icons extracted + } + + let mut large_icons = vec![HICON::default(); num_icons_total as usize]; + let mut small_icons = vec![HICON::default(); num_icons_total as usize]; + let num_icons_fetched = ExtractIconExW( + path_pcwstr, + 0, + Some(large_icons.as_mut_ptr()), + Some(small_icons.as_mut_ptr()), + num_icons_total, + ); + + if num_icons_fetched == 0 { + return Ok(Vec::new()); // No icons extracted + } + + let images = large_icons + .iter() + .chain(small_icons.iter()) + .map(convert_hicon_to_rgba_image) + .filter_map(|r| match r { + Ok(img) => Some(img), + Err(e) => { + log::error!("Failed to convert HICON to RgbaImage: {:?}", e); + None + } + }) + .collect_vec(); + + large_icons + .iter() + .chain(small_icons.iter()) + .filter(|icon| !icon.is_invalid()) + .map(|icon| DestroyIcon(*icon)) + .filter_map(|r| r.err()) + .for_each(|e| { + log::error!("Failed to destroy icon: {:?}", e); + }); + + Ok(images) + } +} + +pub fn convert_hicon_to_rgba_image(hicon: &HICON) -> Result { + unsafe { + let mut icon_info = ICONINFOEXW { + cbSize: std::mem::size_of::() as u32, + ..Default::default() + }; + + if !GetIconInfoExW(*hicon, &mut icon_info).as_bool() { + return Err(eyre!("Failed to get icon info").into()); + } + let hdc_screen = CreateCompatibleDC(None); + let hdc_mem = CreateCompatibleDC(hdc_screen); + let hbm_old = SelectObject(hdc_mem, icon_info.hbmColor); + + let mut bmp_info = BITMAPINFO { + bmiHeader: BITMAPINFOHEADER { + biSize: std::mem::size_of::() as u32, + biWidth: icon_info.xHotspot as i32 * 2, + biHeight: -(icon_info.yHotspot as i32 * 2), + biPlanes: 1, + biBitCount: 32, + biCompression: DIB_RGB_COLORS.0, + ..Default::default() + }, + ..Default::default() + }; + + let mut buffer: Vec = + vec![0; (icon_info.xHotspot * 2 * icon_info.yHotspot * 2 * 4) as usize]; + + if GetDIBits( + hdc_mem, + icon_info.hbmColor, + 0, + icon_info.yHotspot * 2, + Some(buffer.as_mut_ptr() as *mut _), + &mut bmp_info, + DIB_RGB_COLORS, + ) == 0 + { + return Err(eyre!("Failed to get dibits").into()); + } + // Clean up + SelectObject(hdc_mem, hbm_old); + DeleteDC(hdc_mem).ok()?; + DeleteDC(hdc_screen).ok()?; + DeleteObject(icon_info.hbmColor).ok()?; + DeleteObject(icon_info.hbmMask).ok()?; + + bgra_to_rgba(buffer.as_mut_slice()); + + let image = ImageBuffer::from_raw(icon_info.xHotspot * 2, icon_info.yHotspot * 2, buffer) + .expect("Failed to create image buffer"); + Ok(image) + } +} + +/// returns the path of the icon extracted from the executable or copied if is an UWP app. +/// +/// If the icon already exists, it returns the path instead overriding, this is needed for allow user custom icons. +pub fn extract_and_save_icon(handle: &AppHandle, exe_path: &str) -> Result { + let gen_icons_paths = app_data_path(handle).join("icons"); + if !gen_icons_paths.exists() { + std::fs::create_dir_all(&gen_icons_paths)?; + } + + let path = PathBuf::from(exe_path); + let filename = path + .file_name() + .unwrap_or_default() + .to_string_lossy() + .to_string(); + let saved_icon_path = gen_icons_paths.join(filename.replace(".exe", ".png")); + + if saved_icon_path.exists() { + return Ok(saved_icon_path); + } + + log::trace!("Extracting icon for \"{}\"", filename); + + if let Some(package) = trace_lock!(UWP_MANAGER).get_from_path(&path) { + if let Some(uwp_icon_path) = package.get_light_icon(&filename) { + log::debug!("Copying UWP icon from \"{}\"", uwp_icon_path.display()); + + std::fs::copy(uwp_icon_path, &saved_icon_path)?; + return Ok(saved_icon_path); + } + } + + let images = get_images_from_exe(exe_path); + if let Ok(images) = images { + // icon on index 0 always is the app showed icon + if let Some(icon) = images.first() { + icon.save(&saved_icon_path)?; + return Ok(saved_icon_path); + } + } + + Err("Failed to extract icon".into()) +} diff --git a/src/background/seelen_weg/mod.rs b/src/background/seelen_weg/mod.rs index f056b6c8..b02acee2 100644 --- a/src/background/seelen_weg/mod.rs +++ b/src/background/seelen_weg/mod.rs @@ -1,460 +1,460 @@ -pub mod handler; -pub mod hook; -pub mod icon_extractor; - -use std::thread::JoinHandle; - -use getset::{Getters, MutGetters}; -use icon_extractor::extract_and_save_icon; -use image::{DynamicImage, RgbaImage}; -use lazy_static::lazy_static; -use parking_lot::Mutex; -use serde::Serialize; -use tauri::{path::BaseDirectory, Emitter, Listener, Manager, WebviewWindow, Wry}; -use win_screenshot::capture::capture_window; -use windows::Win32::{ - Foundation::{BOOL, HWND, LPARAM, RECT}, - UI::WindowsAndMessaging::{ - EnumWindows, GetParent, HWND_TOPMOST, SWP_NOACTIVATE, SW_HIDE, SW_SHOWNOACTIVATE, - WS_EX_APPWINDOW, WS_EX_NOACTIVATE, WS_EX_TOOLWINDOW, - }, -}; - -use crate::{ - error_handler::Result, - log_error, - modules::uwp::UWP_MANAGER, - seelen::{get_app_handle, SEELEN}, - seelen_bar::FancyToolbar, - state::application::FULL_STATE, - trace_lock, - utils::{are_overlaped, sleep_millis}, - windows_api::{AppBarData, AppBarDataState, WindowsApi}, -}; - -lazy_static! { - static ref TITLE_BLACK_LIST: Vec<&'static str> = Vec::from([ - "", - "Task Switching", - "DesktopWindowXamlSource", - "SeelenWeg", - "SeelenWeg Hitbox", - "Seelen Window Manager", - "Seelen Fancy Toolbar", - "Seelen Fancy Toolbar Hitbox", - "Program Manager", - ]); - static ref OPEN_APPS: Mutex> = Mutex::new(Vec::new()); -} - -static OVERLAP_BLACK_LIST_BY_TITLE: [&str; 7] = [ - "", - "SeelenWeg", - "SeelenWeg Hitbox", - "Seelen Window Manager", - "Seelen Fancy Toolbar", - "Seelen Fancy Toolbar Hitbox", - "Program Manager", -]; - -static OVERLAP_BLACK_LIST_BY_EXE: [&str; 4] = [ - "msedgewebview2.exe", - "SearchHost.exe", - "StartMenuExperienceHost.exe", - "ShellExperienceHost.exe", -]; - -#[derive(Debug, Serialize, Clone)] -pub struct SeelenWegApp { - hwnd: isize, - exe: String, - title: String, - icon_path: String, - execution_path: String, - process_hwnd: isize, -} - -#[derive(Getters, MutGetters)] -pub struct SeelenWeg { - window: WebviewWindow, - hitbox: WebviewWindow, - #[getset(get = "pub")] - ready: bool, - hidden: bool, - overlaped: bool, - last_hitbox_rect: Option, -} - -impl Drop for SeelenWeg { - fn drop(&mut self) { - log::info!("Dropping {}", self.window.label()); - log_error!(self.window.destroy()); - log_error!(self.hitbox.destroy()); - } -} - -// SINGLETON -impl SeelenWeg { - pub fn set_active_window(hwnd: HWND) -> Result<()> { - if WindowsApi::get_window_text(hwnd) == "Task Switching" { - return Ok(()); - } - - let handle = get_app_handle(); - handle.emit("set-focused-handle", hwnd.0)?; - handle.emit( - "set-focused-executable", - WindowsApi::exe(hwnd).unwrap_or_default(), - )?; - Ok(()) - } - - pub fn missing_icon() -> String { - get_app_handle() - .path() - .resolve("static/icons/missing.png", BaseDirectory::Resource) - .expect("Failed to resolve default icon path") - .to_string_lossy() - .to_uppercase() - } - - pub fn extract_icon(exe_path: &str) -> Result { - Ok(extract_and_save_icon(&get_app_handle(), exe_path)? - .to_string_lossy() - .trim_start_matches("\\\\?\\") - .to_string()) - } - - pub fn contains_app(hwnd: HWND) -> bool { - OPEN_APPS - .lock() - .iter() - .any(|app| app.hwnd == hwnd.0 || app.process_hwnd == hwnd.0) - } - - pub fn update_app(hwnd: HWND) { - let mut apps = OPEN_APPS.lock(); - let app = apps.iter_mut().find(|app| app.hwnd == hwnd.0); - if let Some(app) = app { - app.title = WindowsApi::get_window_text(hwnd); - get_app_handle() - .emit("update-open-app-info", app.clone()) - .expect("Failed to emit"); - } - } - - pub fn replace_hwnd(old: HWND, new: HWND) -> Result<()> { - let mut found = None; - let mut apps = OPEN_APPS.lock(); - for app in apps.iter_mut() { - if app.hwnd == old.0 { - app.hwnd = new.0; - found = Some(app.clone()); - break; - } - } - - if let Some(app) = found { - get_app_handle().emit("replace-open-app", app)?; - } - - Ok(()) - } - - pub fn add_hwnd(hwnd: HWND) { - if Self::contains_app(hwnd) { - return; - } - - log::trace!( - "Adding {} <=> {:?}", - hwnd.0, - WindowsApi::get_window_text(hwnd) - ); - - let mut app = SeelenWegApp { - hwnd: hwnd.0, - exe: String::new(), - title: WindowsApi::get_window_text(hwnd), - icon_path: String::new(), - execution_path: String::new(), - process_hwnd: hwnd.0, - }; - - if let Ok(path) = WindowsApi::exe_path_v2(hwnd) { - app.exe = path.to_string_lossy().to_string(); - app.icon_path = if !app.exe.is_empty() { - Self::extract_icon(&app.exe).unwrap_or_else(|_| Self::missing_icon()) - } else { - Self::missing_icon() - }; - - let exe = path - .file_name() - .unwrap_or_default() - .to_string_lossy() - .to_string(); - app.execution_path = match trace_lock!(UWP_MANAGER).get_from_path(&path) { - Some(package) => package - .get_shell_path(&exe) - .unwrap_or_else(|| app.exe.clone()), - None => app.exe.clone(), - }; - } - - get_app_handle() - .emit("add-open-app", app.clone()) - .expect("Failed to emit"); - - OPEN_APPS.lock().push(app); - } - - pub fn remove_hwnd(hwnd: HWND) { - OPEN_APPS.lock().retain(|app| app.hwnd != hwnd.0); - get_app_handle() - .emit("remove-open-app", hwnd.0) - .expect("Failed to emit"); - } - - pub fn is_real_window(hwnd: HWND, ignore_frame: bool) -> bool { - if !WindowsApi::is_window_visible(hwnd) { - return false; - } - - let parent = unsafe { GetParent(hwnd) }; - if parent.0 != 0 { - return false; - } - - let ex_style = WindowsApi::get_ex_styles(hwnd); - if (ex_style.contains(WS_EX_TOOLWINDOW) || ex_style.contains(WS_EX_NOACTIVATE)) - && !ex_style.contains(WS_EX_APPWINDOW) - { - return false; - } - - let exe_path = WindowsApi::exe_path(hwnd).unwrap_or_default(); - if exe_path.starts_with("C:\\Windows\\SystemApps") - || (!ignore_frame && exe_path.ends_with("ApplicationFrameHost.exe")) - { - return false; - } - - let title = WindowsApi::get_window_text(hwnd); - !TITLE_BLACK_LIST.contains(&title.as_str()) - } - - pub fn capture_window(hwnd: HWND) -> Option { - capture_window(hwnd.0).ok().map(|buf| { - let image = RgbaImage::from_raw(buf.width, buf.height, buf.pixels).unwrap_or_default(); - DynamicImage::ImageRgba8(image) - }) - } -} - -// INSTANCE -impl SeelenWeg { - pub fn new(postfix: &str) -> Result { - log::info!("Creating {}/{}", Self::TARGET, postfix); - let (window, hitbox) = Self::create_window(postfix)?; - - let weg = Self { - window, - hitbox, - ready: false, - hidden: false, - overlaped: false, - last_hitbox_rect: None, - }; - - Ok(weg) - } - - pub fn emit(&self, event: &str, payload: S) -> Result<()> { - self.window.emit_to(self.window.label(), event, payload)?; - Ok(()) - } - - pub fn is_overlapping(&self, hwnd: HWND) -> bool { - let rect = WindowsApi::get_window_rect_without_margins(hwnd); - let hitbox_rect = self.last_hitbox_rect.unwrap_or_else(|| { - WindowsApi::get_window_rect_without_margins(HWND( - self.hitbox.hwnd().expect("Failed to get hitbox handle").0, - )) - }); - are_overlaped(&hitbox_rect, &rect) - } - - pub fn set_overlaped_status(&mut self, is_overlaped: bool) -> Result<()> { - if self.overlaped == is_overlaped { - return Ok(()); - } - - self.overlaped = is_overlaped; - self.last_hitbox_rect = if self.overlaped { - Some(WindowsApi::get_window_rect_without_margins(HWND( - self.hitbox.hwnd()?.0, - ))) - } else { - None - }; - - self.emit("set-auto-hide", self.overlaped)?; - Ok(()) - } - - pub fn handle_overlaped_status(&mut self, hwnd: HWND) -> Result<()> { - let should_handle_hidden = self.ready - && WindowsApi::is_window_visible(hwnd) - && !OVERLAP_BLACK_LIST_BY_TITLE.contains(&WindowsApi::get_window_text(hwnd).as_str()) - && !OVERLAP_BLACK_LIST_BY_EXE - .contains(&WindowsApi::exe(hwnd).unwrap_or_default().as_str()); - - if !should_handle_hidden { - return Ok(()); - } - - self.set_overlaped_status(self.is_overlapping(hwnd)) - } - - pub fn hide(&mut self) -> Result<()> { - WindowsApi::show_window_async(self.window.hwnd()?, SW_HIDE)?; - WindowsApi::show_window_async(self.hitbox.hwnd()?, SW_HIDE)?; - self.hidden = true; - Ok(()) - } - - pub fn show(&mut self) -> Result<()> { - WindowsApi::show_window_async(self.window.hwnd()?, SW_SHOWNOACTIVATE)?; - WindowsApi::show_window_async(self.hitbox.hwnd()?, SW_SHOWNOACTIVATE)?; - self.hidden = false; - Ok(()) - } - - pub fn ensure_hitbox_zorder(&self) -> Result<()> { - WindowsApi::bring_to(self.hitbox.hwnd()?, HWND_TOPMOST)?; - self.set_positions(WindowsApi::monitor_from_window(self.window.hwnd()?).0)?; - Ok(()) - } - - pub fn set_positions(&self, monitor_id: isize) -> Result<()> { - let rc_work = FancyToolbar::get_work_area_by_monitor(monitor_id)?; - let main_hwnd = HWND(self.window.hwnd()?.0); - // pre set position before resize in case of multiples dpi - WindowsApi::move_window(main_hwnd, &rc_work)?; - WindowsApi::set_position(main_hwnd, None, &rc_work, SWP_NOACTIVATE)?; - Ok(()) - } -} - -impl SeelenWeg { - const TARGET: &'static str = "seelenweg"; - const TARGET_HITBOX: &'static str = "seelenweg-hitbox"; - - fn create_window(postfix: &str) -> Result<(WebviewWindow, WebviewWindow)> { - let manager = get_app_handle(); - - let hitbox = tauri::WebviewWindowBuilder::new( - &manager, - format!("{}/{}", Self::TARGET_HITBOX, postfix), - tauri::WebviewUrl::App("seelenweg-hitbox/index.html".into()), - ) - .title("SeelenWeg Hitbox") - .maximizable(false) - .minimizable(false) - .resizable(false) - .visible(false) - .decorations(false) - .transparent(true) - .shadow(false) - .skip_taskbar(true) - .always_on_top(true) - .build()?; - - let window = tauri::WebviewWindowBuilder::new( - &manager, - format!("{}/{}", Self::TARGET, postfix), - tauri::WebviewUrl::App("seelenweg/index.html".into()), - ) - .title("SeelenWeg") - .maximizable(false) - .minimizable(false) - .resizable(false) - .visible(false) - .decorations(false) - .transparent(true) - .shadow(false) - .skip_taskbar(true) - .always_on_top(true) - .owner(&hitbox)? - .build()?; - - window.set_ignore_cursor_events(true)?; - - let postfix = postfix.to_string(); - window.once("complete-setup", move |_event| { - std::thread::spawn(move || { - if let Some(monitor) = trace_lock!(SEELEN).monitor_by_name_mut(&postfix) { - if let Some(weg) = monitor.weg_mut() { - weg.ready = true; - } - } - }); - }); - - let label = window.label().to_string(); - window.once("store-events-ready", move |_| { - let handler = get_app_handle(); - let apps = &*OPEN_APPS.lock(); - log_error!(handler.emit_to(label, "add-multiple-open-apps", apps)); - }); - Ok((window, hitbox)) - } - - pub fn hide_taskbar() -> JoinHandle<()> { - std::thread::spawn(move || match get_taskbars_handles() { - Ok(handles) => { - let mut attempts = 0; - while attempts < 10 && FULL_STATE.load().is_weg_enabled() { - for handle in &handles { - AppBarData::from_handle(*handle).set_state(AppBarDataState::AutoHide); - let _ = WindowsApi::show_window(*handle, SW_HIDE); - } - attempts += 1; - sleep_millis(50); - } - } - Err(err) => log::error!("Failed to get taskbars handles: {:?}", err), - }) - } - - pub fn show_taskbar() -> Result<()> { - for hwnd in get_taskbars_handles()? { - AppBarData::from_handle(hwnd).set_state(AppBarDataState::AlwaysOnTop); - WindowsApi::show_window(hwnd, SW_SHOWNOACTIVATE)?; - } - Ok(()) - } -} - -lazy_static! { - pub static ref FOUNDS: Mutex> = Mutex::new(Vec::new()); - pub static ref TASKBAR_CLASS: Vec<&'static str> = - Vec::from(["Shell_TrayWnd", "Shell_SecondaryTrayWnd",]); -} - -unsafe extern "system" fn enum_windows_proc(hwnd: HWND, _: LPARAM) -> BOOL { - let class = WindowsApi::get_class(hwnd).unwrap_or_default(); - if TASKBAR_CLASS.contains(&class.as_str()) { - FOUNDS.lock().push(hwnd); - } - true.into() -} - -pub fn get_taskbars_handles() -> Result> { - unsafe { EnumWindows(Some(enum_windows_proc), LPARAM(0))? }; - let mut found = FOUNDS.lock(); - let result = found.clone(); - found.clear(); - Ok(result) -} +pub mod handler; +pub mod hook; +pub mod icon_extractor; + +use std::thread::JoinHandle; + +use getset::{Getters, MutGetters}; +use icon_extractor::extract_and_save_icon; +use image::{DynamicImage, RgbaImage}; +use lazy_static::lazy_static; +use parking_lot::Mutex; +use serde::Serialize; +use tauri::{path::BaseDirectory, Emitter, Listener, Manager, WebviewWindow, Wry}; +use win_screenshot::capture::capture_window; +use windows::Win32::{ + Foundation::{BOOL, HWND, LPARAM, RECT}, + UI::WindowsAndMessaging::{ + EnumWindows, GetParent, HWND_TOPMOST, SWP_NOACTIVATE, SW_HIDE, SW_SHOWNOACTIVATE, + WS_EX_APPWINDOW, WS_EX_NOACTIVATE, WS_EX_TOOLWINDOW, + }, +}; + +use crate::{ + error_handler::Result, + log_error, + modules::uwp::UWP_MANAGER, + seelen::{get_app_handle, SEELEN}, + seelen_bar::FancyToolbar, + state::application::FULL_STATE, + trace_lock, + utils::{are_overlaped, sleep_millis}, + windows_api::{AppBarData, AppBarDataState, WindowsApi}, +}; + +lazy_static! { + static ref TITLE_BLACK_LIST: Vec<&'static str> = Vec::from([ + "", + "Task Switching", + "DesktopWindowXamlSource", + "SeelenWeg", + "SeelenWeg Hitbox", + "Seelen Window Manager", + "Seelen Fancy Toolbar", + "Seelen Fancy Toolbar Hitbox", + "Program Manager", + ]); + static ref OPEN_APPS: Mutex> = Mutex::new(Vec::new()); +} + +static OVERLAP_BLACK_LIST_BY_TITLE: [&str; 7] = [ + "", + "SeelenWeg", + "SeelenWeg Hitbox", + "Seelen Window Manager", + "Seelen Fancy Toolbar", + "Seelen Fancy Toolbar Hitbox", + "Program Manager", +]; + +static OVERLAP_BLACK_LIST_BY_EXE: [&str; 4] = [ + "msedgewebview2.exe", + "SearchHost.exe", + "StartMenuExperienceHost.exe", + "ShellExperienceHost.exe", +]; + +#[derive(Debug, Serialize, Clone)] +pub struct SeelenWegApp { + hwnd: isize, + exe: String, + title: String, + icon_path: String, + execution_path: String, + process_hwnd: isize, +} + +#[derive(Getters, MutGetters)] +pub struct SeelenWeg { + window: WebviewWindow, + hitbox: WebviewWindow, + #[getset(get = "pub")] + ready: bool, + hidden: bool, + overlaped: bool, + last_hitbox_rect: Option, +} + +impl Drop for SeelenWeg { + fn drop(&mut self) { + log::info!("Dropping {}", self.window.label()); + log_error!(self.window.destroy()); + log_error!(self.hitbox.destroy()); + } +} + +// SINGLETON +impl SeelenWeg { + pub fn set_active_window(hwnd: HWND) -> Result<()> { + if WindowsApi::get_window_text(hwnd) == "Task Switching" { + return Ok(()); + } + + let handle = get_app_handle(); + handle.emit("set-focused-handle", hwnd.0)?; + handle.emit( + "set-focused-executable", + WindowsApi::exe(hwnd).unwrap_or_default(), + )?; + Ok(()) + } + + pub fn missing_icon() -> String { + get_app_handle() + .path() + .resolve("static/icons/missing.png", BaseDirectory::Resource) + .expect("Failed to resolve default icon path") + .to_string_lossy() + .to_uppercase() + } + + pub fn extract_icon(exe_path: &str) -> Result { + Ok(extract_and_save_icon(&get_app_handle(), exe_path)? + .to_string_lossy() + .trim_start_matches("\\\\?\\") + .to_string()) + } + + pub fn contains_app(hwnd: HWND) -> bool { + OPEN_APPS + .lock() + .iter() + .any(|app| app.hwnd == hwnd.0 || app.process_hwnd == hwnd.0) + } + + pub fn update_app(hwnd: HWND) { + let mut apps = OPEN_APPS.lock(); + let app = apps.iter_mut().find(|app| app.hwnd == hwnd.0); + if let Some(app) = app { + app.title = WindowsApi::get_window_text(hwnd); + get_app_handle() + .emit("update-open-app-info", app.clone()) + .expect("Failed to emit"); + } + } + + pub fn replace_hwnd(old: HWND, new: HWND) -> Result<()> { + let mut found = None; + let mut apps = OPEN_APPS.lock(); + for app in apps.iter_mut() { + if app.hwnd == old.0 { + app.hwnd = new.0; + found = Some(app.clone()); + break; + } + } + + if let Some(app) = found { + get_app_handle().emit("replace-open-app", app)?; + } + + Ok(()) + } + + pub fn add_hwnd(hwnd: HWND) { + if Self::contains_app(hwnd) { + return; + } + + log::trace!( + "Adding {} <=> {:?}", + hwnd.0, + WindowsApi::get_window_text(hwnd) + ); + + let mut app = SeelenWegApp { + hwnd: hwnd.0, + exe: String::new(), + title: WindowsApi::get_window_text(hwnd), + icon_path: String::new(), + execution_path: String::new(), + process_hwnd: hwnd.0, + }; + + if let Ok(path) = WindowsApi::exe_path_v2(hwnd) { + app.exe = path.to_string_lossy().to_string(); + app.icon_path = if !app.exe.is_empty() { + Self::extract_icon(&app.exe).unwrap_or_else(|_| Self::missing_icon()) + } else { + Self::missing_icon() + }; + + let exe = path + .file_name() + .unwrap_or_default() + .to_string_lossy() + .to_string(); + app.execution_path = match trace_lock!(UWP_MANAGER).get_from_path(&path) { + Some(package) => package + .get_shell_path(&exe) + .unwrap_or_else(|| app.exe.clone()), + None => app.exe.clone(), + }; + } + + get_app_handle() + .emit("add-open-app", app.clone()) + .expect("Failed to emit"); + + OPEN_APPS.lock().push(app); + } + + pub fn remove_hwnd(hwnd: HWND) { + OPEN_APPS.lock().retain(|app| app.hwnd != hwnd.0); + get_app_handle() + .emit("remove-open-app", hwnd.0) + .expect("Failed to emit"); + } + + pub fn is_real_window(hwnd: HWND, ignore_frame: bool) -> bool { + if !WindowsApi::is_window_visible(hwnd) { + return false; + } + + let parent = unsafe { GetParent(hwnd) }; + if parent.0 != 0 { + return false; + } + + let ex_style = WindowsApi::get_ex_styles(hwnd); + if (ex_style.contains(WS_EX_TOOLWINDOW) || ex_style.contains(WS_EX_NOACTIVATE)) + && !ex_style.contains(WS_EX_APPWINDOW) + { + return false; + } + + let exe_path = WindowsApi::exe_path(hwnd).unwrap_or_default(); + if exe_path.starts_with("C:\\Windows\\SystemApps") + || (!ignore_frame && exe_path.ends_with("ApplicationFrameHost.exe")) + { + return false; + } + + let title = WindowsApi::get_window_text(hwnd); + !TITLE_BLACK_LIST.contains(&title.as_str()) + } + + pub fn capture_window(hwnd: HWND) -> Option { + capture_window(hwnd.0).ok().map(|buf| { + let image = RgbaImage::from_raw(buf.width, buf.height, buf.pixels).unwrap_or_default(); + DynamicImage::ImageRgba8(image) + }) + } +} + +// INSTANCE +impl SeelenWeg { + pub fn new(postfix: &str) -> Result { + log::info!("Creating {}/{}", Self::TARGET, postfix); + let (window, hitbox) = Self::create_window(postfix)?; + + let weg = Self { + window, + hitbox, + ready: false, + hidden: false, + overlaped: false, + last_hitbox_rect: None, + }; + + Ok(weg) + } + + pub fn emit(&self, event: &str, payload: S) -> Result<()> { + self.window.emit_to(self.window.label(), event, payload)?; + Ok(()) + } + + pub fn is_overlapping(&self, hwnd: HWND) -> bool { + let rect = WindowsApi::get_window_rect_without_margins(hwnd); + let hitbox_rect = self.last_hitbox_rect.unwrap_or_else(|| { + WindowsApi::get_window_rect_without_margins(HWND( + self.hitbox.hwnd().expect("Failed to get hitbox handle").0, + )) + }); + are_overlaped(&hitbox_rect, &rect) + } + + pub fn set_overlaped_status(&mut self, is_overlaped: bool) -> Result<()> { + if self.overlaped == is_overlaped { + return Ok(()); + } + + self.overlaped = is_overlaped; + self.last_hitbox_rect = if self.overlaped { + Some(WindowsApi::get_window_rect_without_margins(HWND( + self.hitbox.hwnd()?.0, + ))) + } else { + None + }; + + self.emit("set-auto-hide", self.overlaped)?; + Ok(()) + } + + pub fn handle_overlaped_status(&mut self, hwnd: HWND) -> Result<()> { + let should_handle_hidden = self.ready + && WindowsApi::is_window_visible(hwnd) + && !OVERLAP_BLACK_LIST_BY_TITLE.contains(&WindowsApi::get_window_text(hwnd).as_str()) + && !OVERLAP_BLACK_LIST_BY_EXE + .contains(&WindowsApi::exe(hwnd).unwrap_or_default().as_str()); + + if !should_handle_hidden { + return Ok(()); + } + + self.set_overlaped_status(self.is_overlapping(hwnd)) + } + + pub fn hide(&mut self) -> Result<()> { + WindowsApi::show_window_async(self.window.hwnd()?, SW_HIDE)?; + WindowsApi::show_window_async(self.hitbox.hwnd()?, SW_HIDE)?; + self.hidden = true; + Ok(()) + } + + pub fn show(&mut self) -> Result<()> { + WindowsApi::show_window_async(self.window.hwnd()?, SW_SHOWNOACTIVATE)?; + WindowsApi::show_window_async(self.hitbox.hwnd()?, SW_SHOWNOACTIVATE)?; + self.hidden = false; + Ok(()) + } + + pub fn ensure_hitbox_zorder(&self) -> Result<()> { + WindowsApi::bring_to(self.hitbox.hwnd()?, HWND_TOPMOST)?; + self.set_positions(WindowsApi::monitor_from_window(self.window.hwnd()?).0)?; + Ok(()) + } + + pub fn set_positions(&self, monitor_id: isize) -> Result<()> { + let rc_work = FancyToolbar::get_work_area_by_monitor(monitor_id)?; + let main_hwnd = HWND(self.window.hwnd()?.0); + // pre set position before resize in case of multiples dpi + WindowsApi::move_window(main_hwnd, &rc_work)?; + WindowsApi::set_position(main_hwnd, None, &rc_work, SWP_NOACTIVATE)?; + Ok(()) + } +} + +impl SeelenWeg { + const TARGET: &'static str = "seelenweg"; + const TARGET_HITBOX: &'static str = "seelenweg-hitbox"; + + fn create_window(postfix: &str) -> Result<(WebviewWindow, WebviewWindow)> { + let manager = get_app_handle(); + + let hitbox = tauri::WebviewWindowBuilder::new( + &manager, + format!("{}/{}", Self::TARGET_HITBOX, postfix), + tauri::WebviewUrl::App("seelenweg-hitbox/index.html".into()), + ) + .title("SeelenWeg Hitbox") + .maximizable(false) + .minimizable(false) + .resizable(false) + .visible(false) + .decorations(false) + .transparent(true) + .shadow(false) + .skip_taskbar(true) + .always_on_top(true) + .build()?; + + let window = tauri::WebviewWindowBuilder::new( + &manager, + format!("{}/{}", Self::TARGET, postfix), + tauri::WebviewUrl::App("seelenweg/index.html".into()), + ) + .title("SeelenWeg") + .maximizable(false) + .minimizable(false) + .resizable(false) + .visible(false) + .decorations(false) + .transparent(true) + .shadow(false) + .skip_taskbar(true) + .always_on_top(true) + .owner(&hitbox)? + .build()?; + + window.set_ignore_cursor_events(true)?; + + let postfix = postfix.to_string(); + window.once("complete-setup", move |_event| { + std::thread::spawn(move || { + if let Some(monitor) = trace_lock!(SEELEN).monitor_by_name_mut(&postfix) { + if let Some(weg) = monitor.weg_mut() { + weg.ready = true; + } + } + }); + }); + + let label = window.label().to_string(); + window.once("store-events-ready", move |_| { + let handler = get_app_handle(); + let apps = &*OPEN_APPS.lock(); + log_error!(handler.emit_to(label, "add-multiple-open-apps", apps)); + }); + Ok((window, hitbox)) + } + + pub fn hide_taskbar() -> JoinHandle<()> { + std::thread::spawn(move || match get_taskbars_handles() { + Ok(handles) => { + let mut attempts = 0; + while attempts < 10 && FULL_STATE.load().is_weg_enabled() { + for handle in &handles { + AppBarData::from_handle(*handle).set_state(AppBarDataState::AutoHide); + let _ = WindowsApi::show_window(*handle, SW_HIDE); + } + attempts += 1; + sleep_millis(50); + } + } + Err(err) => log::error!("Failed to get taskbars handles: {:?}", err), + }) + } + + pub fn show_taskbar() -> Result<()> { + for hwnd in get_taskbars_handles()? { + AppBarData::from_handle(hwnd).set_state(AppBarDataState::AlwaysOnTop); + WindowsApi::show_window(hwnd, SW_SHOWNOACTIVATE)?; + } + Ok(()) + } +} + +lazy_static! { + pub static ref FOUNDS: Mutex> = Mutex::new(Vec::new()); + pub static ref TASKBAR_CLASS: Vec<&'static str> = + Vec::from(["Shell_TrayWnd", "Shell_SecondaryTrayWnd",]); +} + +unsafe extern "system" fn enum_windows_proc(hwnd: HWND, _: LPARAM) -> BOOL { + let class = WindowsApi::get_class(hwnd).unwrap_or_default(); + if TASKBAR_CLASS.contains(&class.as_str()) { + FOUNDS.lock().push(hwnd); + } + true.into() +} + +pub fn get_taskbars_handles() -> Result> { + unsafe { EnumWindows(Some(enum_windows_proc), LPARAM(0))? }; + let mut found = FOUNDS.lock(); + let result = found.clone(); + found.clear(); + Ok(result) +} diff --git a/src/background/seelen_wm/cli.rs b/src/background/seelen_wm/cli.rs index d9ba866d..ee9cf85a 100644 --- a/src/background/seelen_wm/cli.rs +++ b/src/background/seelen_wm/cli.rs @@ -1,161 +1,161 @@ -use clap::{Command, ValueEnum}; -use serde::{Deserialize, Serialize}; -use windows::Win32::Foundation::HWND; - -use crate::error_handler::Result; -use crate::get_subcommands; -use crate::seelen::Seelen; -use crate::utils::virtual_desktop::VirtualDesktopManager; -use crate::windows_api::WindowsApi; - -use super::WindowManager; - -#[derive(Debug, Clone, Serialize, Deserialize, ValueEnum)] -pub enum AllowedReservations { - Left, - Right, - Top, - Bottom, - Stack, - Float, -} - -#[derive(Debug, Clone, Serialize, Deserialize, ValueEnum)] -pub enum AllowedFocus { - Left, - Right, - Up, - Down, - Latest, -} - -#[derive(Debug, Clone, Serialize, Deserialize, ValueEnum)] -pub enum Sizing { - Increase, - Decrease, -} - -get_subcommands![ - /** Open Dev Tools (only works if the app is running in dev mode) */ - Debug, - /** Pause the Seelen Window Manager. */ - Pause, - /** Resume the Seelen Window Manager. */ - Resume, - /** Reserve space for a incoming window. */ - Reserve(side: AllowedReservations => "The position of the new window."), - /** Cancels the current reservation */ - CancelReservation, - /** Switches to the specified workspace. */ - SwitchWorkspace(index: usize => "The index of the workspace to switch to."), - /** Moves the window to the specified workspace. */ - MoveToWorkspace(index: usize => "The index of the workspace to switch to."), - /** Sends the window to the specified workspace */ - SendToWorkspace(index: usize => "The index of the workspace to switch to."), - /** Increases or decreases the size of the window */ - Height(action: Sizing => "What to do with the height."), - /** Increases or decreases the size of the window */ - Width(action: Sizing => "What to do with the width."), - /** Resets the size of the containers in current workspace to the default size. */ - ResetWorkspaceSize, - /** Focuses the window in the specified position. */ - Focus(side: AllowedFocus => "The position of the window to focus."), -]; - -impl WindowManager { - pub const CLI_IDENTIFIER: &'static str = "manager"; - - pub fn get_cli() -> Command { - Command::new(Self::CLI_IDENTIFIER) - .about("Manage the Seelen Window Manager.") - .visible_alias("wm") - .arg_required_else_help(true) - .subcommands(SubCommand::commands()) - } - - pub fn reserve(&self, side: AllowedReservations) -> Result<()> { - self.emit("set-reservation", side)?; - Ok(()) - } - - pub fn discard_reservation(&self) -> Result<()> { - self.emit("set-reservation", ())?; - Ok(()) - } - - pub fn process(&mut self, matches: &clap::ArgMatches) -> Result<()> { - let subcommand = SubCommand::try_from(matches)?; - match subcommand { - SubCommand::Pause => { - self.pause(true, true)?; - } - SubCommand::Resume => { - self.pause(false, true)?; - Seelen::start_ahk_shortcuts()?; - } - SubCommand::SwitchWorkspace(index) => { - let desktops = VirtualDesktopManager::enum_virtual_desktops()?; - match desktops.get(index) { - Some(_) => { - self.pseudo_pause()?; - winvd::switch_desktop(index as u32)?; - /* sleep_millis(35); // to ensure avoid any artifacts */ - if let Some(next) = Self::get_next_by_order(HWND(0)) { - WindowsApi::async_force_set_foreground(next); - } - self.pseudo_resume()?; - } - None => log::error!("Invalid workspace index: {}", index), - } - } - SubCommand::SendToWorkspace(index) => { - let desktops = VirtualDesktopManager::enum_virtual_desktops()?; - match desktops.get(index) { - Some(desktop) => { - let to_move = WindowsApi::get_foreground_window(); - winvd::move_window_to_desktop(desktop.guid(), &to_move)?; - if let Some(next) = Self::get_next_by_order(to_move) { - WindowsApi::async_force_set_foreground(next); - } - } - None => log::error!("Invalid workspace index: {}", index), - } - } - SubCommand::MoveToWorkspace(index) => { - let desktops = VirtualDesktopManager::enum_virtual_desktops()?; - match desktops.get(index) { - Some(desktop) => { - let to_move = WindowsApi::get_foreground_window(); - let desktop_guid = desktop.guid(); - winvd::move_window_to_desktop(desktop_guid, &to_move)?; - winvd::switch_desktop(desktop_guid)?; - } - None => log::error!("Invalid workspace index: {}", index), - } - } - SubCommand::Reserve(side) => { - self.reserve(side)?; - } - SubCommand::CancelReservation => { - self.discard_reservation()?; - } - SubCommand::Debug => { - #[cfg(any(debug_assertions, feature = "devtools"))] - self.window.open_devtools(); - } - SubCommand::Height(action) => { - self.emit("update-height", action)?; - } - SubCommand::Width(action) => { - self.emit("update-width", action)?; - } - SubCommand::ResetWorkspaceSize => { - self.emit("reset-workspace-size", ())?; - } - SubCommand::Focus(side) => { - self.emit("focus", side)?; - } - }; - Ok(()) - } -} +use clap::{Command, ValueEnum}; +use serde::{Deserialize, Serialize}; +use windows::Win32::Foundation::HWND; + +use crate::error_handler::Result; +use crate::get_subcommands; +use crate::seelen::Seelen; +use crate::utils::virtual_desktop::VirtualDesktopManager; +use crate::windows_api::WindowsApi; + +use super::WindowManager; + +#[derive(Debug, Clone, Serialize, Deserialize, ValueEnum)] +pub enum AllowedReservations { + Left, + Right, + Top, + Bottom, + Stack, + Float, +} + +#[derive(Debug, Clone, Serialize, Deserialize, ValueEnum)] +pub enum AllowedFocus { + Left, + Right, + Up, + Down, + Latest, +} + +#[derive(Debug, Clone, Serialize, Deserialize, ValueEnum)] +pub enum Sizing { + Increase, + Decrease, +} + +get_subcommands![ + /** Open Dev Tools (only works if the app is running in dev mode) */ + Debug, + /** Pause the Seelen Window Manager. */ + Pause, + /** Resume the Seelen Window Manager. */ + Resume, + /** Reserve space for a incoming window. */ + Reserve(side: AllowedReservations => "The position of the new window."), + /** Cancels the current reservation */ + CancelReservation, + /** Switches to the specified workspace. */ + SwitchWorkspace(index: usize => "The index of the workspace to switch to."), + /** Moves the window to the specified workspace. */ + MoveToWorkspace(index: usize => "The index of the workspace to switch to."), + /** Sends the window to the specified workspace */ + SendToWorkspace(index: usize => "The index of the workspace to switch to."), + /** Increases or decreases the size of the window */ + Height(action: Sizing => "What to do with the height."), + /** Increases or decreases the size of the window */ + Width(action: Sizing => "What to do with the width."), + /** Resets the size of the containers in current workspace to the default size. */ + ResetWorkspaceSize, + /** Focuses the window in the specified position. */ + Focus(side: AllowedFocus => "The position of the window to focus."), +]; + +impl WindowManager { + pub const CLI_IDENTIFIER: &'static str = "manager"; + + pub fn get_cli() -> Command { + Command::new(Self::CLI_IDENTIFIER) + .about("Manage the Seelen Window Manager.") + .visible_alias("wm") + .arg_required_else_help(true) + .subcommands(SubCommand::commands()) + } + + pub fn reserve(&self, side: AllowedReservations) -> Result<()> { + self.emit("set-reservation", side)?; + Ok(()) + } + + pub fn discard_reservation(&self) -> Result<()> { + self.emit("set-reservation", ())?; + Ok(()) + } + + pub fn process(&mut self, matches: &clap::ArgMatches) -> Result<()> { + let subcommand = SubCommand::try_from(matches)?; + match subcommand { + SubCommand::Pause => { + self.pause(true, true)?; + } + SubCommand::Resume => { + self.pause(false, true)?; + Seelen::start_ahk_shortcuts()?; + } + SubCommand::SwitchWorkspace(index) => { + let desktops = VirtualDesktopManager::enum_virtual_desktops()?; + match desktops.get(index) { + Some(_) => { + self.pseudo_pause()?; + winvd::switch_desktop(index as u32)?; + /* sleep_millis(35); // to ensure avoid any artifacts */ + if let Some(next) = Self::get_next_by_order(HWND(0)) { + WindowsApi::async_force_set_foreground(next); + } + self.pseudo_resume()?; + } + None => log::error!("Invalid workspace index: {}", index), + } + } + SubCommand::SendToWorkspace(index) => { + let desktops = VirtualDesktopManager::enum_virtual_desktops()?; + match desktops.get(index) { + Some(desktop) => { + let to_move = WindowsApi::get_foreground_window(); + winvd::move_window_to_desktop(desktop.guid(), &to_move)?; + if let Some(next) = Self::get_next_by_order(to_move) { + WindowsApi::async_force_set_foreground(next); + } + } + None => log::error!("Invalid workspace index: {}", index), + } + } + SubCommand::MoveToWorkspace(index) => { + let desktops = VirtualDesktopManager::enum_virtual_desktops()?; + match desktops.get(index) { + Some(desktop) => { + let to_move = WindowsApi::get_foreground_window(); + let desktop_guid = desktop.guid(); + winvd::move_window_to_desktop(desktop_guid, &to_move)?; + winvd::switch_desktop(desktop_guid)?; + } + None => log::error!("Invalid workspace index: {}", index), + } + } + SubCommand::Reserve(side) => { + self.reserve(side)?; + } + SubCommand::CancelReservation => { + self.discard_reservation()?; + } + SubCommand::Debug => { + #[cfg(any(debug_assertions, feature = "devtools"))] + self.window.open_devtools(); + } + SubCommand::Height(action) => { + self.emit("update-height", action)?; + } + SubCommand::Width(action) => { + self.emit("update-width", action)?; + } + SubCommand::ResetWorkspaceSize => { + self.emit("reset-workspace-size", ())?; + } + SubCommand::Focus(side) => { + self.emit("focus", side)?; + } + }; + Ok(()) + } +} diff --git a/src/background/seelen_wm/handler.rs b/src/background/seelen_wm/handler.rs index e4082ad0..5626df24 100644 --- a/src/background/seelen_wm/handler.rs +++ b/src/background/seelen_wm/handler.rs @@ -1,71 +1,71 @@ -use tauri::{Webview, Wry}; -use windows::Win32::{ - Foundation::{HWND, RECT}, - UI::WindowsAndMessaging::{ - SWP_ASYNCWINDOWPOS, SWP_NOACTIVATE, SWP_NOCOPYBITS, SWP_NOOWNERZORDER, SWP_NOSENDCHANGING, - SWP_NOZORDER, - }, -}; - -use crate::{seelen::SEELEN, trace_lock, utils::rect::Rect, windows_api::WindowsApi}; - -#[tauri::command] -pub fn set_window_position(hwnd: isize, rect: Rect) -> Result<(), String> { - let hwnd = HWND(hwnd); - - if !WindowsApi::is_window(hwnd) || WindowsApi::is_iconic(hwnd) { - return Ok(()); - } - - WindowsApi::unmaximize_window(hwnd)?; - let shadow = WindowsApi::shadow_rect(hwnd)?; - WindowsApi::set_position( - hwnd, - None, - &RECT { - top: rect.top + shadow.top, - left: rect.left + shadow.left, - right: rect.right + shadow.right, - bottom: rect.bottom + shadow.bottom, - }, - SWP_NOACTIVATE - | SWP_NOCOPYBITS - | SWP_NOZORDER - | SWP_NOOWNERZORDER - | SWP_ASYNCWINDOWPOS - | SWP_NOSENDCHANGING, - )?; - Ok(()) -} - -#[tauri::command] -pub fn bounce_handle(webview: Webview, hwnd: isize) { - let monitor_id = webview.label().split("/").last().expect("No monitor ID"); - let monitor_id = monitor_id.parse::().expect("Invalid monitor ID"); - - std::thread::spawn(move || { - if let Some(monitor) = trace_lock!(SEELEN).monitor_by_id_mut(monitor_id) { - if let Some(wm) = monitor.wm_mut() { - wm.bounce_handle(HWND(hwnd)); - } - } - }); -} - -#[tauri::command] -pub fn request_focus(hwnd: isize) -> Result<(), String> { - let hwnd = HWND(hwnd); - log::trace!( - "Requesting focus on {:?} - {} , {:?}", - hwnd, - WindowsApi::get_window_text(hwnd), - WindowsApi::exe(hwnd)?, - ); - - if !WindowsApi::is_window(hwnd) { - return Ok(()); - } - - WindowsApi::force_set_foreground(hwnd)?; - Ok(()) -} +use tauri::{Webview, Wry}; +use windows::Win32::{ + Foundation::{HWND, RECT}, + UI::WindowsAndMessaging::{ + SWP_ASYNCWINDOWPOS, SWP_NOACTIVATE, SWP_NOCOPYBITS, SWP_NOOWNERZORDER, SWP_NOSENDCHANGING, + SWP_NOZORDER, + }, +}; + +use crate::{seelen::SEELEN, trace_lock, utils::rect::Rect, windows_api::WindowsApi}; + +#[tauri::command] +pub fn set_window_position(hwnd: isize, rect: Rect) -> Result<(), String> { + let hwnd = HWND(hwnd); + + if !WindowsApi::is_window(hwnd) || WindowsApi::is_iconic(hwnd) { + return Ok(()); + } + + WindowsApi::unmaximize_window(hwnd)?; + let shadow = WindowsApi::shadow_rect(hwnd)?; + WindowsApi::set_position( + hwnd, + None, + &RECT { + top: rect.top + shadow.top, + left: rect.left + shadow.left, + right: rect.right + shadow.right, + bottom: rect.bottom + shadow.bottom, + }, + SWP_NOACTIVATE + | SWP_NOCOPYBITS + | SWP_NOZORDER + | SWP_NOOWNERZORDER + | SWP_ASYNCWINDOWPOS + | SWP_NOSENDCHANGING, + )?; + Ok(()) +} + +#[tauri::command] +pub fn bounce_handle(webview: Webview, hwnd: isize) { + let monitor_id = webview.label().split("/").last().expect("No monitor ID"); + let monitor_id = monitor_id.parse::().expect("Invalid monitor ID"); + + std::thread::spawn(move || { + if let Some(monitor) = trace_lock!(SEELEN).monitor_by_id_mut(monitor_id) { + if let Some(wm) = monitor.wm_mut() { + wm.bounce_handle(HWND(hwnd)); + } + } + }); +} + +#[tauri::command] +pub fn request_focus(hwnd: isize) -> Result<(), String> { + let hwnd = HWND(hwnd); + log::trace!( + "Requesting focus on {:?} - {} , {:?}", + hwnd, + WindowsApi::get_window_text(hwnd), + WindowsApi::exe(hwnd)?, + ); + + if !WindowsApi::is_window(hwnd) { + return Ok(()); + } + + WindowsApi::force_set_foreground(hwnd)?; + Ok(()) +} diff --git a/src/background/seelen_wm/hook.rs b/src/background/seelen_wm/hook.rs index f24285dc..088c61e9 100644 --- a/src/background/seelen_wm/hook.rs +++ b/src/background/seelen_wm/hook.rs @@ -1,120 +1,120 @@ -use windows::Win32::Foundation::HWND; -use winvd::DesktopEvent; - -use crate::{ - error_handler::Result, - seelen::SEELEN, - trace_lock, - utils::{constants::FORCE_RETILING_AFTER_ADD, sleep_millis}, - windows_api::WindowsApi, - winevent::WinEvent, -}; - -use super::WindowManager; - -impl WindowManager { - pub fn process_vd_event(&mut self, event: &DesktopEvent) -> Result<()> { - match event { - DesktopEvent::DesktopChanged { new, old: _ } => { - self.discard_reservation()?; - self.set_active_workspace(format!("{:?}", new.get_id()?))?; - } - DesktopEvent::WindowChanged(hwnd) => { - if self.is_managed(*hwnd) { - self.update_app(*hwnd)?; - } - } - _ => {} - } - Ok(()) - } - - pub fn process_win_event(&mut self, event: WinEvent, origin: HWND) -> Result<()> { - match event { - WinEvent::SystemMoveSizeStart => { - if self.is_managed(origin) { - self.pseudo_pause()?; - } - } - WinEvent::SystemMoveSizeEnd => { - if self.is_managed(origin) { - self.force_retiling()?; - sleep_millis(35); - self.pseudo_resume()?; - } - } - WinEvent::SystemMinimizeEnd => { - if self.should_be_added(origin) { - self.add_hwnd(origin)?; - } - } - WinEvent::SystemMinimizeStart => { - if self.is_managed(origin) { - self.remove_hwnd(origin)?; - } - } - WinEvent::ObjectHide => { - if self.is_managed(origin) { - self.remove_hwnd(origin)?; - } - } - WinEvent::ObjectDestroy => { - let title = WindowsApi::get_window_text(origin); - if Self::VIRTUAL_PREVIEWS.contains(&title.as_str()) { - self.pseudo_resume()?; - } - if self.is_managed(origin) { - self.remove_hwnd(origin)?; - } - } - WinEvent::ObjectShow | WinEvent::ObjectCreate => { - let title = WindowsApi::get_window_text(origin); - if WindowManager::VIRTUAL_PREVIEWS.contains(&title.as_str()) { - self.pseudo_pause()?; - } - - if self.should_be_added(origin) { - self.set_active_window(origin)?; - if self.add_hwnd(origin)? && FORCE_RETILING_AFTER_ADD.contains(&title) { - // Todo search a better way to do this - std::thread::spawn(|| -> Result<()> { - sleep_millis(250); - if let Some(monitor) = trace_lock!(SEELEN).focused_monitor() { - monitor.wm().as_ref().unwrap().force_retiling()? - } - Ok(()) - }); - }; - } - } - WinEvent::ObjectNameChange => { - if self.should_be_added(origin) { - self.set_active_window(origin)?; - let title = WindowsApi::get_window_text(origin); - if self.add_hwnd(origin)? && FORCE_RETILING_AFTER_ADD.contains(&title) { - // Todo search a better way to do this - std::thread::spawn(|| -> Result<()> { - sleep_millis(250); - if let Some(monitor) = trace_lock!(SEELEN).focused_monitor() { - monitor.wm().as_ref().unwrap().force_retiling()? - } - Ok(()) - }); - }; - } - } - WinEvent::ObjectFocus | WinEvent::SystemForeground => { - self.set_active_window(origin)?; - } - WinEvent::ObjectLocationChange => { - if WindowsApi::is_maximized(origin) { - self.pseudo_pause()?; - } - } - WinEvent::SyntheticFullscreenStart(_) => self.pseudo_pause()?, - WinEvent::SyntheticFullscreenEnd(_) => self.pseudo_resume()?, - _ => {} - }; - Ok(()) - } -} +use windows::Win32::Foundation::HWND; +use winvd::DesktopEvent; + +use crate::{ + error_handler::Result, + seelen::SEELEN, + trace_lock, + utils::{constants::FORCE_RETILING_AFTER_ADD, sleep_millis}, + windows_api::WindowsApi, + winevent::WinEvent, +}; + +use super::WindowManager; + +impl WindowManager { + pub fn process_vd_event(&mut self, event: &DesktopEvent) -> Result<()> { + match event { + DesktopEvent::DesktopChanged { new, old: _ } => { + self.discard_reservation()?; + self.set_active_workspace(format!("{:?}", new.get_id()?))?; + } + DesktopEvent::WindowChanged(hwnd) => { + if self.is_managed(*hwnd) { + self.update_app(*hwnd)?; + } + } + _ => {} + } + Ok(()) + } + + pub fn process_win_event(&mut self, event: WinEvent, origin: HWND) -> Result<()> { + match event { + WinEvent::SystemMoveSizeStart => { + if self.is_managed(origin) { + self.pseudo_pause()?; + } + } + WinEvent::SystemMoveSizeEnd => { + if self.is_managed(origin) { + self.force_retiling()?; + sleep_millis(35); + self.pseudo_resume()?; + } + } + WinEvent::SystemMinimizeEnd => { + if self.should_be_added(origin) { + self.add_hwnd(origin)?; + } + } + WinEvent::SystemMinimizeStart => { + if self.is_managed(origin) { + self.remove_hwnd(origin)?; + } + } + WinEvent::ObjectHide => { + if self.is_managed(origin) { + self.remove_hwnd(origin)?; + } + } + WinEvent::ObjectDestroy => { + let title = WindowsApi::get_window_text(origin); + if Self::VIRTUAL_PREVIEWS.contains(&title.as_str()) { + self.pseudo_resume()?; + } + if self.is_managed(origin) { + self.remove_hwnd(origin)?; + } + } + WinEvent::ObjectShow | WinEvent::ObjectCreate => { + let title = WindowsApi::get_window_text(origin); + if WindowManager::VIRTUAL_PREVIEWS.contains(&title.as_str()) { + self.pseudo_pause()?; + } + + if self.should_be_added(origin) { + self.set_active_window(origin)?; + if self.add_hwnd(origin)? && FORCE_RETILING_AFTER_ADD.contains(&title) { + // Todo search a better way to do this + std::thread::spawn(|| -> Result<()> { + sleep_millis(250); + if let Some(monitor) = trace_lock!(SEELEN).focused_monitor() { + monitor.wm().as_ref().unwrap().force_retiling()? + } + Ok(()) + }); + }; + } + } + WinEvent::ObjectNameChange => { + if self.should_be_added(origin) { + self.set_active_window(origin)?; + let title = WindowsApi::get_window_text(origin); + if self.add_hwnd(origin)? && FORCE_RETILING_AFTER_ADD.contains(&title) { + // Todo search a better way to do this + std::thread::spawn(|| -> Result<()> { + sleep_millis(250); + if let Some(monitor) = trace_lock!(SEELEN).focused_monitor() { + monitor.wm().as_ref().unwrap().force_retiling()? + } + Ok(()) + }); + }; + } + } + WinEvent::ObjectFocus | WinEvent::SystemForeground => { + self.set_active_window(origin)?; + } + WinEvent::ObjectLocationChange => { + if WindowsApi::is_maximized(origin) { + self.pseudo_pause()?; + } + } + WinEvent::SyntheticFullscreenStart(_) => self.pseudo_pause()?, + WinEvent::SyntheticFullscreenEnd(_) => self.pseudo_resume()?, + _ => {} + }; + Ok(()) + } +} diff --git a/src/background/seelen_wm/mod.rs b/src/background/seelen_wm/mod.rs index 848de107..d5c4774f 100644 --- a/src/background/seelen_wm/mod.rs +++ b/src/background/seelen_wm/mod.rs @@ -1,352 +1,352 @@ -pub mod cli; -pub mod handler; -pub mod hook; - -use std::sync::atomic::{AtomicIsize, Ordering}; - -use getset::{Getters, MutGetters}; -use serde::Serialize; -use tauri::{AppHandle, Emitter, Listener, WebviewWindow, Wry}; -use windows::Win32::{ - Foundation::{BOOL, HWND, LPARAM}, - Graphics::Gdi::HMONITOR, - UI::WindowsAndMessaging::{ - EnumWindows, HWND_BOTTOM, HWND_TOPMOST, SWP_NOACTIVATE, WS_CAPTION, WS_EX_TOPMOST, - }, -}; - -use crate::{ - error_handler::Result, - log_error, - seelen::{get_app_handle, SEELEN}, - seelen_bar::FancyToolbar, - seelen_weg::SeelenWeg, - state::{application::FULL_STATE, domain::AppExtraFlag}, - trace_lock, - utils::virtual_desktop::VirtualDesktopManager, - windows_api::WindowsApi, -}; - -#[derive(Serialize, Clone)] -pub struct ManagingApp { - hwnd: isize, - monitor: String, - desktop_id: String, - is_floating: bool, -} - -#[derive(Getters, MutGetters)] -pub struct WindowManager { - window: WebviewWindow, - monitor: HMONITOR, - apps: Vec, - pub current_virtual_desktop: String, - paused: bool, - #[getset(get = "pub")] - ready: bool, -} - -impl Drop for WindowManager { - fn drop(&mut self) { - log::info!("Dropping {}", self.window.label()); - log_error!(self.window.destroy()); - } -} - -impl WindowManager { - pub const TARGET: &'static str = "window-manager"; - pub const VIRTUAL_PREVIEWS: [&'static str; 2] = [ - "Virtual desktop switching preview", - "Virtual desktop hotkey switching preview", - ]; - - pub fn new(monitor: isize) -> Result { - log::info!("Creating Tiling Windows Manager / {}", monitor); - - let handle = get_app_handle(); - - Ok(Self { - window: Self::create_window(&handle, monitor)?, - monitor: HMONITOR(monitor), - apps: Vec::new(), - current_virtual_desktop: VirtualDesktopManager::get_current_virtual_desktop()?.id(), - paused: true, // paused until complete-setup is called - ready: false, - }) - } - - pub fn emit(&self, event: &str, payload: S) -> Result<()> { - self.window.emit_to(self.window.label(), event, payload)?; - Ok(()) - } - - pub fn is_managed(&self, hwnd: HWND) -> bool { - self.get_app(hwnd).is_some() - } - - pub fn is_floating(&self, hwnd: HWND) -> bool { - self.get_app(hwnd) - .map(|app| app.is_floating) - .unwrap_or(false) - } - - pub fn get_app(&self, hwnd: HWND) -> Option<&ManagingApp> { - self.apps.iter().find(|app| app.hwnd == hwnd.0) - } - - pub fn get_app_mut(&mut self, hwnd: HWND) -> Option<&mut ManagingApp> { - self.apps.iter_mut().find(|app| app.hwnd == hwnd.0) - } - - pub fn set_active_window(&mut self, hwnd: HWND) -> Result<()> { - if WindowsApi::get_window_text(hwnd) == "Task Switching" { - return Ok(()); - } - - log::trace!( - "Setting active window to {} <=> {:?}", - hwnd.0, - WindowsApi::get_window_text(hwnd), - ); - - let hwnd = match self.is_managed(hwnd) - && !self.is_floating(hwnd) - && !WindowsApi::is_maximized(hwnd) - { - true => { - self.pseudo_resume()?; - hwnd - } - false => { - self.pseudo_pause()?; - HWND(0) - } - }; - self.emit("set-active-window", hwnd.0)?; - Ok(()) - } - - pub fn set_active_workspace(&mut self, virtual_desktop_id: String) -> Result<()> { - if virtual_desktop_id == self.current_virtual_desktop { - return Ok(()); - } - log::trace!("Setting active workspace to: {}", virtual_desktop_id); - self.current_virtual_desktop = virtual_desktop_id; - self.window - .emit("set-active-workspace", &self.current_virtual_desktop)?; - Ok(()) - } - - pub fn add_hwnd(&mut self, hwnd: HWND) -> Result { - if self.paused || self.is_managed(hwnd) { - return Ok(false); - } - - let desktop_to_add = if WindowsApi::is_cloaked(hwnd)? { - VirtualDesktopManager::get_by_window(hwnd)?.id() - } else { - self.current_virtual_desktop.clone() - }; - - log::trace!( - "Adding {}({}) <=> {:?} on desktop: {}", - WindowsApi::exe(hwnd).unwrap_or_default(), - hwnd.0, - WindowsApi::get_window_text(hwnd), - desktop_to_add - ); - - let mut is_floating = false; - if let Some(config) = FULL_STATE.load().get_app_config_by_window(hwnd) { - is_floating = config.options_contains(AppExtraFlag::Float); - } - - let app = ManagingApp { - hwnd: hwnd.0, - monitor: WindowsApi::monitor_name(WindowsApi::monitor_from_window(hwnd))?, - desktop_id: desktop_to_add, - is_floating, - }; - - self.emit("add-window", &app)?; - self.apps.push(app); - Ok(true) - } - - pub fn update_app(&mut self, hwnd: HWND) -> Result<()> { - if self.paused { - return Ok(()); - } - let app = { - let app = match self.get_app_mut(hwnd) { - Some(app) => app, - None => return Ok(()), - }; - - let current_desktop = VirtualDesktopManager::get_by_window(HWND(app.hwnd))?.id(); - if app.desktop_id != current_desktop { - app.desktop_id = current_desktop; - } - app.clone() - }; - self.emit("update-window", app)?; - Ok(()) - } - - /** triggered when a window is bounced by the front-end on adding action */ - pub fn bounce_handle(&mut self, hwnd: HWND) { - if let Some(app) = self.get_app_mut(hwnd) { - app.is_floating = true; - } - } - - fn remove_hwnd_no_emit(&mut self, hwnd: HWND) -> bool { - if self.paused || !self.is_managed(hwnd) { - return false; - } - self.apps.retain(|x| x.hwnd != hwnd.0); - true - } - - pub fn remove_hwnd(&mut self, hwnd: HWND) -> Result { - if !self.remove_hwnd_no_emit(hwnd) { - return Ok(false); - } - log::trace!( - "Removing {} <=> {:?}", - hwnd.0, - WindowsApi::get_window_text(hwnd) - ); - self.emit("remove-window", hwnd.0)?; - Ok(true) - } - - pub fn force_retiling(&self) -> Result<()> { - log::trace!("Forcing retiling"); - self.emit("force-retiling", ())?; - Ok(()) - } - - pub fn pseudo_pause(&self) -> Result<()> { - WindowsApi::bring_to(self.window.hwnd()?, HWND_BOTTOM) - } - - pub fn pseudo_resume(&self) -> Result<()> { - WindowsApi::bring_to(self.window.hwnd()?, HWND_TOPMOST) - } - - pub fn pause(&mut self, action: bool, visuals: bool) -> Result<()> { - self.paused = action; - if visuals { - match action { - true => self.pseudo_pause()?, - false => self.pseudo_resume()?, - } - } - Ok(()) - } - - pub fn should_be_added(&self, hwnd: HWND) -> bool { - !self.is_managed(hwnd) - && self.monitor == WindowsApi::monitor_from_window(hwnd) - && Self::should_be_managed(hwnd) - } -} - -// UTILS AND STATICS -impl WindowManager { - pub fn should_be_managed(hwnd: HWND) -> bool { - if let Some(config) = FULL_STATE.load().get_app_config_by_window(hwnd) { - return config.options_contains(AppExtraFlag::Force) || { - !config.options_contains(AppExtraFlag::Unmanage) - && !config.options_contains(AppExtraFlag::Pinned) - && Self::is_manageable_window(hwnd, false) - }; - } - Self::is_manageable_window(hwnd, false) - } - - pub fn is_manageable_window(hwnd: HWND, ignore_cloaked: bool) -> bool { - let exe = WindowsApi::exe(hwnd); - - if let Ok(exe) = &exe { - if exe.ends_with("ApplicationFrameHost.exe") && SeelenWeg::is_real_window(hwnd, true) { - return true; - } - } - - // Without admin some apps does not return the exe path so these should be unmanaged - exe.is_ok() - && SeelenWeg::is_real_window(hwnd, true) - // Ignore windows without a title bar, and top most windows normally are widgets or tools so they should not be managed - && (WindowsApi::get_styles(hwnd).contains(WS_CAPTION) && !WindowsApi::get_ex_styles(hwnd).contains(WS_EX_TOPMOST)) - && !WindowsApi::is_iconic(hwnd) - && (ignore_cloaked || !WindowsApi::is_cloaked(hwnd).unwrap_or(false)) - } - - fn create_window(handle: &AppHandle, monitor_id: isize) -> Result { - let work_area = FancyToolbar::get_work_area_by_monitor(monitor_id)?; - - let window = tauri::WebviewWindowBuilder::>::new( - handle, - format!("{}/{}", Self::TARGET, monitor_id), - tauri::WebviewUrl::App("seelen_wm/index.html".into()), - ) - .title("Seelen Window Manager") - .maximizable(false) - .minimizable(false) - .resizable(false) - .visible(true) - .decorations(false) - .transparent(true) - .shadow(false) - .skip_taskbar(true) - .build()?; - - window.set_ignore_cursor_events(true)?; - - let main_hwnd = HWND(window.hwnd()?.0); - WindowsApi::move_window(main_hwnd, &work_area)?; - WindowsApi::set_position(main_hwnd, Some(HWND_TOPMOST), &work_area, SWP_NOACTIVATE)?; - - window.once("complete-setup", move |_event| { - std::thread::spawn(move || -> Result<()> { - if let Some(monitor) = trace_lock!(SEELEN).monitor_by_id_mut(monitor_id) { - if let Some(wm) = monitor.wm_mut() { - wm.paused = false; - wm.ready = true; - wm.window - .emit("set-active-workspace", &wm.current_virtual_desktop)?; - } - } - Ok(()) - }); - }); - - Ok(window) - } - - unsafe extern "system" fn get_next_by_order_proc(hwnd: HWND, lparam: LPARAM) -> BOOL { - // TODO search a way to handle ApplicationFrameHost.exe as well on change of virtual desktop - if WindowManager::is_manageable_window(hwnd, false) - && hwnd.0 != lparam.0 - && !WindowsApi::exe(hwnd).is_ok_and(|exe| &exe == "ApplicationFrameHost.exe") - { - NEXT.store(hwnd.0, Ordering::SeqCst); - return false.into(); - } - true.into() - } - - pub fn get_next_by_order(hwnd: HWND) -> Option { - NEXT.store(0, Ordering::SeqCst); - unsafe { EnumWindows(Some(Self::get_next_by_order_proc), LPARAM(hwnd.0)) }.ok(); - let result = NEXT.load(Ordering::SeqCst); - if result == 0 { - return None; - } - Some(HWND(result)) - } -} - -static NEXT: AtomicIsize = AtomicIsize::new(0); +pub mod cli; +pub mod handler; +pub mod hook; + +use std::sync::atomic::{AtomicIsize, Ordering}; + +use getset::{Getters, MutGetters}; +use serde::Serialize; +use tauri::{AppHandle, Emitter, Listener, WebviewWindow, Wry}; +use windows::Win32::{ + Foundation::{BOOL, HWND, LPARAM}, + Graphics::Gdi::HMONITOR, + UI::WindowsAndMessaging::{ + EnumWindows, HWND_BOTTOM, HWND_TOPMOST, SWP_NOACTIVATE, WS_CAPTION, WS_EX_TOPMOST, + }, +}; + +use crate::{ + error_handler::Result, + log_error, + seelen::{get_app_handle, SEELEN}, + seelen_bar::FancyToolbar, + seelen_weg::SeelenWeg, + state::{application::FULL_STATE, domain::AppExtraFlag}, + trace_lock, + utils::virtual_desktop::VirtualDesktopManager, + windows_api::WindowsApi, +}; + +#[derive(Serialize, Clone)] +pub struct ManagingApp { + hwnd: isize, + monitor: String, + desktop_id: String, + is_floating: bool, +} + +#[derive(Getters, MutGetters)] +pub struct WindowManager { + window: WebviewWindow, + monitor: HMONITOR, + apps: Vec, + pub current_virtual_desktop: String, + paused: bool, + #[getset(get = "pub")] + ready: bool, +} + +impl Drop for WindowManager { + fn drop(&mut self) { + log::info!("Dropping {}", self.window.label()); + log_error!(self.window.destroy()); + } +} + +impl WindowManager { + pub const TARGET: &'static str = "window-manager"; + pub const VIRTUAL_PREVIEWS: [&'static str; 2] = [ + "Virtual desktop switching preview", + "Virtual desktop hotkey switching preview", + ]; + + pub fn new(monitor: isize) -> Result { + log::info!("Creating Tiling Windows Manager / {}", monitor); + + let handle = get_app_handle(); + + Ok(Self { + window: Self::create_window(&handle, monitor)?, + monitor: HMONITOR(monitor), + apps: Vec::new(), + current_virtual_desktop: VirtualDesktopManager::get_current_virtual_desktop()?.id(), + paused: true, // paused until complete-setup is called + ready: false, + }) + } + + pub fn emit(&self, event: &str, payload: S) -> Result<()> { + self.window.emit_to(self.window.label(), event, payload)?; + Ok(()) + } + + pub fn is_managed(&self, hwnd: HWND) -> bool { + self.get_app(hwnd).is_some() + } + + pub fn is_floating(&self, hwnd: HWND) -> bool { + self.get_app(hwnd) + .map(|app| app.is_floating) + .unwrap_or(false) + } + + pub fn get_app(&self, hwnd: HWND) -> Option<&ManagingApp> { + self.apps.iter().find(|app| app.hwnd == hwnd.0) + } + + pub fn get_app_mut(&mut self, hwnd: HWND) -> Option<&mut ManagingApp> { + self.apps.iter_mut().find(|app| app.hwnd == hwnd.0) + } + + pub fn set_active_window(&mut self, hwnd: HWND) -> Result<()> { + if WindowsApi::get_window_text(hwnd) == "Task Switching" { + return Ok(()); + } + + log::trace!( + "Setting active window to {} <=> {:?}", + hwnd.0, + WindowsApi::get_window_text(hwnd), + ); + + let hwnd = match self.is_managed(hwnd) + && !self.is_floating(hwnd) + && !WindowsApi::is_maximized(hwnd) + { + true => { + self.pseudo_resume()?; + hwnd + } + false => { + self.pseudo_pause()?; + HWND(0) + } + }; + self.emit("set-active-window", hwnd.0)?; + Ok(()) + } + + pub fn set_active_workspace(&mut self, virtual_desktop_id: String) -> Result<()> { + if virtual_desktop_id == self.current_virtual_desktop { + return Ok(()); + } + log::trace!("Setting active workspace to: {}", virtual_desktop_id); + self.current_virtual_desktop = virtual_desktop_id; + self.window + .emit("set-active-workspace", &self.current_virtual_desktop)?; + Ok(()) + } + + pub fn add_hwnd(&mut self, hwnd: HWND) -> Result { + if self.paused || self.is_managed(hwnd) { + return Ok(false); + } + + let desktop_to_add = if WindowsApi::is_cloaked(hwnd)? { + VirtualDesktopManager::get_by_window(hwnd)?.id() + } else { + self.current_virtual_desktop.clone() + }; + + log::trace!( + "Adding {}({}) <=> {:?} on desktop: {}", + WindowsApi::exe(hwnd).unwrap_or_default(), + hwnd.0, + WindowsApi::get_window_text(hwnd), + desktop_to_add + ); + + let mut is_floating = false; + if let Some(config) = FULL_STATE.load().get_app_config_by_window(hwnd) { + is_floating = config.options_contains(AppExtraFlag::Float); + } + + let app = ManagingApp { + hwnd: hwnd.0, + monitor: WindowsApi::monitor_name(WindowsApi::monitor_from_window(hwnd))?, + desktop_id: desktop_to_add, + is_floating, + }; + + self.emit("add-window", &app)?; + self.apps.push(app); + Ok(true) + } + + pub fn update_app(&mut self, hwnd: HWND) -> Result<()> { + if self.paused { + return Ok(()); + } + let app = { + let app = match self.get_app_mut(hwnd) { + Some(app) => app, + None => return Ok(()), + }; + + let current_desktop = VirtualDesktopManager::get_by_window(HWND(app.hwnd))?.id(); + if app.desktop_id != current_desktop { + app.desktop_id = current_desktop; + } + app.clone() + }; + self.emit("update-window", app)?; + Ok(()) + } + + /** triggered when a window is bounced by the front-end on adding action */ + pub fn bounce_handle(&mut self, hwnd: HWND) { + if let Some(app) = self.get_app_mut(hwnd) { + app.is_floating = true; + } + } + + fn remove_hwnd_no_emit(&mut self, hwnd: HWND) -> bool { + if self.paused || !self.is_managed(hwnd) { + return false; + } + self.apps.retain(|x| x.hwnd != hwnd.0); + true + } + + pub fn remove_hwnd(&mut self, hwnd: HWND) -> Result { + if !self.remove_hwnd_no_emit(hwnd) { + return Ok(false); + } + log::trace!( + "Removing {} <=> {:?}", + hwnd.0, + WindowsApi::get_window_text(hwnd) + ); + self.emit("remove-window", hwnd.0)?; + Ok(true) + } + + pub fn force_retiling(&self) -> Result<()> { + log::trace!("Forcing retiling"); + self.emit("force-retiling", ())?; + Ok(()) + } + + pub fn pseudo_pause(&self) -> Result<()> { + WindowsApi::bring_to(self.window.hwnd()?, HWND_BOTTOM) + } + + pub fn pseudo_resume(&self) -> Result<()> { + WindowsApi::bring_to(self.window.hwnd()?, HWND_TOPMOST) + } + + pub fn pause(&mut self, action: bool, visuals: bool) -> Result<()> { + self.paused = action; + if visuals { + match action { + true => self.pseudo_pause()?, + false => self.pseudo_resume()?, + } + } + Ok(()) + } + + pub fn should_be_added(&self, hwnd: HWND) -> bool { + !self.is_managed(hwnd) + && self.monitor == WindowsApi::monitor_from_window(hwnd) + && Self::should_be_managed(hwnd) + } +} + +// UTILS AND STATICS +impl WindowManager { + pub fn should_be_managed(hwnd: HWND) -> bool { + if let Some(config) = FULL_STATE.load().get_app_config_by_window(hwnd) { + return config.options_contains(AppExtraFlag::Force) || { + !config.options_contains(AppExtraFlag::Unmanage) + && !config.options_contains(AppExtraFlag::Pinned) + && Self::is_manageable_window(hwnd, false) + }; + } + Self::is_manageable_window(hwnd, false) + } + + pub fn is_manageable_window(hwnd: HWND, ignore_cloaked: bool) -> bool { + let exe = WindowsApi::exe(hwnd); + + if let Ok(exe) = &exe { + if exe.ends_with("ApplicationFrameHost.exe") && SeelenWeg::is_real_window(hwnd, true) { + return true; + } + } + + // Without admin some apps does not return the exe path so these should be unmanaged + exe.is_ok() + && SeelenWeg::is_real_window(hwnd, true) + // Ignore windows without a title bar, and top most windows normally are widgets or tools so they should not be managed + && (WindowsApi::get_styles(hwnd).contains(WS_CAPTION) && !WindowsApi::get_ex_styles(hwnd).contains(WS_EX_TOPMOST)) + && !WindowsApi::is_iconic(hwnd) + && (ignore_cloaked || !WindowsApi::is_cloaked(hwnd).unwrap_or(false)) + } + + fn create_window(handle: &AppHandle, monitor_id: isize) -> Result { + let work_area = FancyToolbar::get_work_area_by_monitor(monitor_id)?; + + let window = tauri::WebviewWindowBuilder::>::new( + handle, + format!("{}/{}", Self::TARGET, monitor_id), + tauri::WebviewUrl::App("seelen_wm/index.html".into()), + ) + .title("Seelen Window Manager") + .maximizable(false) + .minimizable(false) + .resizable(false) + .visible(true) + .decorations(false) + .transparent(true) + .shadow(false) + .skip_taskbar(true) + .build()?; + + window.set_ignore_cursor_events(true)?; + + let main_hwnd = HWND(window.hwnd()?.0); + WindowsApi::move_window(main_hwnd, &work_area)?; + WindowsApi::set_position(main_hwnd, Some(HWND_TOPMOST), &work_area, SWP_NOACTIVATE)?; + + window.once("complete-setup", move |_event| { + std::thread::spawn(move || -> Result<()> { + if let Some(monitor) = trace_lock!(SEELEN).monitor_by_id_mut(monitor_id) { + if let Some(wm) = monitor.wm_mut() { + wm.paused = false; + wm.ready = true; + wm.window + .emit("set-active-workspace", &wm.current_virtual_desktop)?; + } + } + Ok(()) + }); + }); + + Ok(window) + } + + unsafe extern "system" fn get_next_by_order_proc(hwnd: HWND, lparam: LPARAM) -> BOOL { + // TODO search a way to handle ApplicationFrameHost.exe as well on change of virtual desktop + if WindowManager::is_manageable_window(hwnd, false) + && hwnd.0 != lparam.0 + && !WindowsApi::exe(hwnd).is_ok_and(|exe| &exe == "ApplicationFrameHost.exe") + { + NEXT.store(hwnd.0, Ordering::SeqCst); + return false.into(); + } + true.into() + } + + pub fn get_next_by_order(hwnd: HWND) -> Option { + NEXT.store(0, Ordering::SeqCst); + unsafe { EnumWindows(Some(Self::get_next_by_order_proc), LPARAM(hwnd.0)) }.ok(); + let result = NEXT.load(Ordering::SeqCst); + if result == 0 { + return None; + } + Some(HWND(result)) + } +} + +static NEXT: AtomicIsize = AtomicIsize::new(0); diff --git a/src/background/state/application/apps_config.rs b/src/background/state/application/apps_config.rs index 733e3d4b..a2e57e08 100644 --- a/src/background/state/application/apps_config.rs +++ b/src/background/state/application/apps_config.rs @@ -1,134 +1,134 @@ -use lazy_static::lazy_static; -use parking_lot::Mutex; -use regex::Regex; -use std::{collections::HashMap, sync::Arc}; -use windows::Win32::Foundation::HWND; - -use crate::{ - state::domain::{AppConfig, AppExtraFlag, AppIdentifier, AppIdentifierType, MatchingStrategy}, - trace_lock, - windows_api::WindowsApi, -}; - -use super::FullState; - -lazy_static! { - pub static ref REGEX_IDENTIFIERS: Arc>> = - Arc::new(Mutex::new(HashMap::new())); -} - -impl AppIdentifier { - pub fn cache_regex(&self) { - if matches!(self.matching_strategy, MatchingStrategy::Regex) { - let result = Regex::new(&self.id); - if let Ok(re) = result { - let mut regex_identifiers = trace_lock!(REGEX_IDENTIFIERS); - regex_identifiers.insert(self.id.clone(), re); - } - } - } - - pub fn validate(&self, title: &str, class: &str, exe: &str, path: &str) -> bool { - let mut self_result = match self.matching_strategy { - MatchingStrategy::Legacy | MatchingStrategy::Equals => match self.kind { - AppIdentifierType::Title => title.eq(&self.id), - AppIdentifierType::Class => class.eq(&self.id), - AppIdentifierType::Exe => exe.eq(&self.id), - AppIdentifierType::Path => path.eq(&self.id), - }, - MatchingStrategy::StartsWith => match self.kind { - AppIdentifierType::Title => title.starts_with(&self.id), - AppIdentifierType::Class => class.starts_with(&self.id), - AppIdentifierType::Exe => exe.starts_with(&self.id), - AppIdentifierType::Path => path.starts_with(&self.id), - }, - MatchingStrategy::EndsWith => match self.kind { - AppIdentifierType::Title => title.ends_with(&self.id), - AppIdentifierType::Class => class.ends_with(&self.id), - AppIdentifierType::Exe => exe.ends_with(&self.id), - AppIdentifierType::Path => path.ends_with(&self.id), - }, - MatchingStrategy::Contains => match self.kind { - AppIdentifierType::Title => title.contains(&self.id), - AppIdentifierType::Class => class.contains(&self.id), - AppIdentifierType::Exe => exe.contains(&self.id), - AppIdentifierType::Path => path.contains(&self.id), - }, - MatchingStrategy::Regex => match trace_lock!(REGEX_IDENTIFIERS).get(&self.id) { - Some(re) => match self.kind { - AppIdentifierType::Title => re.is_match(title), - AppIdentifierType::Class => re.is_match(class), - AppIdentifierType::Exe => re.is_match(exe), - AppIdentifierType::Path => re.is_match(path), - }, - None => false, - }, - }; - - if self.negation { - self_result = !self_result; - } - - (self_result && { - self.and - .iter() - .all(|and| and.validate(title, class, exe, path)) - }) || { - self.or - .iter() - .any(|or| or.validate(title, class, exe, path)) - } - } -} - -impl AppConfig { - pub fn match_window(&self, hwnd: HWND) -> bool { - if let (title, Ok(path), Ok(exe), Ok(class)) = ( - WindowsApi::get_window_text(hwnd), - WindowsApi::exe_path(hwnd), - WindowsApi::exe(hwnd), - WindowsApi::get_class(hwnd), - ) { - return self.identifier.validate(&title, &class, &exe, &path); - } - false - } - - pub fn options_contains(&self, option: AppExtraFlag) -> bool { - self.options.contains(&option) - } -} - -impl FullState { - pub fn get_app_config_by_window(&self, hwnd: HWND) -> Option<&AppConfig> { - // Can no cache apps that changes titles - /* match self.cache.entry(hwnd.0) { - Entry::Occupied(entry) => entry.get().and_then(|index| self.apps.get(index)), - Entry::Vacant(entry) => { - for (i, app) in self.apps.iter().enumerate() { - if app.match_window(hwnd) { - entry.insert(Some(i)); - return Option::from(app); - } - } - entry.insert(None); - None - } - } */ - - if let (title, Ok(path), Ok(exe), Ok(class)) = ( - WindowsApi::get_window_text(hwnd), - WindowsApi::exe_path(hwnd), - WindowsApi::exe(hwnd), - WindowsApi::get_class(hwnd), - ) { - for app in self.settings_by_app.iter() { - if app.identifier.validate(&title, &class, &exe, &path) { - return Option::from(app); - } - } - } - - None - } -} +use lazy_static::lazy_static; +use parking_lot::Mutex; +use regex::Regex; +use std::{collections::HashMap, sync::Arc}; +use windows::Win32::Foundation::HWND; + +use crate::{ + state::domain::{AppConfig, AppExtraFlag, AppIdentifier, AppIdentifierType, MatchingStrategy}, + trace_lock, + windows_api::WindowsApi, +}; + +use super::FullState; + +lazy_static! { + pub static ref REGEX_IDENTIFIERS: Arc>> = + Arc::new(Mutex::new(HashMap::new())); +} + +impl AppIdentifier { + pub fn cache_regex(&self) { + if matches!(self.matching_strategy, MatchingStrategy::Regex) { + let result = Regex::new(&self.id); + if let Ok(re) = result { + let mut regex_identifiers = trace_lock!(REGEX_IDENTIFIERS); + regex_identifiers.insert(self.id.clone(), re); + } + } + } + + pub fn validate(&self, title: &str, class: &str, exe: &str, path: &str) -> bool { + let mut self_result = match self.matching_strategy { + MatchingStrategy::Legacy | MatchingStrategy::Equals => match self.kind { + AppIdentifierType::Title => title.eq(&self.id), + AppIdentifierType::Class => class.eq(&self.id), + AppIdentifierType::Exe => exe.eq(&self.id), + AppIdentifierType::Path => path.eq(&self.id), + }, + MatchingStrategy::StartsWith => match self.kind { + AppIdentifierType::Title => title.starts_with(&self.id), + AppIdentifierType::Class => class.starts_with(&self.id), + AppIdentifierType::Exe => exe.starts_with(&self.id), + AppIdentifierType::Path => path.starts_with(&self.id), + }, + MatchingStrategy::EndsWith => match self.kind { + AppIdentifierType::Title => title.ends_with(&self.id), + AppIdentifierType::Class => class.ends_with(&self.id), + AppIdentifierType::Exe => exe.ends_with(&self.id), + AppIdentifierType::Path => path.ends_with(&self.id), + }, + MatchingStrategy::Contains => match self.kind { + AppIdentifierType::Title => title.contains(&self.id), + AppIdentifierType::Class => class.contains(&self.id), + AppIdentifierType::Exe => exe.contains(&self.id), + AppIdentifierType::Path => path.contains(&self.id), + }, + MatchingStrategy::Regex => match trace_lock!(REGEX_IDENTIFIERS).get(&self.id) { + Some(re) => match self.kind { + AppIdentifierType::Title => re.is_match(title), + AppIdentifierType::Class => re.is_match(class), + AppIdentifierType::Exe => re.is_match(exe), + AppIdentifierType::Path => re.is_match(path), + }, + None => false, + }, + }; + + if self.negation { + self_result = !self_result; + } + + (self_result && { + self.and + .iter() + .all(|and| and.validate(title, class, exe, path)) + }) || { + self.or + .iter() + .any(|or| or.validate(title, class, exe, path)) + } + } +} + +impl AppConfig { + pub fn match_window(&self, hwnd: HWND) -> bool { + if let (title, Ok(path), Ok(exe), Ok(class)) = ( + WindowsApi::get_window_text(hwnd), + WindowsApi::exe_path(hwnd), + WindowsApi::exe(hwnd), + WindowsApi::get_class(hwnd), + ) { + return self.identifier.validate(&title, &class, &exe, &path); + } + false + } + + pub fn options_contains(&self, option: AppExtraFlag) -> bool { + self.options.contains(&option) + } +} + +impl FullState { + pub fn get_app_config_by_window(&self, hwnd: HWND) -> Option<&AppConfig> { + // Can no cache apps that changes titles + /* match self.cache.entry(hwnd.0) { + Entry::Occupied(entry) => entry.get().and_then(|index| self.apps.get(index)), + Entry::Vacant(entry) => { + for (i, app) in self.apps.iter().enumerate() { + if app.match_window(hwnd) { + entry.insert(Some(i)); + return Option::from(app); + } + } + entry.insert(None); + None + } + } */ + + if let (title, Ok(path), Ok(exe), Ok(class)) = ( + WindowsApi::get_window_text(hwnd), + WindowsApi::exe_path(hwnd), + WindowsApi::exe(hwnd), + WindowsApi::get_class(hwnd), + ) { + for app in self.settings_by_app.iter() { + if app.identifier.validate(&title, &class, &exe, &path) { + return Option::from(app); + } + } + } + + None + } +} diff --git a/src/background/state/application/mod.rs b/src/background/state/application/mod.rs index 14ee46f0..ed33ff20 100644 --- a/src/background/state/application/mod.rs +++ b/src/background/state/application/mod.rs @@ -1,407 +1,407 @@ -mod apps_config; - -use arc_swap::ArcSwap; -use getset::Getters; -use itertools::Itertools; -use lazy_static::lazy_static; -use notify::{RecursiveMode, Watcher}; -use serde::Serialize; -use std::{ - collections::{HashMap, VecDeque}, - path::{Path, PathBuf}, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - }, -}; -use tauri::{AppHandle, Emitter, Manager}; - -use crate::{ - error_handler::Result, - log_error, - modules::cli::domain::Resource, - seelen::{get_app_handle, SEELEN}, - trace_lock, - windows_api::WindowsApi, -}; - -use super::{ - application::apps_config::REGEX_IDENTIFIERS, - domain::{AppConfig, Placeholder, Settings, Theme, WegItems}, -}; - -lazy_static! { - pub static ref FULL_STATE: Arc> = Arc::new(ArcSwap::from_pointee( - FullState::new().expect("Failed to create State Manager") - )); -} - -#[derive(Getters, Debug, Clone, Serialize)] -pub struct FullState { - #[serde(skip)] - handle: AppHandle, - #[serde(skip)] - data_dir: PathBuf, - #[serde(skip)] - resources_dir: PathBuf, - // ======== data ======== - #[getset(get = "pub")] - settings: Settings, - #[getset(get = "pub")] - settings_by_app: VecDeque, - #[getset(get = "pub")] - themes: HashMap, - #[getset(get = "pub")] - placeholders: HashMap, - #[getset(get = "pub")] - weg_items: WegItems, -} - -static FILE_LISTENER_PAUSED: AtomicBool = AtomicBool::new(false); - -impl FullState { - fn new() -> Result { - let handle = get_app_handle(); - let mut manager = Self { - data_dir: handle.path().app_data_dir()?, - resources_dir: handle.path().resource_dir()?, - handle, - // ======== data ======== - settings: Settings::default(), - settings_by_app: VecDeque::new(), - themes: HashMap::new(), - placeholders: HashMap::new(), - weg_items: serde_yaml::Value::Null, - }; - manager.load_all()?; - manager.start_listeners()?; - Ok(manager) - } - - /// shorthand of `FullState::clone` on Arc reference - pub fn cloned(&self) -> Self { - self.clone() - } - - /// store `self` as the static `FULL_STATE` instance - pub fn store(self) { - FULL_STATE.store(Arc::new(self)); - } - - pub fn settings_path(&self) -> PathBuf { - self.data_dir.join("settings.json") - } - - fn process_event(&mut self, event: notify::Event) -> Result<()> { - let weg_items_path = self.data_dir.join("seelenweg_items.yaml"); - - let user_themes = self.data_dir.join("themes"); - let bundled_themes = self.resources_dir.join("static/themes"); - - let user_placeholders = self.data_dir.join("placeholders"); - let bundled_placeholders = self.resources_dir.join("static/placeholders"); - - let user_app_configs = self.data_dir.join("applications.yml"); - let bundled_app_configs = self.resources_dir.join("static/apps_templates"); - - if event.paths.contains(&weg_items_path) { - log::info!("Weg Items changed: {:?}", event.paths); - self.load_weg_items()?; - self.emit_weg_items()?; - } - - if event.paths.contains(&self.settings_path()) { - log::info!("Seelen Settings changed: {:?}", event.paths); - self.load_settings()?; - self.emit_settings()?; - } - - if event - .paths - .iter() - .any(|p| p.starts_with(&user_themes) || p.starts_with(&bundled_themes)) - { - log::info!("Theme changed: {:?}", event.paths); - self.load_themes()?; - self.emit_themes()?; - } - - if event - .paths - .iter() - .any(|p| p.starts_with(&user_placeholders) || p.starts_with(&bundled_placeholders)) - { - log::info!("Placeholder changed: {:?}", event.paths); - self.load_placeholders()?; - self.emit_placeholders()?; - } - - if event - .paths - .iter() - .any(|p| p.starts_with(&user_app_configs) || p.starts_with(&bundled_app_configs)) - { - log::info!("Specific App Configuration changed: {:?}", event.paths); - self.load_settings_by_app()?; - self.emit_settings_by_app()?; - } - - Ok(()) - } - - fn start_listeners(&mut self) -> Result<()> { - let (tx, rx) = crossbeam_channel::unbounded(); - - let mut watcher = notify::recommended_watcher(tx)?; - - watcher.watch(&self.data_dir, RecursiveMode::Recursive)?; - watcher.watch(&self.resources_dir, RecursiveMode::Recursive)?; - - std::thread::spawn(move || { - let _watcher = watcher; - for event in rx { - match event { - Ok(event) => { - if !FILE_LISTENER_PAUSED.load(Ordering::Acquire) { - let mut state = FULL_STATE.load().cloned(); - log_error!(state.process_event(event)); - state.store(); - } - } - Err(e) => log::error!("Seelen UI Data Watcher error: {:?}", e), - } - } - }); - - log::trace!("Seelen UI Data Watcher started!"); - Ok(()) - } - - fn load_settings(&mut self) -> Result<()> { - let path = self.settings_path(); - if path.exists() { - self.settings = serde_json::from_str(&std::fs::read_to_string(&path)?)?; - } - Ok(()) - } - - fn load_weg_items(&mut self) -> Result<()> { - let path = self.data_dir.join("seelenweg_items.yaml"); - self.weg_items = if !path.exists() { - serde_yaml::Value::Null - } else { - serde_yaml::from_str(&std::fs::read_to_string(&path)?)? - }; - Ok(()) - } - - fn load_theme_from_file(path: PathBuf) -> Result { - match path.extension() { - Some(ext) if ext == "yml" || ext == "yaml" => { - Ok(serde_yaml::from_str(&std::fs::read_to_string(&path)?)?) - } - _ => Err("Invalid theme file extension".into()), - } - } - - fn load_theme_from_dir(path: PathBuf) -> Result { - let file = path.join("theme.yml"); - if !file.exists() { - return Err("theme.yml not found".into()); - } - - let mut theme = Self::load_theme_from_file(file)?; - - if path.join("theme.weg.css").exists() { - theme.styles.weg = std::fs::read_to_string(path.join("theme.weg.css"))?; - } - - if path.join("theme.toolbar.css").exists() { - theme.styles.toolbar = std::fs::read_to_string(path.join("theme.toolbar.css"))?; - } - - if path.join("theme.wm.css").exists() { - theme.styles.wm = std::fs::read_to_string(path.join("theme.wm.css"))?; - } - - Ok(theme) - } - - fn load_themes(&mut self) -> Result<()> { - let user_path = self.data_dir.join("themes"); - let resources_path = self.resources_dir.join("static/themes"); - let entries = std::fs::read_dir(&resources_path)?.chain(std::fs::read_dir(&user_path)?); - for entry in entries.flatten() { - let path = entry.path(); - let theme = if path.is_dir() { - Self::load_theme_from_dir(path) - } else { - Self::load_theme_from_file(path) - }; - match theme { - Ok(mut theme) => { - theme.info.filename = entry.file_name().to_string_lossy().to_string(); - self.themes.insert(theme.info.filename.clone(), theme); - } - Err(err) => log::error!("Failed to load theme ({:?}): {:?}", entry.path(), err), - } - } - Ok(()) - } - - fn load_placeholder_from_file(path: PathBuf) -> Result { - match path.extension() { - Some(ext) if ext == "yml" || ext == "yaml" => { - Ok(serde_yaml::from_str(&std::fs::read_to_string(&path)?)?) - } - _ => Err("Invalid placeholder file extension".into()), - } - } - - fn load_placeholders(&mut self) -> Result<()> { - let user_path = self.data_dir.join("placeholders"); - let resources_path = self.resources_dir.join("static/placeholders"); - let entries = std::fs::read_dir(&resources_path)?.chain(std::fs::read_dir(&user_path)?); - for entry in entries.flatten() { - let path = entry.path(); - if path.is_dir() { - continue; - } - - let placeholder = Self::load_placeholder_from_file(path); - - match placeholder { - Ok(mut placeholder) => { - placeholder.info.filename = entry.file_name().to_string_lossy().to_string(); - self.placeholders - .insert(placeholder.info.filename.clone(), placeholder); - } - Err(err) => { - log::error!("Failed to load placeholder ({:?}): {:?}", entry.path(), err) - } - } - } - Ok(()) - } - - fn load_settings_by_app(&mut self) -> Result<()> { - let user_apps_path = self.data_dir.join("applications.yml"); - let apps_templates_path = self.resources_dir.join("static/apps_templates"); - - trace_lock!(REGEX_IDENTIFIERS).clear(); - self.settings_by_app.clear(); - - if user_apps_path.exists() { - let content = std::fs::read_to_string(&user_apps_path)?; - let apps: Vec = serde_yaml::from_str(&content)?; - self.settings_by_app.extend(apps); - } - - for entry in apps_templates_path.read_dir()?.flatten() { - let content = std::fs::read_to_string(entry.path())?; - let mut apps: Vec = serde_yaml::from_str(&content)?; - for app in apps.iter_mut() { - app.is_bundled = true; - } - self.settings_by_app.extend(apps); - } - - self.settings_by_app - .iter() - .for_each(|app| app.identifier.cache_regex()); - Ok(()) - } - - fn load_all(&mut self) -> Result<()> { - self.load_settings()?; - self.load_weg_items()?; - self.load_themes()?; - self.load_placeholders()?; - self.load_settings_by_app()?; - Ok(()) - } - - fn emit_settings(&self) -> Result<()> { - self.handle.emit("settings", self.settings())?; - trace_lock!(SEELEN).on_state_changed()?; - Ok(()) - } - - fn emit_weg_items(&self) -> Result<()> { - self.handle.emit("weg-items", self.weg_items())?; - Ok(()) - } - - fn emit_themes(&self) -> Result<()> { - self.handle - .emit("themes", self.themes().values().collect_vec())?; - Ok(()) - } - - fn emit_placeholders(&self) -> Result<()> { - self.handle - .emit("placeholders", self.placeholders().values().collect_vec())?; - Ok(()) - } - - fn emit_settings_by_app(&self) -> Result<()> { - self.handle - .emit("settings-by-app", self.settings_by_app())?; - Ok(()) - } - - pub fn save_settings(&self) -> Result<()> { - std::fs::write(self.settings_path(), serde_json::to_string(&self.settings)?)?; - Ok(()) - } - - async fn set_wallpaper(url: &str, path: &Path) -> Result<()> { - let response = tauri_plugin_http::reqwest::get(url).await?; - let contents = response.bytes().await?; - std::fs::write(path, &contents)?; - WindowsApi::set_wallpaper(path.to_string_lossy().to_string())?; - Ok(()) - } - - pub fn load_resource(&mut self, resource: Resource) -> Result<()> { - log::trace!("Loading resource: {}", resource.id); - let id = resource.id; - - if let Some(image_url) = resource.wallpaper { - let path = self.data_dir.join(format!("wallpapers/{id}.png")); - tauri::async_runtime::spawn(async move { - log_error!(Self::set_wallpaper(&image_url, &path).await); - }); - } - - if let Some(theme) = resource.resources.theme { - let filename = format!("{id}.yml"); - std::fs::write( - self.data_dir.join(format!("themes/{filename}")), - serde_yaml::to_string(&theme)?, - )?; - if !self.settings.selected_theme.contains(&filename) { - self.settings.selected_theme.push(filename); - } - } - - if let Some(placeholder) = resource.resources.placeholder { - std::fs::write( - self.data_dir.join(format!("placeholders/{id}.yml")), - serde_yaml::to_string(&placeholder)?, - )?; - self.settings.fancy_toolbar.placeholder = Some(format!("{id}.yml")); - } - - if let Some(layout) = resource.resources.layout { - std::fs::write( - self.data_dir.join(format!("layouts/{id}.yml")), - serde_yaml::to_string(&layout)?, - )?; - self.settings.window_manager.default_layout = Some(format!("{id}.yml")); - } - - self.save_settings()?; - Ok(()) - } -} +mod apps_config; + +use arc_swap::ArcSwap; +use getset::Getters; +use itertools::Itertools; +use lazy_static::lazy_static; +use notify::{RecursiveMode, Watcher}; +use serde::Serialize; +use std::{ + collections::{HashMap, VecDeque}, + path::{Path, PathBuf}, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, +}; +use tauri::{AppHandle, Emitter, Manager}; + +use crate::{ + error_handler::Result, + log_error, + modules::cli::domain::Resource, + seelen::{get_app_handle, SEELEN}, + trace_lock, + windows_api::WindowsApi, +}; + +use super::{ + application::apps_config::REGEX_IDENTIFIERS, + domain::{AppConfig, Placeholder, Settings, Theme, WegItems}, +}; + +lazy_static! { + pub static ref FULL_STATE: Arc> = Arc::new(ArcSwap::from_pointee( + FullState::new().expect("Failed to create State Manager") + )); +} + +#[derive(Getters, Debug, Clone, Serialize)] +pub struct FullState { + #[serde(skip)] + handle: AppHandle, + #[serde(skip)] + data_dir: PathBuf, + #[serde(skip)] + resources_dir: PathBuf, + // ======== data ======== + #[getset(get = "pub")] + settings: Settings, + #[getset(get = "pub")] + settings_by_app: VecDeque, + #[getset(get = "pub")] + themes: HashMap, + #[getset(get = "pub")] + placeholders: HashMap, + #[getset(get = "pub")] + weg_items: WegItems, +} + +static FILE_LISTENER_PAUSED: AtomicBool = AtomicBool::new(false); + +impl FullState { + fn new() -> Result { + let handle = get_app_handle(); + let mut manager = Self { + data_dir: handle.path().app_data_dir()?, + resources_dir: handle.path().resource_dir()?, + handle, + // ======== data ======== + settings: Settings::default(), + settings_by_app: VecDeque::new(), + themes: HashMap::new(), + placeholders: HashMap::new(), + weg_items: serde_yaml::Value::Null, + }; + manager.load_all()?; + manager.start_listeners()?; + Ok(manager) + } + + /// shorthand of `FullState::clone` on Arc reference + pub fn cloned(&self) -> Self { + self.clone() + } + + /// store `self` as the static `FULL_STATE` instance + pub fn store(self) { + FULL_STATE.store(Arc::new(self)); + } + + pub fn settings_path(&self) -> PathBuf { + self.data_dir.join("settings.json") + } + + fn process_event(&mut self, event: notify::Event) -> Result<()> { + let weg_items_path = self.data_dir.join("seelenweg_items.yaml"); + + let user_themes = self.data_dir.join("themes"); + let bundled_themes = self.resources_dir.join("static/themes"); + + let user_placeholders = self.data_dir.join("placeholders"); + let bundled_placeholders = self.resources_dir.join("static/placeholders"); + + let user_app_configs = self.data_dir.join("applications.yml"); + let bundled_app_configs = self.resources_dir.join("static/apps_templates"); + + if event.paths.contains(&weg_items_path) { + log::info!("Weg Items changed: {:?}", event.paths); + self.load_weg_items()?; + self.emit_weg_items()?; + } + + if event.paths.contains(&self.settings_path()) { + log::info!("Seelen Settings changed: {:?}", event.paths); + self.load_settings()?; + self.emit_settings()?; + } + + if event + .paths + .iter() + .any(|p| p.starts_with(&user_themes) || p.starts_with(&bundled_themes)) + { + log::info!("Theme changed: {:?}", event.paths); + self.load_themes()?; + self.emit_themes()?; + } + + if event + .paths + .iter() + .any(|p| p.starts_with(&user_placeholders) || p.starts_with(&bundled_placeholders)) + { + log::info!("Placeholder changed: {:?}", event.paths); + self.load_placeholders()?; + self.emit_placeholders()?; + } + + if event + .paths + .iter() + .any(|p| p.starts_with(&user_app_configs) || p.starts_with(&bundled_app_configs)) + { + log::info!("Specific App Configuration changed: {:?}", event.paths); + self.load_settings_by_app()?; + self.emit_settings_by_app()?; + } + + Ok(()) + } + + fn start_listeners(&mut self) -> Result<()> { + let (tx, rx) = crossbeam_channel::unbounded(); + + let mut watcher = notify::recommended_watcher(tx)?; + + watcher.watch(&self.data_dir, RecursiveMode::Recursive)?; + watcher.watch(&self.resources_dir, RecursiveMode::Recursive)?; + + std::thread::spawn(move || { + let _watcher = watcher; + for event in rx { + match event { + Ok(event) => { + if !FILE_LISTENER_PAUSED.load(Ordering::Acquire) { + let mut state = FULL_STATE.load().cloned(); + log_error!(state.process_event(event)); + state.store(); + } + } + Err(e) => log::error!("Seelen UI Data Watcher error: {:?}", e), + } + } + }); + + log::trace!("Seelen UI Data Watcher started!"); + Ok(()) + } + + fn load_settings(&mut self) -> Result<()> { + let path = self.settings_path(); + if path.exists() { + self.settings = serde_json::from_str(&std::fs::read_to_string(&path)?)?; + } + Ok(()) + } + + fn load_weg_items(&mut self) -> Result<()> { + let path = self.data_dir.join("seelenweg_items.yaml"); + self.weg_items = if !path.exists() { + serde_yaml::Value::Null + } else { + serde_yaml::from_str(&std::fs::read_to_string(&path)?)? + }; + Ok(()) + } + + fn load_theme_from_file(path: PathBuf) -> Result { + match path.extension() { + Some(ext) if ext == "yml" || ext == "yaml" => { + Ok(serde_yaml::from_str(&std::fs::read_to_string(&path)?)?) + } + _ => Err("Invalid theme file extension".into()), + } + } + + fn load_theme_from_dir(path: PathBuf) -> Result { + let file = path.join("theme.yml"); + if !file.exists() { + return Err("theme.yml not found".into()); + } + + let mut theme = Self::load_theme_from_file(file)?; + + if path.join("theme.weg.css").exists() { + theme.styles.weg = std::fs::read_to_string(path.join("theme.weg.css"))?; + } + + if path.join("theme.toolbar.css").exists() { + theme.styles.toolbar = std::fs::read_to_string(path.join("theme.toolbar.css"))?; + } + + if path.join("theme.wm.css").exists() { + theme.styles.wm = std::fs::read_to_string(path.join("theme.wm.css"))?; + } + + Ok(theme) + } + + fn load_themes(&mut self) -> Result<()> { + let user_path = self.data_dir.join("themes"); + let resources_path = self.resources_dir.join("static/themes"); + let entries = std::fs::read_dir(&resources_path)?.chain(std::fs::read_dir(&user_path)?); + for entry in entries.flatten() { + let path = entry.path(); + let theme = if path.is_dir() { + Self::load_theme_from_dir(path) + } else { + Self::load_theme_from_file(path) + }; + match theme { + Ok(mut theme) => { + theme.info.filename = entry.file_name().to_string_lossy().to_string(); + self.themes.insert(theme.info.filename.clone(), theme); + } + Err(err) => log::error!("Failed to load theme ({:?}): {:?}", entry.path(), err), + } + } + Ok(()) + } + + fn load_placeholder_from_file(path: PathBuf) -> Result { + match path.extension() { + Some(ext) if ext == "yml" || ext == "yaml" => { + Ok(serde_yaml::from_str(&std::fs::read_to_string(&path)?)?) + } + _ => Err("Invalid placeholder file extension".into()), + } + } + + fn load_placeholders(&mut self) -> Result<()> { + let user_path = self.data_dir.join("placeholders"); + let resources_path = self.resources_dir.join("static/placeholders"); + let entries = std::fs::read_dir(&resources_path)?.chain(std::fs::read_dir(&user_path)?); + for entry in entries.flatten() { + let path = entry.path(); + if path.is_dir() { + continue; + } + + let placeholder = Self::load_placeholder_from_file(path); + + match placeholder { + Ok(mut placeholder) => { + placeholder.info.filename = entry.file_name().to_string_lossy().to_string(); + self.placeholders + .insert(placeholder.info.filename.clone(), placeholder); + } + Err(err) => { + log::error!("Failed to load placeholder ({:?}): {:?}", entry.path(), err) + } + } + } + Ok(()) + } + + fn load_settings_by_app(&mut self) -> Result<()> { + let user_apps_path = self.data_dir.join("applications.yml"); + let apps_templates_path = self.resources_dir.join("static/apps_templates"); + + trace_lock!(REGEX_IDENTIFIERS).clear(); + self.settings_by_app.clear(); + + if user_apps_path.exists() { + let content = std::fs::read_to_string(&user_apps_path)?; + let apps: Vec = serde_yaml::from_str(&content)?; + self.settings_by_app.extend(apps); + } + + for entry in apps_templates_path.read_dir()?.flatten() { + let content = std::fs::read_to_string(entry.path())?; + let mut apps: Vec = serde_yaml::from_str(&content)?; + for app in apps.iter_mut() { + app.is_bundled = true; + } + self.settings_by_app.extend(apps); + } + + self.settings_by_app + .iter() + .for_each(|app| app.identifier.cache_regex()); + Ok(()) + } + + fn load_all(&mut self) -> Result<()> { + self.load_settings()?; + self.load_weg_items()?; + self.load_themes()?; + self.load_placeholders()?; + self.load_settings_by_app()?; + Ok(()) + } + + fn emit_settings(&self) -> Result<()> { + self.handle.emit("settings", self.settings())?; + trace_lock!(SEELEN).on_state_changed()?; + Ok(()) + } + + fn emit_weg_items(&self) -> Result<()> { + self.handle.emit("weg-items", self.weg_items())?; + Ok(()) + } + + fn emit_themes(&self) -> Result<()> { + self.handle + .emit("themes", self.themes().values().collect_vec())?; + Ok(()) + } + + fn emit_placeholders(&self) -> Result<()> { + self.handle + .emit("placeholders", self.placeholders().values().collect_vec())?; + Ok(()) + } + + fn emit_settings_by_app(&self) -> Result<()> { + self.handle + .emit("settings-by-app", self.settings_by_app())?; + Ok(()) + } + + pub fn save_settings(&self) -> Result<()> { + std::fs::write(self.settings_path(), serde_json::to_string(&self.settings)?)?; + Ok(()) + } + + async fn set_wallpaper(url: &str, path: &Path) -> Result<()> { + let response = tauri_plugin_http::reqwest::get(url).await?; + let contents = response.bytes().await?; + std::fs::write(path, &contents)?; + WindowsApi::set_wallpaper(path.to_string_lossy().to_string())?; + Ok(()) + } + + pub fn load_resource(&mut self, resource: Resource) -> Result<()> { + log::trace!("Loading resource: {}", resource.id); + let id = resource.id; + + if let Some(image_url) = resource.wallpaper { + let path = self.data_dir.join(format!("wallpapers/{id}.png")); + tauri::async_runtime::spawn(async move { + log_error!(Self::set_wallpaper(&image_url, &path).await); + }); + } + + if let Some(theme) = resource.resources.theme { + let filename = format!("{id}.yml"); + std::fs::write( + self.data_dir.join(format!("themes/{filename}")), + serde_yaml::to_string(&theme)?, + )?; + if !self.settings.selected_theme.contains(&filename) { + self.settings.selected_theme.push(filename); + } + } + + if let Some(placeholder) = resource.resources.placeholder { + std::fs::write( + self.data_dir.join(format!("placeholders/{id}.yml")), + serde_yaml::to_string(&placeholder)?, + )?; + self.settings.fancy_toolbar.placeholder = Some(format!("{id}.yml")); + } + + if let Some(layout) = resource.resources.layout { + std::fs::write( + self.data_dir.join(format!("layouts/{id}.yml")), + serde_yaml::to_string(&layout)?, + )?; + self.settings.window_manager.default_layout = Some(format!("{id}.yml")); + } + + self.save_settings()?; + Ok(()) + } +} diff --git a/src/background/state/domain/mod.rs b/src/background/state/domain/mod.rs index 400c2f5d..aab6f850 100644 --- a/src/background/state/domain/mod.rs +++ b/src/background/state/domain/mod.rs @@ -1,127 +1,127 @@ -mod settings; - -use serde::{Deserialize, Serialize}; -pub use settings::*; - -// ============== THEMES ============== - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -#[serde(default, rename_all = "camelCase")] -pub struct ThemeCss { - pub weg: String, - pub toolbar: String, - pub wm: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -#[serde(default, rename_all = "camelCase")] -pub struct ThemeInfo { - pub display_name: String, - pub author: String, - pub description: String, - pub filename: String, - pub tags: Vec, -} - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -#[serde(default, rename_all = "camelCase")] -pub struct Theme { - pub info: ThemeInfo, - pub styles: ThemeCss, -} - -// ============== PLACEHOLDERS ============== - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -#[serde(default, rename_all = "camelCase")] -pub struct PlaceholderInfo { - pub display_name: String, - pub author: String, - pub description: String, - pub filename: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -#[serde(default, rename_all = "camelCase")] -pub struct Placeholder { - pub info: PlaceholderInfo, - pub left: Vec, - pub center: Vec, - pub right: Vec, -} - -// ============== WEG ============== - -pub type WegItems = serde_yaml::Value; - -// ============== SETTINGS BY APP ============== - -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -#[serde(rename_all(deserialize = "snake_case"))] -pub enum AppExtraFlag { - Float, - Force, - Unmanage, - Pinned, - // only for backwards compatibility - ObjectNameChange, - Layered, - BorderOverflow, - TrayAndMultiWindow, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub enum AppIdentifierType { - #[serde(alias = "exe")] - Exe, - #[serde(alias = "class")] - Class, - #[serde(alias = "title")] - Title, - #[serde(alias = "path")] - Path, -} - -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub enum MatchingStrategy { - #[serde(alias = "equals")] - Equals, - #[serde(alias = "startsWith")] - StartsWith, - #[serde(alias = "endsWith")] - EndsWith, - #[serde(alias = "contains")] - Contains, - #[serde(alias = "regex")] - Regex, - // only for backwards compatibility - #[serde(alias = "legacy")] - Legacy, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct AppIdentifier { - pub id: String, - pub kind: AppIdentifierType, - pub matching_strategy: MatchingStrategy, - #[serde(default)] - pub negation: bool, - #[serde(default)] - pub and: Vec, - #[serde(default)] - pub or: Vec, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[allow(dead_code)] -pub struct AppConfig { - pub name: String, - pub category: Option, - pub bound_monitor_idx: Option, - pub bound_workspace_name: Option, - pub identifier: AppIdentifier, - #[serde(default)] - pub options: Vec, - #[serde(default)] - pub is_bundled: bool, -} +mod settings; + +use serde::{Deserialize, Serialize}; +pub use settings::*; + +// ============== THEMES ============== + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +#[serde(default, rename_all = "camelCase")] +pub struct ThemeCss { + pub weg: String, + pub toolbar: String, + pub wm: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +#[serde(default, rename_all = "camelCase")] +pub struct ThemeInfo { + pub display_name: String, + pub author: String, + pub description: String, + pub filename: String, + pub tags: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +#[serde(default, rename_all = "camelCase")] +pub struct Theme { + pub info: ThemeInfo, + pub styles: ThemeCss, +} + +// ============== PLACEHOLDERS ============== + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +#[serde(default, rename_all = "camelCase")] +pub struct PlaceholderInfo { + pub display_name: String, + pub author: String, + pub description: String, + pub filename: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +#[serde(default, rename_all = "camelCase")] +pub struct Placeholder { + pub info: PlaceholderInfo, + pub left: Vec, + pub center: Vec, + pub right: Vec, +} + +// ============== WEG ============== + +pub type WegItems = serde_yaml::Value; + +// ============== SETTINGS BY APP ============== + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[serde(rename_all(deserialize = "snake_case"))] +pub enum AppExtraFlag { + Float, + Force, + Unmanage, + Pinned, + // only for backwards compatibility + ObjectNameChange, + Layered, + BorderOverflow, + TrayAndMultiWindow, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum AppIdentifierType { + #[serde(alias = "exe")] + Exe, + #[serde(alias = "class")] + Class, + #[serde(alias = "title")] + Title, + #[serde(alias = "path")] + Path, +} + +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub enum MatchingStrategy { + #[serde(alias = "equals")] + Equals, + #[serde(alias = "startsWith")] + StartsWith, + #[serde(alias = "endsWith")] + EndsWith, + #[serde(alias = "contains")] + Contains, + #[serde(alias = "regex")] + Regex, + // only for backwards compatibility + #[serde(alias = "legacy")] + Legacy, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct AppIdentifier { + pub id: String, + pub kind: AppIdentifierType, + pub matching_strategy: MatchingStrategy, + #[serde(default)] + pub negation: bool, + #[serde(default)] + pub and: Vec, + #[serde(default)] + pub or: Vec, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[allow(dead_code)] +pub struct AppConfig { + pub name: String, + pub category: Option, + pub bound_monitor_idx: Option, + pub bound_workspace_name: Option, + pub identifier: AppIdentifier, + #[serde(default)] + pub options: Vec, + #[serde(default)] + pub is_bundled: bool, +} diff --git a/src/background/state/domain/settings.rs b/src/background/state/domain/settings.rs index 16545b42..ef77e606 100644 --- a/src/background/state/domain/settings.rs +++ b/src/background/state/domain/settings.rs @@ -1,361 +1,361 @@ -use serde::{Deserialize, Serialize}; - -use crate::utils::rect::Rect; - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default)] -pub struct Settings { - /// fancy toolbar config - pub fancy_toolbar: FancyToolbarSettings, - /// seelenweg (dock/taskbar) config - pub seelenweg: SeelenWegSettings, - /// window manager config - pub window_manager: WindowManagerSettings, - /// list of monitors - pub monitors: Vec, - /// enable or disable ahk - pub ahk_enabled: bool, - /// ahk variables - pub ahk_variables: AhkVarList, - /// list of selected themes - pub selected_theme: Vec, - /// enable or disable dev tools tab in settings - pub dev_tools: bool, - /// language to use, if null the system locale is used - pub language: Option, -} - -impl Default for Settings { - fn default() -> Self { - Self { - ahk_enabled: true, - selected_theme: vec!["default".to_string()], - language: None, // default language is added in the webview using system locale - monitors: vec![Monitor::default()], - fancy_toolbar: FancyToolbarSettings::default(), - seelenweg: SeelenWegSettings::default(), - window_manager: WindowManagerSettings::default(), - ahk_variables: AhkVarList::default(), - dev_tools: false, - } - } -} - -// ============== Fancy Toolbar Settings ============== - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct FancyToolbarSettings { - /// enable or disable the fancy toolbar - pub enabled: bool, - /// height of the fancy toolbar - pub height: u32, - /// default placeholder for the fancy toolbar - pub placeholder: Option, -} - -impl Default for FancyToolbarSettings { - fn default() -> Self { - Self { - enabled: true, - height: 30, - placeholder: None, - } - } -} - -// ============== SeelenWeg Settings ============== - -#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)] -pub enum SeelenWegMode { - #[serde(rename = "Full-Width")] - FullWidth, - #[serde(rename = "Min-Content")] - MinContent, -} - -#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)] -pub enum SeelenWegHideMode { - /// never hide - Never, - /// auto-hide always on - Always, - /// auto-hide only if is overlaped by the focused window - #[serde(rename = "On-Overlap")] - OnOverlap, -} - -#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)] -pub enum SeelenWegSide { - Left, - Right, - Top, - Bottom, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct SeelenWegSettings { - /// enable or disable the seelenweg - pub enabled: bool, - /// Dock/Taskbar mode - pub mode: SeelenWegMode, - /// When to hide the dock - pub hide_mode: SeelenWegHideMode, - /// Dock position - pub position: SeelenWegSide, - /// enable or disable separators visibility - pub visible_separators: bool, - /// item size in px - pub size: u32, - /// zoomed item size in px - pub zoom_size: u32, - /// Dock/Taskbar margin in px - pub margin: u32, - /// Dock/Taskbar padding in px - pub padding: u32, - /// space between items in px - pub space_between_items: u32, -} - -impl Default for SeelenWegSettings { - fn default() -> Self { - Self { - enabled: true, - mode: SeelenWegMode::MinContent, - hide_mode: SeelenWegHideMode::OnOverlap, - position: SeelenWegSide::Bottom, - visible_separators: true, - size: 40, - zoom_size: 70, - margin: 8, - padding: 8, - space_between_items: 8, - } - } -} - -// ============== Window Manager Settings ============== - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct Border { - pub enabled: bool, - pub width: f64, - pub offset: f64, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct FloatingWindowSettings { - pub width: f64, - pub height: f64, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct WindowManagerSettings { - /// enable or disable the window manager - pub enabled: bool, - /// enable or disable auto stacking by category - pub auto_stacking_by_category: bool, - /// window manager border - pub border: Border, - /// the resize size in % to be used when resizing via cli - pub resize_delta: f64, - /// default gap between containers - pub workspace_gap: f64, - /// default workspace padding - pub workspace_padding: f64, - /// default workspace margin - pub global_work_area_offset: Rect, - /// floating window settings - pub floating: FloatingWindowSettings, - /// default layout - pub default_layout: Option, -} - -impl Default for Border { - fn default() -> Self { - Self { - enabled: true, - width: 3.0, - offset: -1.0, - } - } -} - -impl Default for FloatingWindowSettings { - fn default() -> Self { - Self { - width: 800.0, - height: 500.0, - } - } -} - -impl Default for WindowManagerSettings { - fn default() -> Self { - Self { - enabled: false, - auto_stacking_by_category: true, - border: Border::default(), - resize_delta: 10.0, - workspace_gap: 10.0, - workspace_padding: 10.0, - global_work_area_offset: Rect::default(), - floating: FloatingWindowSettings::default(), - default_layout: None, // added in frontend - } - } -} -// ============== Settings by Monitor ============== - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct Workspace { - pub name: String, - pub layout: String, - pub padding: Option, - pub gap: Option, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct Monitor { - pub workspaces: Vec, - pub work_area_offset: Option, -} - -impl Default for Workspace { - fn default() -> Self { - Self { - name: "New Workspace".to_string(), - layout: "BSP".to_string(), - padding: None, - gap: None, - } - } -} - -impl Default for Monitor { - fn default() -> Self { - Self { - workspaces: vec![Workspace::default()], - work_area_offset: None, - } - } -} - -// ============== Ahk Variables ============== - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct AhkVar { - pub fancy: String, - pub ahk: String, -} - -impl AhkVar { - pub fn new(f: &str, ahk: &str) -> Self { - Self { - fancy: f.to_string(), - ahk: ahk.to_string(), - } - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct AhkVarList { - pub reserve_top: AhkVar, - pub reserve_bottom: AhkVar, - pub reserve_left: AhkVar, - pub reserve_right: AhkVar, - pub reserve_float: AhkVar, - pub reserve_stack: AhkVar, - pub focus_top: AhkVar, - pub focus_bottom: AhkVar, - pub focus_left: AhkVar, - pub focus_right: AhkVar, - pub focus_latest: AhkVar, - pub increase_width: AhkVar, - pub decrease_width: AhkVar, - pub increase_height: AhkVar, - pub decrease_height: AhkVar, - pub restore_sizes: AhkVar, - pub switch_workspace_0: AhkVar, - pub switch_workspace_1: AhkVar, - pub switch_workspace_2: AhkVar, - pub switch_workspace_3: AhkVar, - pub switch_workspace_4: AhkVar, - pub switch_workspace_5: AhkVar, - pub switch_workspace_6: AhkVar, - pub switch_workspace_7: AhkVar, - pub switch_workspace_8: AhkVar, - pub switch_workspace_9: AhkVar, - pub move_to_workspace_0: AhkVar, - pub move_to_workspace_1: AhkVar, - pub move_to_workspace_2: AhkVar, - pub move_to_workspace_3: AhkVar, - pub move_to_workspace_4: AhkVar, - pub move_to_workspace_5: AhkVar, - pub move_to_workspace_6: AhkVar, - pub move_to_workspace_7: AhkVar, - pub move_to_workspace_8: AhkVar, - pub move_to_workspace_9: AhkVar, - pub send_to_workspace_0: AhkVar, - pub send_to_workspace_1: AhkVar, - pub send_to_workspace_2: AhkVar, - pub send_to_workspace_3: AhkVar, - pub send_to_workspace_4: AhkVar, - pub send_to_workspace_5: AhkVar, - pub send_to_workspace_6: AhkVar, - pub send_to_workspace_7: AhkVar, - pub send_to_workspace_8: AhkVar, - pub send_to_workspace_9: AhkVar, -} - -impl Default for AhkVarList { - fn default() -> Self { - Self { - reserve_top: AhkVar::new("Win + Shift + I", "#+i"), - reserve_bottom: AhkVar::new("Win + Shift + K", "#+k"), - reserve_left: AhkVar::new("Win + Shift + J", "#+j"), - reserve_right: AhkVar::new("Win + Shift + L", "#+l"), - reserve_float: AhkVar::new("Win + Shift + U", "#+u"), - reserve_stack: AhkVar::new("Win + Shift + O", "#+o"), - focus_top: AhkVar::new("Win + Shift + W", "#+w"), - focus_bottom: AhkVar::new("Win + Shift + S", "#+s"), - focus_left: AhkVar::new("Win + Shift + A", "#+a"), - focus_right: AhkVar::new("Win + Shift + D", "#+d"), - focus_latest: AhkVar::new("Win + Shift + E", "#+e"), - increase_width: AhkVar::new("Win + Alt + =", "#!="), - decrease_width: AhkVar::new("Win + Alt + -", "#!-"), - increase_height: AhkVar::new("Win + Shift + =", "#+="), - decrease_height: AhkVar::new("Win + Shift + -", "#+-"), - restore_sizes: AhkVar::new("Win + Alt + 0", "#!0"), - switch_workspace_0: AhkVar::new("Alt + 1", "!1"), - switch_workspace_1: AhkVar::new("Alt + 2", "!2"), - switch_workspace_2: AhkVar::new("Alt + 3", "!3"), - switch_workspace_3: AhkVar::new("Alt + 4", "!4"), - switch_workspace_4: AhkVar::new("Alt + 5", "!5"), - switch_workspace_5: AhkVar::new("Alt + 6", "!6"), - switch_workspace_6: AhkVar::new("Alt + 7", "!7"), - switch_workspace_7: AhkVar::new("Alt + 8", "!8"), - switch_workspace_8: AhkVar::new("Alt + 9", "!9"), - switch_workspace_9: AhkVar::new("Alt + 0", "!0"), - move_to_workspace_0: AhkVar::new("Alt + Shift + 1", "!+1"), - move_to_workspace_1: AhkVar::new("Alt + Shift + 2", "!+2"), - move_to_workspace_2: AhkVar::new("Alt + Shift + 3", "!+3"), - move_to_workspace_3: AhkVar::new("Alt + Shift + 4", "!+4"), - move_to_workspace_4: AhkVar::new("Alt + Shift + 5", "!+5"), - move_to_workspace_5: AhkVar::new("Alt + Shift + 6", "!+6"), - move_to_workspace_6: AhkVar::new("Alt + Shift + 7", "!+7"), - move_to_workspace_7: AhkVar::new("Alt + Shift + 8", "!+8"), - move_to_workspace_8: AhkVar::new("Alt + Shift + 9", "!+9"), - move_to_workspace_9: AhkVar::new("Alt + Shift + 0", "!+0"), - send_to_workspace_0: AhkVar::new("Win + Shift + 1", "#+1"), - send_to_workspace_1: AhkVar::new("Win + Shift + 2", "#+2"), - send_to_workspace_2: AhkVar::new("Win + Shift + 3", "#+3"), - send_to_workspace_3: AhkVar::new("Win + Shift + 4", "#+4"), - send_to_workspace_4: AhkVar::new("Win + Shift + 5", "#+5"), - send_to_workspace_5: AhkVar::new("Win + Shift + 6", "#+6"), - send_to_workspace_6: AhkVar::new("Win + Shift + 7", "#+7"), - send_to_workspace_7: AhkVar::new("Win + Shift + 8", "#+8"), - send_to_workspace_8: AhkVar::new("Win + Shift + 9", "#+9"), - send_to_workspace_9: AhkVar::new("Win + Shift + 0", "#+0"), - } - } -} +use serde::{Deserialize, Serialize}; + +use crate::utils::rect::Rect; + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(default)] +pub struct Settings { + /// fancy toolbar config + pub fancy_toolbar: FancyToolbarSettings, + /// seelenweg (dock/taskbar) config + pub seelenweg: SeelenWegSettings, + /// window manager config + pub window_manager: WindowManagerSettings, + /// list of monitors + pub monitors: Vec, + /// enable or disable ahk + pub ahk_enabled: bool, + /// ahk variables + pub ahk_variables: AhkVarList, + /// list of selected themes + pub selected_theme: Vec, + /// enable or disable dev tools tab in settings + pub dev_tools: bool, + /// language to use, if null the system locale is used + pub language: Option, +} + +impl Default for Settings { + fn default() -> Self { + Self { + ahk_enabled: true, + selected_theme: vec!["default".to_string()], + language: None, // default language is added in the webview using system locale + monitors: vec![Monitor::default()], + fancy_toolbar: FancyToolbarSettings::default(), + seelenweg: SeelenWegSettings::default(), + window_manager: WindowManagerSettings::default(), + ahk_variables: AhkVarList::default(), + dev_tools: false, + } + } +} + +// ============== Fancy Toolbar Settings ============== + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct FancyToolbarSettings { + /// enable or disable the fancy toolbar + pub enabled: bool, + /// height of the fancy toolbar + pub height: u32, + /// default placeholder for the fancy toolbar + pub placeholder: Option, +} + +impl Default for FancyToolbarSettings { + fn default() -> Self { + Self { + enabled: true, + height: 30, + placeholder: None, + } + } +} + +// ============== SeelenWeg Settings ============== + +#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)] +pub enum SeelenWegMode { + #[serde(rename = "Full-Width")] + FullWidth, + #[serde(rename = "Min-Content")] + MinContent, +} + +#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)] +pub enum SeelenWegHideMode { + /// never hide + Never, + /// auto-hide always on + Always, + /// auto-hide only if is overlaped by the focused window + #[serde(rename = "On-Overlap")] + OnOverlap, +} + +#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)] +pub enum SeelenWegSide { + Left, + Right, + Top, + Bottom, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct SeelenWegSettings { + /// enable or disable the seelenweg + pub enabled: bool, + /// Dock/Taskbar mode + pub mode: SeelenWegMode, + /// When to hide the dock + pub hide_mode: SeelenWegHideMode, + /// Dock position + pub position: SeelenWegSide, + /// enable or disable separators visibility + pub visible_separators: bool, + /// item size in px + pub size: u32, + /// zoomed item size in px + pub zoom_size: u32, + /// Dock/Taskbar margin in px + pub margin: u32, + /// Dock/Taskbar padding in px + pub padding: u32, + /// space between items in px + pub space_between_items: u32, +} + +impl Default for SeelenWegSettings { + fn default() -> Self { + Self { + enabled: true, + mode: SeelenWegMode::MinContent, + hide_mode: SeelenWegHideMode::OnOverlap, + position: SeelenWegSide::Bottom, + visible_separators: true, + size: 40, + zoom_size: 70, + margin: 8, + padding: 8, + space_between_items: 8, + } + } +} + +// ============== Window Manager Settings ============== + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct Border { + pub enabled: bool, + pub width: f64, + pub offset: f64, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct FloatingWindowSettings { + pub width: f64, + pub height: f64, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct WindowManagerSettings { + /// enable or disable the window manager + pub enabled: bool, + /// enable or disable auto stacking by category + pub auto_stacking_by_category: bool, + /// window manager border + pub border: Border, + /// the resize size in % to be used when resizing via cli + pub resize_delta: f64, + /// default gap between containers + pub workspace_gap: f64, + /// default workspace padding + pub workspace_padding: f64, + /// default workspace margin + pub global_work_area_offset: Rect, + /// floating window settings + pub floating: FloatingWindowSettings, + /// default layout + pub default_layout: Option, +} + +impl Default for Border { + fn default() -> Self { + Self { + enabled: true, + width: 3.0, + offset: -1.0, + } + } +} + +impl Default for FloatingWindowSettings { + fn default() -> Self { + Self { + width: 800.0, + height: 500.0, + } + } +} + +impl Default for WindowManagerSettings { + fn default() -> Self { + Self { + enabled: false, + auto_stacking_by_category: true, + border: Border::default(), + resize_delta: 10.0, + workspace_gap: 10.0, + workspace_padding: 10.0, + global_work_area_offset: Rect::default(), + floating: FloatingWindowSettings::default(), + default_layout: None, // added in frontend + } + } +} +// ============== Settings by Monitor ============== + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct Workspace { + pub name: String, + pub layout: String, + pub padding: Option, + pub gap: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct Monitor { + pub workspaces: Vec, + pub work_area_offset: Option, +} + +impl Default for Workspace { + fn default() -> Self { + Self { + name: "New Workspace".to_string(), + layout: "BSP".to_string(), + padding: None, + gap: None, + } + } +} + +impl Default for Monitor { + fn default() -> Self { + Self { + workspaces: vec![Workspace::default()], + work_area_offset: None, + } + } +} + +// ============== Ahk Variables ============== + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct AhkVar { + pub fancy: String, + pub ahk: String, +} + +impl AhkVar { + pub fn new(f: &str, ahk: &str) -> Self { + Self { + fancy: f.to_string(), + ahk: ahk.to_string(), + } + } +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct AhkVarList { + pub reserve_top: AhkVar, + pub reserve_bottom: AhkVar, + pub reserve_left: AhkVar, + pub reserve_right: AhkVar, + pub reserve_float: AhkVar, + pub reserve_stack: AhkVar, + pub focus_top: AhkVar, + pub focus_bottom: AhkVar, + pub focus_left: AhkVar, + pub focus_right: AhkVar, + pub focus_latest: AhkVar, + pub increase_width: AhkVar, + pub decrease_width: AhkVar, + pub increase_height: AhkVar, + pub decrease_height: AhkVar, + pub restore_sizes: AhkVar, + pub switch_workspace_0: AhkVar, + pub switch_workspace_1: AhkVar, + pub switch_workspace_2: AhkVar, + pub switch_workspace_3: AhkVar, + pub switch_workspace_4: AhkVar, + pub switch_workspace_5: AhkVar, + pub switch_workspace_6: AhkVar, + pub switch_workspace_7: AhkVar, + pub switch_workspace_8: AhkVar, + pub switch_workspace_9: AhkVar, + pub move_to_workspace_0: AhkVar, + pub move_to_workspace_1: AhkVar, + pub move_to_workspace_2: AhkVar, + pub move_to_workspace_3: AhkVar, + pub move_to_workspace_4: AhkVar, + pub move_to_workspace_5: AhkVar, + pub move_to_workspace_6: AhkVar, + pub move_to_workspace_7: AhkVar, + pub move_to_workspace_8: AhkVar, + pub move_to_workspace_9: AhkVar, + pub send_to_workspace_0: AhkVar, + pub send_to_workspace_1: AhkVar, + pub send_to_workspace_2: AhkVar, + pub send_to_workspace_3: AhkVar, + pub send_to_workspace_4: AhkVar, + pub send_to_workspace_5: AhkVar, + pub send_to_workspace_6: AhkVar, + pub send_to_workspace_7: AhkVar, + pub send_to_workspace_8: AhkVar, + pub send_to_workspace_9: AhkVar, +} + +impl Default for AhkVarList { + fn default() -> Self { + Self { + reserve_top: AhkVar::new("Win + Shift + I", "#+i"), + reserve_bottom: AhkVar::new("Win + Shift + K", "#+k"), + reserve_left: AhkVar::new("Win + Shift + J", "#+j"), + reserve_right: AhkVar::new("Win + Shift + L", "#+l"), + reserve_float: AhkVar::new("Win + Shift + U", "#+u"), + reserve_stack: AhkVar::new("Win + Shift + O", "#+o"), + focus_top: AhkVar::new("Win + Shift + W", "#+w"), + focus_bottom: AhkVar::new("Win + Shift + S", "#+s"), + focus_left: AhkVar::new("Win + Shift + A", "#+a"), + focus_right: AhkVar::new("Win + Shift + D", "#+d"), + focus_latest: AhkVar::new("Win + Shift + E", "#+e"), + increase_width: AhkVar::new("Win + Alt + =", "#!="), + decrease_width: AhkVar::new("Win + Alt + -", "#!-"), + increase_height: AhkVar::new("Win + Shift + =", "#+="), + decrease_height: AhkVar::new("Win + Shift + -", "#+-"), + restore_sizes: AhkVar::new("Win + Alt + 0", "#!0"), + switch_workspace_0: AhkVar::new("Alt + 1", "!1"), + switch_workspace_1: AhkVar::new("Alt + 2", "!2"), + switch_workspace_2: AhkVar::new("Alt + 3", "!3"), + switch_workspace_3: AhkVar::new("Alt + 4", "!4"), + switch_workspace_4: AhkVar::new("Alt + 5", "!5"), + switch_workspace_5: AhkVar::new("Alt + 6", "!6"), + switch_workspace_6: AhkVar::new("Alt + 7", "!7"), + switch_workspace_7: AhkVar::new("Alt + 8", "!8"), + switch_workspace_8: AhkVar::new("Alt + 9", "!9"), + switch_workspace_9: AhkVar::new("Alt + 0", "!0"), + move_to_workspace_0: AhkVar::new("Alt + Shift + 1", "!+1"), + move_to_workspace_1: AhkVar::new("Alt + Shift + 2", "!+2"), + move_to_workspace_2: AhkVar::new("Alt + Shift + 3", "!+3"), + move_to_workspace_3: AhkVar::new("Alt + Shift + 4", "!+4"), + move_to_workspace_4: AhkVar::new("Alt + Shift + 5", "!+5"), + move_to_workspace_5: AhkVar::new("Alt + Shift + 6", "!+6"), + move_to_workspace_6: AhkVar::new("Alt + Shift + 7", "!+7"), + move_to_workspace_7: AhkVar::new("Alt + Shift + 8", "!+8"), + move_to_workspace_8: AhkVar::new("Alt + Shift + 9", "!+9"), + move_to_workspace_9: AhkVar::new("Alt + Shift + 0", "!+0"), + send_to_workspace_0: AhkVar::new("Win + Shift + 1", "#+1"), + send_to_workspace_1: AhkVar::new("Win + Shift + 2", "#+2"), + send_to_workspace_2: AhkVar::new("Win + Shift + 3", "#+3"), + send_to_workspace_3: AhkVar::new("Win + Shift + 4", "#+4"), + send_to_workspace_4: AhkVar::new("Win + Shift + 5", "#+5"), + send_to_workspace_5: AhkVar::new("Win + Shift + 6", "#+6"), + send_to_workspace_6: AhkVar::new("Win + Shift + 7", "#+7"), + send_to_workspace_7: AhkVar::new("Win + Shift + 8", "#+8"), + send_to_workspace_8: AhkVar::new("Win + Shift + 9", "#+9"), + send_to_workspace_9: AhkVar::new("Win + Shift + 0", "#+0"), + } + } +} diff --git a/src/background/state/infrastructure.rs b/src/background/state/infrastructure.rs index f417afee..e4f33b56 100644 --- a/src/background/state/infrastructure.rs +++ b/src/background/state/infrastructure.rs @@ -1,55 +1,55 @@ -use std::path::PathBuf; - -use itertools::Itertools; - -use crate::{error_handler::Result, windows_api::WindowsApi}; - -use super::{ - application::FULL_STATE, - domain::{AppConfig, Placeholder, Settings, Theme, WegItems}, -}; - -#[tauri::command] -pub fn state_get_themes() -> Vec { - FULL_STATE.load().themes().values().cloned().collect_vec() -} - -#[tauri::command] -pub fn state_get_placeholders() -> Vec { - FULL_STATE - .load() - .placeholders() - .values() - .cloned() - .collect_vec() -} - -#[tauri::command] -pub fn state_get_weg_items() -> WegItems { - FULL_STATE.load().weg_items().clone() -} - -#[tauri::command] -pub fn state_get_settings() -> Settings { - FULL_STATE.load().settings().clone() -} - -#[tauri::command] -pub fn state_get_specific_apps_configurations() -> Vec { - FULL_STATE - .load() - .settings_by_app() - .iter() - .cloned() - .collect_vec() -} - -#[tauri::command] -pub fn state_get_wallpaper() -> Result { - WindowsApi::get_wallpaper() -} - -#[tauri::command] -pub fn state_set_wallpaper(path: String) -> Result<()> { - WindowsApi::set_wallpaper(path) -} +use std::path::PathBuf; + +use itertools::Itertools; + +use crate::{error_handler::Result, windows_api::WindowsApi}; + +use super::{ + application::FULL_STATE, + domain::{AppConfig, Placeholder, Settings, Theme, WegItems}, +}; + +#[tauri::command] +pub fn state_get_themes() -> Vec { + FULL_STATE.load().themes().values().cloned().collect_vec() +} + +#[tauri::command] +pub fn state_get_placeholders() -> Vec { + FULL_STATE + .load() + .placeholders() + .values() + .cloned() + .collect_vec() +} + +#[tauri::command] +pub fn state_get_weg_items() -> WegItems { + FULL_STATE.load().weg_items().clone() +} + +#[tauri::command] +pub fn state_get_settings() -> Settings { + FULL_STATE.load().settings().clone() +} + +#[tauri::command] +pub fn state_get_specific_apps_configurations() -> Vec { + FULL_STATE + .load() + .settings_by_app() + .iter() + .cloned() + .collect_vec() +} + +#[tauri::command] +pub fn state_get_wallpaper() -> Result { + WindowsApi::get_wallpaper() +} + +#[tauri::command] +pub fn state_set_wallpaper(path: String) -> Result<()> { + WindowsApi::set_wallpaper(path) +} diff --git a/src/background/state/mod.rs b/src/background/state/mod.rs index e5967ecb..1db6d5d8 100644 --- a/src/background/state/mod.rs +++ b/src/background/state/mod.rs @@ -1,42 +1,42 @@ -pub mod application; -pub mod domain; -pub mod infrastructure; - -use std::{ - collections::HashMap, - sync::atomic::{AtomicBool, AtomicU32}, -}; - -use application::FullState; -use domain::AhkVar; - -pub static IS_TOOLBAR_ENABLED: AtomicBool = AtomicBool::new(true); -pub static TOOLBAR_HEIGHT: AtomicU32 = AtomicU32::new(30); - -impl FullState { - pub fn is_weg_enabled(&self) -> bool { - self.settings().seelenweg.enabled - } - - pub fn is_shell_enabled(&self) -> bool { - false - } - - pub fn is_bar_enabled(&self) -> bool { - self.settings().fancy_toolbar.enabled - } - - pub fn is_window_manager_enabled(&self) -> bool { - self.settings().window_manager.enabled - } - - pub fn is_ahk_enabled(&self) -> bool { - self.settings().ahk_enabled - } - - pub fn get_ahk_variables(&self) -> HashMap { - let json_value = serde_json::to_value(&self.settings().ahk_variables) - .expect("Failed to serialize AHK variables"); - serde_json::from_value(json_value).expect("Failed to deserialize AHK variables") - } -} +pub mod application; +pub mod domain; +pub mod infrastructure; + +use std::{ + collections::HashMap, + sync::atomic::{AtomicBool, AtomicU32}, +}; + +use application::FullState; +use domain::AhkVar; + +pub static IS_TOOLBAR_ENABLED: AtomicBool = AtomicBool::new(true); +pub static TOOLBAR_HEIGHT: AtomicU32 = AtomicU32::new(30); + +impl FullState { + pub fn is_weg_enabled(&self) -> bool { + self.settings().seelenweg.enabled + } + + pub fn is_shell_enabled(&self) -> bool { + false + } + + pub fn is_bar_enabled(&self) -> bool { + self.settings().fancy_toolbar.enabled + } + + pub fn is_window_manager_enabled(&self) -> bool { + self.settings().window_manager.enabled + } + + pub fn is_ahk_enabled(&self) -> bool { + self.settings().ahk_enabled + } + + pub fn get_ahk_variables(&self) -> HashMap { + let json_value = serde_json::to_value(&self.settings().ahk_variables) + .expect("Failed to serialize AHK variables"); + serde_json::from_value(json_value).expect("Failed to deserialize AHK variables") + } +} diff --git a/src/background/system/brightness.rs b/src/background/system/brightness.rs index a2eb0abc..e3a082b8 100644 --- a/src/background/system/brightness.rs +++ b/src/background/system/brightness.rs @@ -1,63 +1,63 @@ -use serde::Serialize; -use windows::Win32::Devices::Display::{ - GetMonitorBrightness, GetMonitorCapabilities, SetMonitorBrightness, -}; - -use crate::windows_api::WindowsApi; - -#[derive(Debug, Serialize)] -pub struct Brightness { - min: u32, - max: u32, - current: u32, -} - -#[tauri::command] -pub fn get_main_monitor_brightness() -> Result { - let mut brightness = Brightness { - min: 0, - max: 0, - current: 0, - }; - - unsafe { - let hmonitor = WindowsApi::primary_physical_monitor()?; - - let mut pdwmonitorcapabilities: u32 = 0; - let mut pdwsupportedcolortemperatures: u32 = 0; - let mut result = GetMonitorCapabilities( - hmonitor.hPhysicalMonitor, - &mut pdwmonitorcapabilities, - &mut pdwsupportedcolortemperatures, - ); - - if result == 0 { - return Err("GetMonitorCapabilities failed".to_string()); - } - - result = GetMonitorBrightness( - hmonitor.hPhysicalMonitor, - &mut brightness.min, - &mut brightness.current, - &mut brightness.max, - ); - - if result == 0 { - return Err("GetMonitorBrightness failed".to_string()); - } - } - - Ok(brightness) -} - -#[tauri::command] -pub fn set_main_monitor_brightness(brightness: u32) -> Result<(), String> { - let result = unsafe { - let hmonitor = WindowsApi::primary_physical_monitor()?; - SetMonitorBrightness(hmonitor.hPhysicalMonitor, brightness) - }; - if result == 0 { - return Err("SetMonitorBrightness failed".to_string()); - } - Ok(()) -} +use serde::Serialize; +use windows::Win32::Devices::Display::{ + GetMonitorBrightness, GetMonitorCapabilities, SetMonitorBrightness, +}; + +use crate::windows_api::WindowsApi; + +#[derive(Debug, Serialize)] +pub struct Brightness { + min: u32, + max: u32, + current: u32, +} + +#[tauri::command] +pub fn get_main_monitor_brightness() -> Result { + let mut brightness = Brightness { + min: 0, + max: 0, + current: 0, + }; + + unsafe { + let hmonitor = WindowsApi::primary_physical_monitor()?; + + let mut pdwmonitorcapabilities: u32 = 0; + let mut pdwsupportedcolortemperatures: u32 = 0; + let mut result = GetMonitorCapabilities( + hmonitor.hPhysicalMonitor, + &mut pdwmonitorcapabilities, + &mut pdwsupportedcolortemperatures, + ); + + if result == 0 { + return Err("GetMonitorCapabilities failed".to_string()); + } + + result = GetMonitorBrightness( + hmonitor.hPhysicalMonitor, + &mut brightness.min, + &mut brightness.current, + &mut brightness.max, + ); + + if result == 0 { + return Err("GetMonitorBrightness failed".to_string()); + } + } + + Ok(brightness) +} + +#[tauri::command] +pub fn set_main_monitor_brightness(brightness: u32) -> Result<(), String> { + let result = unsafe { + let hmonitor = WindowsApi::primary_physical_monitor()?; + SetMonitorBrightness(hmonitor.hPhysicalMonitor, brightness) + }; + if result == 0 { + return Err("SetMonitorBrightness failed".to_string()); + } + Ok(()) +} diff --git a/src/background/system/mod.rs b/src/background/system/mod.rs index c66564c4..4dc00558 100644 --- a/src/background/system/mod.rs +++ b/src/background/system/mod.rs @@ -1,60 +1,60 @@ -pub mod brightness; - -use tauri::Listener; - -use crate::{ - error_handler::Result, - log_error, - modules::{ - media::infrastructure::{register_media_events, release_media_events}, - network::infrastructure::register_network_events, - notifications::infrastructure::{ - register_notification_events, release_notification_events, - }, - power::infrastructure::PowerManager, - system_settings::infrastructure::{register_colors_events, release_colors_events}, - tray::infrastructure::register_tray_events, - }, - seelen::get_app_handle, -}; - -pub fn declare_system_events_handlers() -> Result<()> { - let handle = get_app_handle(); - - handle.listen("register-power-events", move |_| { - log_error!(PowerManager::register_power_events()); - log_error!(PowerManager::emit_system_power_info()); - }); - - handle.listen("register-tray-events", move |_| { - log_error!(register_tray_events()) - }); - - handle.listen("register-network-events", move |_| { - log_error!(register_network_events()); - }); - - handle.listen("register-bluetooth-events", move |_| { - // todo - }); - - handle.listen("register-media-events", move |_| { - register_media_events(); - }); - - handle.listen("register-notifications-events", move |_| { - register_notification_events(); - }); - - handle.listen("register-colors-events", move |_| { - register_colors_events(); - }); - - Ok(()) -} - -pub fn release_system_events_handlers() { - release_media_events(); - release_notification_events(); - release_colors_events(); -} +pub mod brightness; + +use tauri::Listener; + +use crate::{ + error_handler::Result, + log_error, + modules::{ + media::infrastructure::{register_media_events, release_media_events}, + network::infrastructure::register_network_events, + notifications::infrastructure::{ + register_notification_events, release_notification_events, + }, + power::infrastructure::PowerManager, + system_settings::infrastructure::{register_colors_events, release_colors_events}, + tray::infrastructure::register_tray_events, + }, + seelen::get_app_handle, +}; + +pub fn declare_system_events_handlers() -> Result<()> { + let handle = get_app_handle(); + + handle.listen("register-power-events", move |_| { + log_error!(PowerManager::register_power_events()); + log_error!(PowerManager::emit_system_power_info()); + }); + + handle.listen("register-tray-events", move |_| { + log_error!(register_tray_events()) + }); + + handle.listen("register-network-events", move |_| { + log_error!(register_network_events()); + }); + + handle.listen("register-bluetooth-events", move |_| { + // todo + }); + + handle.listen("register-media-events", move |_| { + register_media_events(); + }); + + handle.listen("register-notifications-events", move |_| { + register_notification_events(); + }); + + handle.listen("register-colors-events", move |_| { + register_colors_events(); + }); + + Ok(()) +} + +pub fn release_system_events_handlers() { + release_media_events(); + release_notification_events(); + release_colors_events(); +} diff --git a/src/background/tray.rs b/src/background/tray.rs index 51f378fa..2008243b 100644 --- a/src/background/tray.rs +++ b/src/background/tray.rs @@ -1,85 +1,85 @@ -use tauri::image::Image; -use tauri::path::BaseDirectory; -use tauri::tray::{MouseButton, MouseButtonState, TrayIconEvent}; -use tauri::Manager; -use tauri::{ - menu::{MenuBuilder, MenuEvent, MenuItemBuilder}, - tray::TrayIconBuilder, - App, AppHandle, -}; - -use crate::error_handler::Result; -use crate::log_error; -use crate::seelen::Seelen; -use crate::utils::sleep_millis; - -pub fn try_register_tray_icon(app: &mut App) -> Result<()> { - log::trace!("registering tray icon"); - let mut attempts = 0; - - // normally tray icon creation not fails but on windows startup - // it could fail until some processes are started - while let Err(e) = register_tray_icon(app) { - if attempts >= 10 { - return Err(e); - } - attempts += 1; - sleep_millis(100); - } - - Ok(()) -} - -fn register_tray_icon(app: &mut App) -> Result<()> { - let settings = MenuItemBuilder::with_id("settings", "Open Settings").build(app)?; - - let toggle_pause = MenuItemBuilder::with_id("pause", "Pause/Resume").build(app)?; - let restart = MenuItemBuilder::with_id("restart", "Reload").build(app)?; - - let quit = MenuItemBuilder::with_id("quit", "Quit").build(app)?; - - let menu = MenuBuilder::new(app) - .item(&settings) - .separator() - .item(&toggle_pause) - .item(&restart) - .separator() - .item(&quit) - .build()?; - - TrayIconBuilder::new() - .icon(Image::from_path(app.path().resolve( - "static/icons/32x32.png", - BaseDirectory::Resource, - )?)?) - .tooltip("Seelen UI") - .menu(&menu) - .on_menu_event( - move |app: &AppHandle, event: MenuEvent| match event.id().as_ref() { - "settings" => { - log_error!(Seelen::show_settings()); - } - "pause" => {} - "restart" => app.restart(), - "quit" => app.exit(0), - _ => (), - }, - ) - .on_tray_icon_event(move |_, event| { - if let TrayIconEvent::Click { - id: _, - position: _, - rect: _, - button, - button_state, - } = event - { - if button == MouseButton::Left && button_state == MouseButtonState::Up { - log_error!(Seelen::show_settings()); - } - } - }) - .build(app)?; - - Ok(()) -} +use tauri::image::Image; +use tauri::path::BaseDirectory; +use tauri::tray::{MouseButton, MouseButtonState, TrayIconEvent}; +use tauri::Manager; +use tauri::{ + menu::{MenuBuilder, MenuEvent, MenuItemBuilder}, + tray::TrayIconBuilder, + App, AppHandle, +}; + +use crate::error_handler::Result; +use crate::log_error; +use crate::seelen::Seelen; +use crate::utils::sleep_millis; + +pub fn try_register_tray_icon(app: &mut App) -> Result<()> { + log::trace!("registering tray icon"); + let mut attempts = 0; + + // normally tray icon creation not fails but on windows startup + // it could fail until some processes are started + while let Err(e) = register_tray_icon(app) { + if attempts >= 10 { + return Err(e); + } + attempts += 1; + sleep_millis(100); + } + + Ok(()) +} + +fn register_tray_icon(app: &mut App) -> Result<()> { + let settings = MenuItemBuilder::with_id("settings", "Open Settings").build(app)?; + + let toggle_pause = MenuItemBuilder::with_id("pause", "Pause/Resume").build(app)?; + let restart = MenuItemBuilder::with_id("restart", "Reload").build(app)?; + + let quit = MenuItemBuilder::with_id("quit", "Quit").build(app)?; + + let menu = MenuBuilder::new(app) + .item(&settings) + .separator() + .item(&toggle_pause) + .item(&restart) + .separator() + .item(&quit) + .build()?; + + TrayIconBuilder::new() + .icon(Image::from_path(app.path().resolve( + "static/icons/32x32.png", + BaseDirectory::Resource, + )?)?) + .tooltip("Seelen UI") + .menu(&menu) + .on_menu_event( + move |app: &AppHandle, event: MenuEvent| match event.id().as_ref() { + "settings" => { + log_error!(Seelen::show_settings()); + } + "pause" => {} + "restart" => app.restart(), + "quit" => app.exit(0), + _ => (), + }, + ) + .on_tray_icon_event(move |_, event| { + if let TrayIconEvent::Click { + id: _, + position: _, + rect: _, + button, + button_state, + } = event + { + if button == MouseButton::Left && button_state == MouseButtonState::Up { + log_error!(Seelen::show_settings()); + } + } + }) + .build(app)?; + + Ok(()) +} diff --git a/src/background/utils/ahk/mocks/seelen.ahk b/src/background/utils/ahk/mocks/seelen.ahk index fd13782d..e8460398 100644 --- a/src/background/utils/ahk/mocks/seelen.ahk +++ b/src/background/utils/ahk/mocks/seelen.ahk @@ -1,20 +1,20 @@ -/* - * This file is generated by Seelen UI and will be replaced on each update please don't modify manually. - * If you want to introduce your own implementation for shortcuts with AHK or any other scripting language - * just disable Seelen UI intergrated shortcuts in the shortcuts tab, and this file will be ignored. -*/ -#Requires AutoHotkey v2.0 -#SingleInstance Force -#NoTrayIcon - -#Include seelen.lib.ahk - -CloseIfNotRunning() - -; Open Settings -#k:: OpenSettings() - -; Resume Window Manager -^#!p:: { - ResumeWM() +/* + * This file is generated by Seelen UI and will be replaced on each update please don't modify manually. + * If you want to introduce your own implementation for shortcuts with AHK or any other scripting language + * just disable Seelen UI intergrated shortcuts in the shortcuts tab, and this file will be ignored. +*/ +#Requires AutoHotkey v2.0 +#SingleInstance Force +#NoTrayIcon + +#Include seelen.lib.ahk + +CloseIfNotRunning() + +; Open Settings +#k:: OpenSettings() + +; Resume Window Manager +^#!p:: { + ResumeWM() } \ No newline at end of file diff --git a/src/background/utils/ahk/mocks/seelen.lib.ahk b/src/background/utils/ahk/mocks/seelen.lib.ahk index 60350df1..8add2b8d 100644 --- a/src/background/utils/ahk/mocks/seelen.lib.ahk +++ b/src/background/utils/ahk/mocks/seelen.lib.ahk @@ -1,73 +1,73 @@ -/* - * This file is generated by Seelen UI and will be replaced on each update please don't modify manually. - * If you want to introduce your own implementation for shortcuts with AHK or any other scripting language - * just disable Seelen UI intergrated shortcuts in the shortcuts tab, and this file will be ignored. -*/ -#Requires AutoHotkey v2.0 -#SingleInstance Force - -global seelen := "SEELEN_UI_EXE_PATH" - -/** Close the AHK if app is crashed or forced to close */ -CloseIfNotRunning() { - if ProcessExist("seelen-ui.exe") == 0 { - ExitApp() - } - SetTimer(CloseIfNotRunning, 1000) -} - -OpenSettings(){ - RunWait(seelen " settings", , "Hide") -} - -Reserve(reservation) { - RunWait(seelen " wm reserve " reservation, , "Hide") -} - -CancelReservation() { - RunWait(seelen " wm cancel-reservation", , "Hide") -} - -WMDebug() { - RunWait(seelen " wm debug", , "Hide") -} - -updateWindowWidth(action) { - RunWait(seelen " wm width " action, , "Hide") -} - -updateWindowHeight(action) { - RunWait(seelen " wm height " action, , "Hide") -} - -resetWorkspaceSize() { - RunWait(seelen " wm reset-workspace-size", , "Hide") -} - -focus(action) { - RunWait(seelen " wm focus " action, , "Hide") -} - -SwitchWorkspace(idx) { - RunWait(seelen " wm switch-workspace " idx, , "Hide") -} - -MoveToWorkspace(idx) { - RunWait(seelen " wm move-to-workspace " idx, , "Hide") -} - -SendToWorkspace(idx) { - RunWait(seelen " wm send-to-workspace " idx, , "Hide") -} - -PauseWM() { - RunWait(seelen " wm pause", , "Hide") -} - -/** - * Resumes the window manager and will start `seelen.wm.ahk` if - * the included AHK shortcuts are enabled in the settings. - */ -ResumeWM() { - RunWait(seelen " wm resume", , "Hide") +/* + * This file is generated by Seelen UI and will be replaced on each update please don't modify manually. + * If you want to introduce your own implementation for shortcuts with AHK or any other scripting language + * just disable Seelen UI intergrated shortcuts in the shortcuts tab, and this file will be ignored. +*/ +#Requires AutoHotkey v2.0 +#SingleInstance Force + +global seelen := "SEELEN_UI_EXE_PATH" + +/** Close the AHK if app is crashed or forced to close */ +CloseIfNotRunning() { + if ProcessExist("seelen-ui.exe") == 0 { + ExitApp() + } + SetTimer(CloseIfNotRunning, 1000) +} + +OpenSettings(){ + RunWait(seelen " settings", , "Hide") +} + +Reserve(reservation) { + RunWait(seelen " wm reserve " reservation, , "Hide") +} + +CancelReservation() { + RunWait(seelen " wm cancel-reservation", , "Hide") +} + +WMDebug() { + RunWait(seelen " wm debug", , "Hide") +} + +updateWindowWidth(action) { + RunWait(seelen " wm width " action, , "Hide") +} + +updateWindowHeight(action) { + RunWait(seelen " wm height " action, , "Hide") +} + +resetWorkspaceSize() { + RunWait(seelen " wm reset-workspace-size", , "Hide") +} + +focus(action) { + RunWait(seelen " wm focus " action, , "Hide") +} + +SwitchWorkspace(idx) { + RunWait(seelen " wm switch-workspace " idx, , "Hide") +} + +MoveToWorkspace(idx) { + RunWait(seelen " wm move-to-workspace " idx, , "Hide") +} + +SendToWorkspace(idx) { + RunWait(seelen " wm send-to-workspace " idx, , "Hide") +} + +PauseWM() { + RunWait(seelen " wm pause", , "Hide") +} + +/** + * Resumes the window manager and will start `seelen.wm.ahk` if + * the included AHK shortcuts are enabled in the settings. + */ +ResumeWM() { + RunWait(seelen " wm resume", , "Hide") } \ No newline at end of file diff --git a/src/background/utils/ahk/mocks/seelen.wm.ahk b/src/background/utils/ahk/mocks/seelen.wm.ahk index f0aa042d..3bcefe9a 100644 --- a/src/background/utils/ahk/mocks/seelen.wm.ahk +++ b/src/background/utils/ahk/mocks/seelen.wm.ahk @@ -1,161 +1,161 @@ -/* - * This file is generated by Seelen UI and will be replaced on each update please don't modify manually. - * If you want to introduce your own implementation for shortcuts with AHK or any other scripting language - * just disable Seelen UI integrated shortcuts in the shortcuts tab, and this file will be ignored. -*/ -#Requires AutoHotkey v2.0 -#SingleInstance Force -#NoTrayIcon - -#Include seelen.lib.ahk - -CloseIfNotRunning() - -;debug_wm -^#!w:: WMDebug() - -^#!p:: { - PauseWM() - ExitApp() -} - -;reserve_top -x:: Reserve("top") -;reserve_bottom -x:: Reserve("bottom") -;reserve_left -x:: Reserve("left") -;reserve_right -x:: Reserve("right") - -;reserve_float -x:: Reserve("float") -;reserve_stack -x:: Reserve("stack") - -~Esc:: { - CancelReservation() -} - -;focusTop -x:: focus("up") -;focus_bottom -x:: focus("down") -;focus_left -x:: focus("left") -;focus_right -x:: focus("right") - -;focus_latest -x:: focus("latest") - -; Increase or decrease window size -;increase_width -x:: updateWindowWidth("increase") -;decrease_width -x:: updateWindowWidth("decrease") -;increase_height -x:: updateWindowHeight("increase") -;decrease_height -x:: updateWindowHeight("decrease") - -;restore_sizes -x:: resetWorkspaceSize() - -; Switch workspaces -;switch_workspace_0 -x:: SwitchWorkspace(0) -;switch_workspace_1 -x:: SwitchWorkspace(1) -;switch_workspace_2 -x:: SwitchWorkspace(2) -;switch_workspace_3 -x:: SwitchWorkspace(3) -;switch_workspace_4 -x:: SwitchWorkspace(4) -;switch_workspace_5 -x:: SwitchWorkspace(5) -;switch_workspace_6 -x:: SwitchWorkspace(6) -;switch_workspace_7 -x:: SwitchWorkspace(7) -;switch_workspace_8 -x:: SwitchWorkspace(8) -;switch_workspace_9 -x:: SwitchWorkspace(9) - -; Send the focused window across workspaces and switch specified workspace -;move_to_workspace_0 -x:: MoveToWorkspace(0) -;move_to_workspace_1 -x:: MoveToWorkspace(1) -;move_to_workspace_2 -x:: MoveToWorkspace(2) -;move_to_workspace_3 -x:: MoveToWorkspace(3) -;move_to_workspace_4 -x:: MoveToWorkspace(4) -;move_to_workspace_5 -x:: MoveToWorkspace(5) -;move_to_workspace_6 -x:: MoveToWorkspace(6) -;move_to_workspace_7 -x:: MoveToWorkspace(7) -;move_to_workspace_8 -x:: MoveToWorkspace(8) -;move_to_workspace_9 -x:: MoveToWorkspace(9) - -; Send the focused window across workspaces -;send_to_workspace_0 -x:: SendToWorkspace(0) -;send_to_workspace_1 -x:: SendToWorkspace(1) -;send_to_workspace_2 -x:: SendToWorkspace(2) -;send_to_workspace_3 -x:: SendToWorkspace(3) -;send_to_workspace_4 -x:: SendToWorkspace(4) -;send_to_workspace_5 -x:: SendToWorkspace(5) -;send_to_workspace_6 -x:: SendToWorkspace(6) -;send_to_workspace_7 -x:: SendToWorkspace(7) -;send_to_workspace_8 -x:: SendToWorkspace(8) -;send_to_workspace_9 -x:: SendToWorkspace(9) - -/* -TODO - -!+q:: CycleFocus("previous") -!q:: CycleFocus("next") - -; Move windows -#+a:: Move("left") -#+s:: Move("down") -#+w:: Move("up") -#+d:: Move("right") - -#+Enter:: Promote() - -#+x:: FlipLayout("horizontal") -#+z:: FlipLayout("vertical") - -; Stack windows -#a:: Stack("left") -#d:: Stack("right") -#w:: Stack("up") -#s:: Stack("down") -#;:: Unstack() - -#+q:: CycleStack("previous") -#q:: CycleStack("next") - -; Manipulate windows -#f:: ToggleFloat() -#m:: ToggleMonocle() -*/ +/* + * This file is generated by Seelen UI and will be replaced on each update please don't modify manually. + * If you want to introduce your own implementation for shortcuts with AHK or any other scripting language + * just disable Seelen UI integrated shortcuts in the shortcuts tab, and this file will be ignored. +*/ +#Requires AutoHotkey v2.0 +#SingleInstance Force +#NoTrayIcon + +#Include seelen.lib.ahk + +CloseIfNotRunning() + +;debug_wm +^#!w:: WMDebug() + +^#!p:: { + PauseWM() + ExitApp() +} + +;reserve_top +x:: Reserve("top") +;reserve_bottom +x:: Reserve("bottom") +;reserve_left +x:: Reserve("left") +;reserve_right +x:: Reserve("right") + +;reserve_float +x:: Reserve("float") +;reserve_stack +x:: Reserve("stack") + +~Esc:: { + CancelReservation() +} + +;focusTop +x:: focus("up") +;focus_bottom +x:: focus("down") +;focus_left +x:: focus("left") +;focus_right +x:: focus("right") + +;focus_latest +x:: focus("latest") + +; Increase or decrease window size +;increase_width +x:: updateWindowWidth("increase") +;decrease_width +x:: updateWindowWidth("decrease") +;increase_height +x:: updateWindowHeight("increase") +;decrease_height +x:: updateWindowHeight("decrease") + +;restore_sizes +x:: resetWorkspaceSize() + +; Switch workspaces +;switch_workspace_0 +x:: SwitchWorkspace(0) +;switch_workspace_1 +x:: SwitchWorkspace(1) +;switch_workspace_2 +x:: SwitchWorkspace(2) +;switch_workspace_3 +x:: SwitchWorkspace(3) +;switch_workspace_4 +x:: SwitchWorkspace(4) +;switch_workspace_5 +x:: SwitchWorkspace(5) +;switch_workspace_6 +x:: SwitchWorkspace(6) +;switch_workspace_7 +x:: SwitchWorkspace(7) +;switch_workspace_8 +x:: SwitchWorkspace(8) +;switch_workspace_9 +x:: SwitchWorkspace(9) + +; Send the focused window across workspaces and switch specified workspace +;move_to_workspace_0 +x:: MoveToWorkspace(0) +;move_to_workspace_1 +x:: MoveToWorkspace(1) +;move_to_workspace_2 +x:: MoveToWorkspace(2) +;move_to_workspace_3 +x:: MoveToWorkspace(3) +;move_to_workspace_4 +x:: MoveToWorkspace(4) +;move_to_workspace_5 +x:: MoveToWorkspace(5) +;move_to_workspace_6 +x:: MoveToWorkspace(6) +;move_to_workspace_7 +x:: MoveToWorkspace(7) +;move_to_workspace_8 +x:: MoveToWorkspace(8) +;move_to_workspace_9 +x:: MoveToWorkspace(9) + +; Send the focused window across workspaces +;send_to_workspace_0 +x:: SendToWorkspace(0) +;send_to_workspace_1 +x:: SendToWorkspace(1) +;send_to_workspace_2 +x:: SendToWorkspace(2) +;send_to_workspace_3 +x:: SendToWorkspace(3) +;send_to_workspace_4 +x:: SendToWorkspace(4) +;send_to_workspace_5 +x:: SendToWorkspace(5) +;send_to_workspace_6 +x:: SendToWorkspace(6) +;send_to_workspace_7 +x:: SendToWorkspace(7) +;send_to_workspace_8 +x:: SendToWorkspace(8) +;send_to_workspace_9 +x:: SendToWorkspace(9) + +/* +TODO + +!+q:: CycleFocus("previous") +!q:: CycleFocus("next") + +; Move windows +#+a:: Move("left") +#+s:: Move("down") +#+w:: Move("up") +#+d:: Move("right") + +#+Enter:: Promote() + +#+x:: FlipLayout("horizontal") +#+z:: FlipLayout("vertical") + +; Stack windows +#a:: Stack("left") +#d:: Stack("right") +#w:: Stack("up") +#s:: Stack("down") +#;:: Unstack() + +#+q:: CycleStack("previous") +#q:: CycleStack("next") + +; Manipulate windows +#f:: ToggleFloat() +#m:: ToggleMonocle() +*/ diff --git a/src/background/utils/ahk/mod.rs b/src/background/utils/ahk/mod.rs index 06e98ed0..6a6055c1 100644 --- a/src/background/utils/ahk/mod.rs +++ b/src/background/utils/ahk/mod.rs @@ -1,158 +1,158 @@ -use std::{collections::HashMap, env::temp_dir, path::PathBuf}; - -use lazy_static::lazy_static; -use regex::Regex; -use tauri::{path::BaseDirectory, Manager}; -use tauri_plugin_shell::ShellExt; - -use crate::{error_handler::Result, seelen::get_app_handle, state::domain::AhkVar}; - -lazy_static! { - pub static ref LIB_AHK_PATH: PathBuf = { - let mut lib_ahk = AutoHotKey::new(include_str!("mocks/seelen.lib.ahk")); - - lib_ahk.inner = lib_ahk.inner.replace( - "SEELEN_UI_EXE_PATH", - &std::env::current_exe() - .expect("Failed to get current exe path") - .to_string_lossy(), - ); - - lib_ahk.save().expect("Failed to load lib.ahk") - }; -} - -pub struct AutoHotKey { - inner: String, -} - -impl AutoHotKey { - pub fn new(contents: &str) -> Self { - Self { - inner: contents.to_string(), - } - } - - pub fn from_template(template: &str, vars: HashMap) -> Self { - Self { - inner: Self::replace_variables(template.to_string(), vars), - } - } - - pub fn with_lib(mut self) -> Self { - self.inner = self - .inner - .replace("seelen.lib.ahk", &LIB_AHK_PATH.to_string_lossy()); - self - } - - pub fn save(&self) -> Result { - let script_path = temp_dir().join(format!("slu-{}.ahk", uuid::Uuid::new_v4())); - std::fs::write(&script_path, &self.inner)?; - Ok(script_path) - } - - pub fn execute(&self) -> Result<()> { - let script_path = self.save()?; - - let handle = get_app_handle(); - let ahk_executable_path = handle - .path() - .resolve("static/redis/AutoHotkey.exe", BaseDirectory::Resource)? - .to_string_lossy() - .trim_start_matches(r"\\?\") - .to_owned(); - - handle - .shell() - .command(ahk_executable_path) - .arg(script_path.to_string_lossy().to_string()) - .spawn()?; - - Ok(()) - } - - fn replace_variables(template: String, vars: HashMap) -> String { - let mut replaced = template.clone(); - - for (key, value) in vars.iter() { - let pattern = Regex::new(&format!(";{}\\s*x::", key)).unwrap(); - replaced = pattern - .replace_all(&replaced, format!("{}::", value.ahk)) - .to_string(); - } - - replaced.replace("x::", ";missing_shortcut::") - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn replace_variables() { - let mut vars = HashMap::new(); - vars.insert( - "test".to_string(), - AhkVar { - fancy: String::new(), - ahk: "!b".to_string(), - }, - ); - vars.insert( - "test2".to_string(), - AhkVar { - fancy: String::new(), - ahk: "!c".to_string(), - }, - ); - - let template = r#" - ; other comment - ;test - x:: anything() - ;test2 - x:: anything2() - "# - .to_owned(); - - let expected = r#" - ; other comment - !b:: anything() - !c:: anything2() - "#; - - assert_eq!(AutoHotKey::replace_variables(template, vars), expected); - } - - #[test] - fn comment_missing_shortcuts() { - let mut vars = HashMap::new(); - vars.insert( - "test".to_string(), - AhkVar { - fancy: String::new(), - ahk: "!b".to_string(), - }, - ); - - let template = r#" - ; other comment - ;test - x:: anything() - ;test2 - x:: anything2() - "# - .to_owned(); - - let expected = r#" - ; other comment - !b:: anything() - ;test2 - ;missing_shortcut:: anything2() - "#; - - assert_eq!(AutoHotKey::replace_variables(template, vars), expected); - } -} +use std::{collections::HashMap, env::temp_dir, path::PathBuf}; + +use lazy_static::lazy_static; +use regex::Regex; +use tauri::{path::BaseDirectory, Manager}; +use tauri_plugin_shell::ShellExt; + +use crate::{error_handler::Result, seelen::get_app_handle, state::domain::AhkVar}; + +lazy_static! { + pub static ref LIB_AHK_PATH: PathBuf = { + let mut lib_ahk = AutoHotKey::new(include_str!("mocks/seelen.lib.ahk")); + + lib_ahk.inner = lib_ahk.inner.replace( + "SEELEN_UI_EXE_PATH", + &std::env::current_exe() + .expect("Failed to get current exe path") + .to_string_lossy(), + ); + + lib_ahk.save().expect("Failed to load lib.ahk") + }; +} + +pub struct AutoHotKey { + inner: String, +} + +impl AutoHotKey { + pub fn new(contents: &str) -> Self { + Self { + inner: contents.to_string(), + } + } + + pub fn from_template(template: &str, vars: HashMap) -> Self { + Self { + inner: Self::replace_variables(template.to_string(), vars), + } + } + + pub fn with_lib(mut self) -> Self { + self.inner = self + .inner + .replace("seelen.lib.ahk", &LIB_AHK_PATH.to_string_lossy()); + self + } + + pub fn save(&self) -> Result { + let script_path = temp_dir().join(format!("slu-{}.ahk", uuid::Uuid::new_v4())); + std::fs::write(&script_path, &self.inner)?; + Ok(script_path) + } + + pub fn execute(&self) -> Result<()> { + let script_path = self.save()?; + + let handle = get_app_handle(); + let ahk_executable_path = handle + .path() + .resolve("static/redis/AutoHotkey.exe", BaseDirectory::Resource)? + .to_string_lossy() + .trim_start_matches(r"\\?\") + .to_owned(); + + handle + .shell() + .command(ahk_executable_path) + .arg(script_path.to_string_lossy().to_string()) + .spawn()?; + + Ok(()) + } + + fn replace_variables(template: String, vars: HashMap) -> String { + let mut replaced = template.clone(); + + for (key, value) in vars.iter() { + let pattern = Regex::new(&format!(";{}\\s*x::", key)).unwrap(); + replaced = pattern + .replace_all(&replaced, format!("{}::", value.ahk)) + .to_string(); + } + + replaced.replace("x::", ";missing_shortcut::") + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn replace_variables() { + let mut vars = HashMap::new(); + vars.insert( + "test".to_string(), + AhkVar { + fancy: String::new(), + ahk: "!b".to_string(), + }, + ); + vars.insert( + "test2".to_string(), + AhkVar { + fancy: String::new(), + ahk: "!c".to_string(), + }, + ); + + let template = r#" + ; other comment + ;test + x:: anything() + ;test2 + x:: anything2() + "# + .to_owned(); + + let expected = r#" + ; other comment + !b:: anything() + !c:: anything2() + "#; + + assert_eq!(AutoHotKey::replace_variables(template, vars), expected); + } + + #[test] + fn comment_missing_shortcuts() { + let mut vars = HashMap::new(); + vars.insert( + "test".to_string(), + AhkVar { + fancy: String::new(), + ahk: "!b".to_string(), + }, + ); + + let template = r#" + ; other comment + ;test + x:: anything() + ;test2 + x:: anything2() + "# + .to_owned(); + + let expected = r#" + ; other comment + !b:: anything() + ;test2 + ;missing_shortcut:: anything2() + "#; + + assert_eq!(AutoHotKey::replace_variables(template, vars), expected); + } +} diff --git a/src/background/utils/constants.rs b/src/background/utils/constants.rs index 2a9381b8..49968a74 100644 --- a/src/background/utils/constants.rs +++ b/src/background/utils/constants.rs @@ -1,37 +1,37 @@ -use itertools::Itertools; -use lazy_static::lazy_static; - -lazy_static! { - pub static ref IGNORE_FOCUS: Vec = [ - "Task Switching", - "Task View", - "Virtual desktop switching preview", - "Virtual desktop hotkey switching preview", - "Seelen Window Manager", - ] - .iter() - .map(|x| x.to_string()) - .collect_vec(); - - pub static ref IGNORE_FULLSCREEN: Vec = [ - "Task Switching", - "Task View", - "Virtual desktop switching preview", - "Virtual desktop hotkey switching preview", - "Seelen Window Manager", - "Seelen Fancy Toolbar", - "SeelenWeg" - ] - .iter() - .map(|x| x.to_string()) - .collect_vec(); - - /** - * Some UWP apps like WhatsApp are resized after be opened, - * this list will be used to resize them back after a delay. - */ - pub static ref FORCE_RETILING_AFTER_ADD: Vec = ["WhatsApp"] - .iter() - .map(|x| x.to_string()) - .collect_vec(); -} +use itertools::Itertools; +use lazy_static::lazy_static; + +lazy_static! { + pub static ref IGNORE_FOCUS: Vec = [ + "Task Switching", + "Task View", + "Virtual desktop switching preview", + "Virtual desktop hotkey switching preview", + "Seelen Window Manager", + ] + .iter() + .map(|x| x.to_string()) + .collect_vec(); + + pub static ref IGNORE_FULLSCREEN: Vec = [ + "Task Switching", + "Task View", + "Virtual desktop switching preview", + "Virtual desktop hotkey switching preview", + "Seelen Window Manager", + "Seelen Fancy Toolbar", + "SeelenWeg" + ] + .iter() + .map(|x| x.to_string()) + .collect_vec(); + + /** + * Some UWP apps like WhatsApp are resized after be opened, + * this list will be used to resize them back after a delay. + */ + pub static ref FORCE_RETILING_AFTER_ADD: Vec = ["WhatsApp"] + .iter() + .map(|x| x.to_string()) + .collect_vec(); +} diff --git a/src/background/utils/mod.rs b/src/background/utils/mod.rs index c120555b..e89a3cea 100644 --- a/src/background/utils/mod.rs +++ b/src/background/utils/mod.rs @@ -1,156 +1,156 @@ -pub mod ahk; -pub mod constants; -pub mod pwsh; -pub mod rect; -pub mod virtual_desktop; - -use std::{ - path::PathBuf, - time::{Duration, Instant}, -}; - -use itertools::Itertools; -use lazy_static::lazy_static; -use parking_lot::Mutex; -use tauri::{AppHandle, Manager}; -use windows::{ - core::GUID, - Win32::{ - Foundation::{HANDLE, RECT}, - UI::Shell::{SHGetKnownFolderPath, KF_FLAG_DEFAULT}, - }, -}; - -use crate::error_handler::Result; - -pub fn pcwstr(s: &str) -> windows::core::PCWSTR { - windows::core::PCWSTR::from_raw(s.encode_utf16().chain(Some(0)).collect_vec().as_ptr()) -} - -pub fn sleep_millis(millis: u64) { - std::thread::sleep(Duration::from_millis(millis)); -} - -pub fn are_overlaped(a: &RECT, b: &RECT) -> bool { - if a.right < b.left || a.left > b.right || a.bottom < b.top || a.top > b.bottom { - return false; - } - true -} - -pub fn pascal_to_kebab(input: &str) -> String { - let mut kebab_case = String::new(); - let mut prev_char_lowercase = false; - for c in input.chars() { - if c.is_uppercase() { - if prev_char_lowercase { - kebab_case.push('-'); - } - kebab_case.push(c.to_ascii_lowercase()); - prev_char_lowercase = false; - } else { - kebab_case.push(c); - prev_char_lowercase = true; - } - } - kebab_case -} - -pub fn kebab_to_pascal(input: &str) -> String { - let mut pascal_case = String::new(); - let mut prev_char_dash = false; - for c in input.chars() { - if c == '-' { - prev_char_dash = true; - } else if prev_char_dash || pascal_case.is_empty() { - pascal_case.push(c.to_ascii_uppercase()); - prev_char_dash = false; - } else { - pascal_case.push(c); - } - } - pascal_case -} - -pub fn is_windows_10() -> bool { - matches!(os_info::get().version(), os_info::Version::Semantic(_, _, x) if (&10240..&22000).contains(&x)) -} - -pub fn is_windows_11() -> bool { - matches!(os_info::get().version(), os_info::Version::Semantic(_, _, x) if x >= &22000) -} - -/// Resolve paths with folder ids in the form of "{GUID}\path\to\file" -/// -/// https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid -pub fn resolve_guid_path>(path: S) -> Result { - let parts = path.as_ref().split("\\"); - let mut path_buf = PathBuf::new(); - - for (idx, part) in parts.into_iter().enumerate() { - if part.starts_with("{") && part.ends_with("}") { - let guid = part.trim_start_matches('{').trim_end_matches('}'); - let rfid = GUID::from(guid); - let string_path = unsafe { - SHGetKnownFolderPath(&rfid as _, KF_FLAG_DEFAULT, HANDLE(0))?.to_string()? - }; - - path_buf.push(string_path); - } else if idx == 0 { - return Ok(PathBuf::from(path.as_ref())); - } else { - path_buf.push(part); - } - } - - Ok(path_buf) -} - -pub fn app_data_path(handle: &AppHandle) -> PathBuf { - handle - .path() - .app_data_dir() - .expect("Failed to resolve App Data path") -} - -#[macro_export] -macro_rules! trace_lock { - ($mutex:expr) => {{ - #[cfg(feature = "trace_lock")] - { - log::debug!( - "Attempting to acquire lock on {} at {}:{}", - stringify!($mutex), - file!(), - line!() - ); - let lock = $mutex.lock(); - log::debug!("Successfully acquired lock on {}", stringify!($mutex)); - lock - } - #[cfg(not(feature = "trace_lock"))] - { - $mutex.lock() - } - }}; -} - -lazy_static! { - pub static ref PERFORMANCE_HELPER: Mutex = Mutex::new(PerformanceHelper { - time: Instant::now() - }); -} - -pub struct PerformanceHelper { - time: Instant, -} - -impl PerformanceHelper { - pub fn start(&mut self) { - self.time = Instant::now(); - } - - pub fn elapsed(&self) -> Duration { - self.time.elapsed() - } -} +pub mod ahk; +pub mod constants; +pub mod pwsh; +pub mod rect; +pub mod virtual_desktop; + +use std::{ + path::PathBuf, + time::{Duration, Instant}, +}; + +use itertools::Itertools; +use lazy_static::lazy_static; +use parking_lot::Mutex; +use tauri::{AppHandle, Manager}; +use windows::{ + core::GUID, + Win32::{ + Foundation::{HANDLE, RECT}, + UI::Shell::{SHGetKnownFolderPath, KF_FLAG_DEFAULT}, + }, +}; + +use crate::error_handler::Result; + +pub fn pcwstr(s: &str) -> windows::core::PCWSTR { + windows::core::PCWSTR::from_raw(s.encode_utf16().chain(Some(0)).collect_vec().as_ptr()) +} + +pub fn sleep_millis(millis: u64) { + std::thread::sleep(Duration::from_millis(millis)); +} + +pub fn are_overlaped(a: &RECT, b: &RECT) -> bool { + if a.right < b.left || a.left > b.right || a.bottom < b.top || a.top > b.bottom { + return false; + } + true +} + +pub fn pascal_to_kebab(input: &str) -> String { + let mut kebab_case = String::new(); + let mut prev_char_lowercase = false; + for c in input.chars() { + if c.is_uppercase() { + if prev_char_lowercase { + kebab_case.push('-'); + } + kebab_case.push(c.to_ascii_lowercase()); + prev_char_lowercase = false; + } else { + kebab_case.push(c); + prev_char_lowercase = true; + } + } + kebab_case +} + +pub fn kebab_to_pascal(input: &str) -> String { + let mut pascal_case = String::new(); + let mut prev_char_dash = false; + for c in input.chars() { + if c == '-' { + prev_char_dash = true; + } else if prev_char_dash || pascal_case.is_empty() { + pascal_case.push(c.to_ascii_uppercase()); + prev_char_dash = false; + } else { + pascal_case.push(c); + } + } + pascal_case +} + +pub fn is_windows_10() -> bool { + matches!(os_info::get().version(), os_info::Version::Semantic(_, _, x) if (&10240..&22000).contains(&x)) +} + +pub fn is_windows_11() -> bool { + matches!(os_info::get().version(), os_info::Version::Semantic(_, _, x) if x >= &22000) +} + +/// Resolve paths with folder ids in the form of "{GUID}\path\to\file" +/// +/// https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid +pub fn resolve_guid_path>(path: S) -> Result { + let parts = path.as_ref().split("\\"); + let mut path_buf = PathBuf::new(); + + for (idx, part) in parts.into_iter().enumerate() { + if part.starts_with("{") && part.ends_with("}") { + let guid = part.trim_start_matches('{').trim_end_matches('}'); + let rfid = GUID::from(guid); + let string_path = unsafe { + SHGetKnownFolderPath(&rfid as _, KF_FLAG_DEFAULT, HANDLE(0))?.to_string()? + }; + + path_buf.push(string_path); + } else if idx == 0 { + return Ok(PathBuf::from(path.as_ref())); + } else { + path_buf.push(part); + } + } + + Ok(path_buf) +} + +pub fn app_data_path(handle: &AppHandle) -> PathBuf { + handle + .path() + .app_data_dir() + .expect("Failed to resolve App Data path") +} + +#[macro_export] +macro_rules! trace_lock { + ($mutex:expr) => {{ + #[cfg(feature = "trace_lock")] + { + log::debug!( + "Attempting to acquire lock on {} at {}:{}", + stringify!($mutex), + file!(), + line!() + ); + let lock = $mutex.lock(); + log::debug!("Successfully acquired lock on {}", stringify!($mutex)); + lock + } + #[cfg(not(feature = "trace_lock"))] + { + $mutex.lock() + } + }}; +} + +lazy_static! { + pub static ref PERFORMANCE_HELPER: Mutex = Mutex::new(PerformanceHelper { + time: Instant::now() + }); +} + +pub struct PerformanceHelper { + time: Instant, +} + +impl PerformanceHelper { + pub fn start(&mut self) { + self.time = Instant::now(); + } + + pub fn elapsed(&self) -> Duration { + self.time.elapsed() + } +} diff --git a/src/background/utils/pwsh.rs b/src/background/utils/pwsh.rs index 3bece89c..5de62d8e 100644 --- a/src/background/utils/pwsh.rs +++ b/src/background/utils/pwsh.rs @@ -1,64 +1,64 @@ -use std::env::temp_dir; - -use itertools::Itertools; -use tauri_plugin_shell::ShellExt; - -use crate::{error_handler::Result, seelen::get_app_handle}; - -pub struct PwshScript { - inner: String, - args: Vec, -} - -impl PwshScript { - pub fn new>(contents: S) -> Self { - Self { - inner: contents.into(), - args: Vec::new(), - } - } - - pub fn with_args(&mut self, args: I) - where - I: IntoIterator, - S: Into, - { - self.args = args.into_iter().map(|s| s.into()).collect_vec(); - } - - /// returns `Ok(stdout)` or `Err(stderr)` - pub async fn execute(self) -> Result { - let script_path = temp_dir().join(format!("slu-{}.ps1", uuid::Uuid::new_v4())); - let script_path_str = script_path.to_string_lossy(); - - let args = [ - "-ExecutionPolicy", - "Bypass", - "-NoProfile", - "-File", - &script_path_str, - ] - .iter() - .map(|s| s.to_string()) - .chain(self.args.clone()) - .collect_vec(); - - std::fs::write(&script_path, &self.inner)?; - - let handle = get_app_handle(); - let output = handle - .shell() - .command("powershell") - .args(args) - .output() - .await?; - - std::fs::remove_file(&script_path)?; - - if output.status.success() { - Ok(String::from_utf8(output.stdout)?.trim().to_owned()) - } else { - Err(output.into()) - } - } -} +use std::env::temp_dir; + +use itertools::Itertools; +use tauri_plugin_shell::ShellExt; + +use crate::{error_handler::Result, seelen::get_app_handle}; + +pub struct PwshScript { + inner: String, + args: Vec, +} + +impl PwshScript { + pub fn new>(contents: S) -> Self { + Self { + inner: contents.into(), + args: Vec::new(), + } + } + + pub fn with_args(&mut self, args: I) + where + I: IntoIterator, + S: Into, + { + self.args = args.into_iter().map(|s| s.into()).collect_vec(); + } + + /// returns `Ok(stdout)` or `Err(stderr)` + pub async fn execute(self) -> Result { + let script_path = temp_dir().join(format!("slu-{}.ps1", uuid::Uuid::new_v4())); + let script_path_str = script_path.to_string_lossy(); + + let args = [ + "-ExecutionPolicy", + "Bypass", + "-NoProfile", + "-File", + &script_path_str, + ] + .iter() + .map(|s| s.to_string()) + .chain(self.args.clone()) + .collect_vec(); + + std::fs::write(&script_path, &self.inner)?; + + let handle = get_app_handle(); + let output = handle + .shell() + .command("powershell") + .args(args) + .output() + .await?; + + std::fs::remove_file(&script_path)?; + + if output.status.success() { + Ok(String::from_utf8(output.stdout)?.trim().to_owned()) + } else { + Err(output.into()) + } + } +} diff --git a/src/background/utils/rect.rs b/src/background/utils/rect.rs index 721e2d05..cb63d83b 100644 --- a/src/background/utils/rect.rs +++ b/src/background/utils/rect.rs @@ -1,42 +1,42 @@ -use serde::{Deserialize, Serialize}; -use windows::Win32::Foundation::RECT; - -#[derive(Serialize, Deserialize, Debug, Clone, Default)] -pub struct Rect { - pub left: i32, - pub top: i32, - pub right: i32, - pub bottom: i32, -} - -impl From for Rect { - fn from(rect: RECT) -> Self { - Self { - left: rect.left, - top: rect.top, - right: rect.right, - bottom: rect.bottom, - } - } -} - -impl From for RECT { - fn from(val: Rect) -> Self { - RECT { - left: val.left, - top: val.top, - right: val.right, - bottom: val.bottom, - } - } -} - -impl Eq for Rect {} -impl PartialEq for Rect { - fn eq(&self, other: &Self) -> bool { - self.left == other.left - && self.top == other.top - && self.right == other.right - && self.bottom == other.bottom - } -} +use serde::{Deserialize, Serialize}; +use windows::Win32::Foundation::RECT; + +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub struct Rect { + pub left: i32, + pub top: i32, + pub right: i32, + pub bottom: i32, +} + +impl From for Rect { + fn from(rect: RECT) -> Self { + Self { + left: rect.left, + top: rect.top, + right: rect.right, + bottom: rect.bottom, + } + } +} + +impl From for RECT { + fn from(val: Rect) -> Self { + RECT { + left: val.left, + top: val.top, + right: val.right, + bottom: val.bottom, + } + } +} + +impl Eq for Rect {} +impl PartialEq for Rect { + fn eq(&self, other: &Self) -> bool { + self.left == other.left + && self.top == other.top + && self.right == other.right + && self.bottom == other.bottom + } +} diff --git a/src/background/utils/virtual_desktop.rs b/src/background/utils/virtual_desktop.rs index 9ae07c62..d3fcc579 100644 --- a/src/background/utils/virtual_desktop.rs +++ b/src/background/utils/virtual_desktop.rs @@ -1,112 +1,112 @@ -use color_eyre::eyre::eyre; -use windows::{core::GUID, Win32::Foundation::HWND}; -use winreg::{enums::HKEY_CURRENT_USER, RegKey}; - -use crate::{error_handler::Result, windows_api::WindowsApi}; - -pub struct VirtualDesktopManager {} - -pub struct VirtualDesktop { - #[allow(dead_code)] - id: [u8; 16], - guid: GUID, - #[allow(dead_code)] - name: String, -} - -impl From for VirtualDesktop { - fn from(guid: GUID) -> Self { - let mut id: Vec = Vec::new(); - id.append(&mut guid.data1.to_le_bytes().to_vec()); - id.append(&mut guid.data2.to_le_bytes().to_vec()); - id.append(&mut guid.data3.to_le_bytes().to_vec()); - id.append(&mut guid.data4.to_vec()); - - Self { - id: id.try_into().expect("Invalid id length"), - guid, - name: String::new(), - } - } -} - -impl From> for VirtualDesktop { - fn from(id: Vec) -> Self { - Self { - id: id.clone().try_into().expect("Invalid id length"), - guid: GUID { - data1: u32::from_le_bytes(id[0..4].try_into().unwrap()), - data2: u16::from_le_bytes(id[4..6].try_into().unwrap()), - data3: u16::from_le_bytes(id[6..8].try_into().unwrap()), - data4: id[8..].try_into().unwrap(), - }, - name: String::new(), - } - } -} - -impl VirtualDesktop { - pub fn id(&self) -> String { - format!("{:?}", self.guid) - } - - pub fn guid(&self) -> GUID { - self.guid - } -} - -impl VirtualDesktopManager { - pub fn enum_virtual_desktops() -> Result> { - let session_id = WindowsApi::current_session_id()?; - let hkcu = RegKey::predef(HKEY_CURRENT_USER); - - // This is the path on Windows 10 - let mut current = hkcu - .open_subkey(format!( - r"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SessionInfo\{session_id}\VirtualDesktops" - )) - .ok() - .and_then( - |desktops| match desktops.get_raw_value("VirtualDesktopIDs") { - Ok(current) => Option::from(current.bytes), - Err(_) => None, - }, - ); - - // This is the path on Windows 11 - if current.is_none() { - current = hkcu - .open_subkey(r"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VirtualDesktops") - .ok() - .and_then( - |desktops| match desktops.get_raw_value("VirtualDesktopIDs") { - Ok(current) => Option::from(current.bytes), - Err(_) => None, - }, - ); - } - - match current { - Some(current) => { - let mut result = Vec::new(); - for desktop_id in current.chunks_exact(16).map(Vec::from) { - result.push(VirtualDesktop::from(desktop_id)) - } - Ok(result) - } - None => Err(eyre!("could not determine current virtual desktop").into()), - } - } - - pub fn get_by_window(hwnd: HWND) -> Result { - Ok(VirtualDesktop::from( - winvd::get_desktop_by_window(hwnd)?.get_id()?, - )) - } - - pub fn get_current_virtual_desktop() -> Result { - Ok(VirtualDesktop::from( - winvd::get_current_desktop()?.get_id()?, - )) - } -} +use color_eyre::eyre::eyre; +use windows::{core::GUID, Win32::Foundation::HWND}; +use winreg::{enums::HKEY_CURRENT_USER, RegKey}; + +use crate::{error_handler::Result, windows_api::WindowsApi}; + +pub struct VirtualDesktopManager {} + +pub struct VirtualDesktop { + #[allow(dead_code)] + id: [u8; 16], + guid: GUID, + #[allow(dead_code)] + name: String, +} + +impl From for VirtualDesktop { + fn from(guid: GUID) -> Self { + let mut id: Vec = Vec::new(); + id.append(&mut guid.data1.to_le_bytes().to_vec()); + id.append(&mut guid.data2.to_le_bytes().to_vec()); + id.append(&mut guid.data3.to_le_bytes().to_vec()); + id.append(&mut guid.data4.to_vec()); + + Self { + id: id.try_into().expect("Invalid id length"), + guid, + name: String::new(), + } + } +} + +impl From> for VirtualDesktop { + fn from(id: Vec) -> Self { + Self { + id: id.clone().try_into().expect("Invalid id length"), + guid: GUID { + data1: u32::from_le_bytes(id[0..4].try_into().unwrap()), + data2: u16::from_le_bytes(id[4..6].try_into().unwrap()), + data3: u16::from_le_bytes(id[6..8].try_into().unwrap()), + data4: id[8..].try_into().unwrap(), + }, + name: String::new(), + } + } +} + +impl VirtualDesktop { + pub fn id(&self) -> String { + format!("{:?}", self.guid) + } + + pub fn guid(&self) -> GUID { + self.guid + } +} + +impl VirtualDesktopManager { + pub fn enum_virtual_desktops() -> Result> { + let session_id = WindowsApi::current_session_id()?; + let hkcu = RegKey::predef(HKEY_CURRENT_USER); + + // This is the path on Windows 10 + let mut current = hkcu + .open_subkey(format!( + r"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SessionInfo\{session_id}\VirtualDesktops" + )) + .ok() + .and_then( + |desktops| match desktops.get_raw_value("VirtualDesktopIDs") { + Ok(current) => Option::from(current.bytes), + Err(_) => None, + }, + ); + + // This is the path on Windows 11 + if current.is_none() { + current = hkcu + .open_subkey(r"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VirtualDesktops") + .ok() + .and_then( + |desktops| match desktops.get_raw_value("VirtualDesktopIDs") { + Ok(current) => Option::from(current.bytes), + Err(_) => None, + }, + ); + } + + match current { + Some(current) => { + let mut result = Vec::new(); + for desktop_id in current.chunks_exact(16).map(Vec::from) { + result.push(VirtualDesktop::from(desktop_id)) + } + Ok(result) + } + None => Err(eyre!("could not determine current virtual desktop").into()), + } + } + + pub fn get_by_window(hwnd: HWND) -> Result { + Ok(VirtualDesktop::from( + winvd::get_desktop_by_window(hwnd)?.get_id()?, + )) + } + + pub fn get_current_virtual_desktop() -> Result { + Ok(VirtualDesktop::from( + winvd::get_current_desktop()?.get_id()?, + )) + } +} diff --git a/src/background/windows_api/app_bar.rs b/src/background/windows_api/app_bar.rs index 86039736..798c0399 100644 --- a/src/background/windows_api/app_bar.rs +++ b/src/background/windows_api/app_bar.rs @@ -1,94 +1,94 @@ -use lazy_static::lazy_static; -use parking_lot::Mutex; -use windows::Win32::{ - Foundation::{HWND, LPARAM, RECT}, - UI::Shell::{ - SHAppBarMessage, ABE_BOTTOM, ABE_LEFT, ABE_RIGHT, ABE_TOP, ABM_GETSTATE, ABM_NEW, - ABM_REMOVE, ABM_SETPOS, ABM_SETSTATE, ABS_ALWAYSONTOP, ABS_AUTOHIDE, APPBARDATA, - }, -}; - -lazy_static! { - pub static ref RegisteredBars: Mutex> = Mutex::new(Vec::new()); -} - -#[allow(dead_code)] -pub enum AppBarDataEdge { - Left = ABE_LEFT as isize, - Top = ABE_TOP as isize, - Right = ABE_RIGHT as isize, - Bottom = ABE_BOTTOM as isize, -} - -/// https://learn.microsoft.com/en-us/windows/win32/shell/abm-setstate#parameters -#[derive(Debug, Clone, Copy)] -pub enum AppBarDataState { - BothOff = 0, - AutoHide = ABS_AUTOHIDE as isize, - AlwaysOnTop = ABS_ALWAYSONTOP as isize, - BothOn = 3, -} - -impl From for LPARAM { - fn from(val: AppBarDataState) -> Self { - LPARAM(val as isize) - } -} - -impl From for AppBarDataState { - fn from(state: u32) -> Self { - match state { - 0 => AppBarDataState::BothOff, - ABS_AUTOHIDE => AppBarDataState::AutoHide, - ABS_ALWAYSONTOP => AppBarDataState::AlwaysOnTop, - 3 => AppBarDataState::BothOn, - _ => unreachable!(), - } - } -} - -pub struct AppBarData(APPBARDATA); -impl AppBarData { - pub fn from_handle(hwnd: HWND) -> Self { - Self(APPBARDATA { - cbSize: std::mem::size_of::() as u32, - hWnd: hwnd, - ..Default::default() - }) - } - - pub fn state(&self) -> AppBarDataState { - let mut data = self.0; - AppBarDataState::from(unsafe { SHAppBarMessage(ABM_GETSTATE, &mut data) as u32 }) - } - - pub fn set_state(&self, state: AppBarDataState) { - let mut data = self.0; - data.lParam = state.into(); - unsafe { SHAppBarMessage(ABM_SETSTATE, &mut data) }; - } - - pub fn set_edge(&mut self, edge: AppBarDataEdge) { - self.0.uEdge = edge as u32; - } - - pub fn set_rect(&mut self, rect: RECT) { - self.0.rc = rect; - } - - pub fn register_as_new_bar(&mut self) { - let mut data = self.0; - let mut registered = RegisteredBars.lock(); - if !registered.contains(&data.hWnd.0) { - registered.push(data.hWnd.0); - unsafe { SHAppBarMessage(ABM_NEW, &mut data) }; - } - unsafe { SHAppBarMessage(ABM_SETPOS, &mut data) }; - } - - pub fn unregister_bar(&mut self) { - let mut data = self.0; - unsafe { SHAppBarMessage(ABM_REMOVE, &mut data) }; - RegisteredBars.lock().retain(|x| *x != data.hWnd.0); - } -} +use lazy_static::lazy_static; +use parking_lot::Mutex; +use windows::Win32::{ + Foundation::{HWND, LPARAM, RECT}, + UI::Shell::{ + SHAppBarMessage, ABE_BOTTOM, ABE_LEFT, ABE_RIGHT, ABE_TOP, ABM_GETSTATE, ABM_NEW, + ABM_REMOVE, ABM_SETPOS, ABM_SETSTATE, ABS_ALWAYSONTOP, ABS_AUTOHIDE, APPBARDATA, + }, +}; + +lazy_static! { + pub static ref RegisteredBars: Mutex> = Mutex::new(Vec::new()); +} + +#[allow(dead_code)] +pub enum AppBarDataEdge { + Left = ABE_LEFT as isize, + Top = ABE_TOP as isize, + Right = ABE_RIGHT as isize, + Bottom = ABE_BOTTOM as isize, +} + +/// https://learn.microsoft.com/en-us/windows/win32/shell/abm-setstate#parameters +#[derive(Debug, Clone, Copy)] +pub enum AppBarDataState { + BothOff = 0, + AutoHide = ABS_AUTOHIDE as isize, + AlwaysOnTop = ABS_ALWAYSONTOP as isize, + BothOn = 3, +} + +impl From for LPARAM { + fn from(val: AppBarDataState) -> Self { + LPARAM(val as isize) + } +} + +impl From for AppBarDataState { + fn from(state: u32) -> Self { + match state { + 0 => AppBarDataState::BothOff, + ABS_AUTOHIDE => AppBarDataState::AutoHide, + ABS_ALWAYSONTOP => AppBarDataState::AlwaysOnTop, + 3 => AppBarDataState::BothOn, + _ => unreachable!(), + } + } +} + +pub struct AppBarData(APPBARDATA); +impl AppBarData { + pub fn from_handle(hwnd: HWND) -> Self { + Self(APPBARDATA { + cbSize: std::mem::size_of::() as u32, + hWnd: hwnd, + ..Default::default() + }) + } + + pub fn state(&self) -> AppBarDataState { + let mut data = self.0; + AppBarDataState::from(unsafe { SHAppBarMessage(ABM_GETSTATE, &mut data) as u32 }) + } + + pub fn set_state(&self, state: AppBarDataState) { + let mut data = self.0; + data.lParam = state.into(); + unsafe { SHAppBarMessage(ABM_SETSTATE, &mut data) }; + } + + pub fn set_edge(&mut self, edge: AppBarDataEdge) { + self.0.uEdge = edge as u32; + } + + pub fn set_rect(&mut self, rect: RECT) { + self.0.rc = rect; + } + + pub fn register_as_new_bar(&mut self) { + let mut data = self.0; + let mut registered = RegisteredBars.lock(); + if !registered.contains(&data.hWnd.0) { + registered.push(data.hWnd.0); + unsafe { SHAppBarMessage(ABM_NEW, &mut data) }; + } + unsafe { SHAppBarMessage(ABM_SETPOS, &mut data) }; + } + + pub fn unregister_bar(&mut self) { + let mut data = self.0; + unsafe { SHAppBarMessage(ABM_REMOVE, &mut data) }; + RegisteredBars.lock().retain(|x| *x != data.hWnd.0); + } +} diff --git a/src/background/windows_api/com.rs b/src/background/windows_api/com.rs index bd7b6cad..70a0d4ab 100644 --- a/src/background/windows_api/com.rs +++ b/src/background/windows_api/com.rs @@ -1,65 +1,65 @@ -use std::thread::JoinHandle; - -use crate::error_handler::Result; -use windows::{ - core::{Interface, GUID}, - Win32::System::Com::{ - CoCreateInstance, CoInitializeEx, CoUninitialize, CLSCTX_ALL, COINIT_APARTMENTTHREADED, - COINIT_MULTITHREADED, - }, -}; - -pub struct Com {} -impl Com { - fn initialize() -> Result<()> { - let result = unsafe { CoInitializeEx(None, COINIT_APARTMENTTHREADED) }; - if result.is_err() { - return Err("CoInitializeEx failed".into()); - } - Ok(()) - } - - fn initialize_multithreaded() -> Result<()> { - let result = unsafe { CoInitializeEx(None, COINIT_MULTITHREADED) }; - if result.is_err() { - return Err("CoInitializeEx failed".into()); - } - Ok(()) - } - - pub fn create_instance(class_id: &GUID) -> Result - where - T: Interface, - { - unsafe { Ok(CoCreateInstance(class_id, None, CLSCTX_ALL)?) } - } - - /// Can panic if Com instances created between init and drop are still alive (no dropped yet) - fn uninitialize() { - unsafe { CoUninitialize() }; - } - - /// Will execute init and drop in a safe way, ensuring that all instances created between init and drop are dropped - pub fn run_with_context(f: F) -> Result - where - F: FnOnce() -> Result, - { - Self::initialize()?; - let result = f(); - Self::uninitialize(); - result - } - - pub fn run_threaded_with_context(f: F) -> JoinHandle - where - F: FnOnce() -> T + Send + 'static, - T: Send + 'static, - { - std::thread::spawn(|| { - Self::initialize_multithreaded().expect("failed to initialize multithreaded"); - let result = f(); - Self::uninitialize(); - result - }) - } -} +use std::thread::JoinHandle; + +use crate::error_handler::Result; +use windows::{ + core::{Interface, GUID}, + Win32::System::Com::{ + CoCreateInstance, CoInitializeEx, CoUninitialize, CLSCTX_ALL, COINIT_APARTMENTTHREADED, + COINIT_MULTITHREADED, + }, +}; + +pub struct Com {} +impl Com { + fn initialize() -> Result<()> { + let result = unsafe { CoInitializeEx(None, COINIT_APARTMENTTHREADED) }; + if result.is_err() { + return Err("CoInitializeEx failed".into()); + } + Ok(()) + } + + fn initialize_multithreaded() -> Result<()> { + let result = unsafe { CoInitializeEx(None, COINIT_MULTITHREADED) }; + if result.is_err() { + return Err("CoInitializeEx failed".into()); + } + Ok(()) + } + + pub fn create_instance(class_id: &GUID) -> Result + where + T: Interface, + { + unsafe { Ok(CoCreateInstance(class_id, None, CLSCTX_ALL)?) } + } + + /// Can panic if Com instances created between init and drop are still alive (no dropped yet) + fn uninitialize() { + unsafe { CoUninitialize() }; + } + + /// Will execute init and drop in a safe way, ensuring that all instances created between init and drop are dropped + pub fn run_with_context(f: F) -> Result + where + F: FnOnce() -> Result, + { + Self::initialize()?; + let result = f(); + Self::uninitialize(); + result + } + + pub fn run_threaded_with_context(f: F) -> JoinHandle + where + F: FnOnce() -> T + Send + 'static, + T: Send + 'static, + { + std::thread::spawn(|| { + Self::initialize_multithreaded().expect("failed to initialize multithreaded"); + let result = f(); + Self::uninitialize(); + result + }) + } +} diff --git a/src/background/windows_api/iterator.rs b/src/background/windows_api/iterator.rs index 83e220f0..73ed9e23 100644 --- a/src/background/windows_api/iterator.rs +++ b/src/background/windows_api/iterator.rs @@ -1,96 +1,96 @@ -use std::slice::Iter; - -use windows::Win32::{ - Foundation::{BOOL, HWND, LPARAM, RECT}, - Graphics::Gdi::{HDC, HMONITOR}, -}; - -use crate::{error_handler::Result, windows_api::WindowsApi}; - -#[derive(Debug, Clone, Default)] -pub struct WindowEnumerator { - handles: Vec, -} - -impl IntoIterator for WindowEnumerator { - type Item = HWND; - type IntoIter = std::vec::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.handles.into_iter() - } -} - -impl WindowEnumerator { - pub fn new_refreshed() -> Result { - let mut enumerator = Self::default(); - enumerator.refresh()?; - Ok(enumerator) - } - - pub fn refresh(&mut self) -> Result<()> { - self.handles.clear(); - - unsafe extern "system" fn get_handles_proc(hwnd: HWND, lparam: LPARAM) -> BOOL { - let data_ptr = lparam.0 as *mut Vec; - if let Some(data) = data_ptr.as_mut() { - data.push(hwnd); - } - true.into() - } - - WindowsApi::enum_windows(Some(get_handles_proc), &mut self.handles as *mut _ as isize) - } - - pub fn iter(&self) -> Iter<'_, HWND> { - self.handles.iter() - } -} - -#[derive(Debug, Clone, Default)] -pub struct MonitorEnumerator { - handles: Vec, -} - -impl IntoIterator for MonitorEnumerator { - type Item = HMONITOR; - type IntoIter = std::vec::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.handles.into_iter() - } -} - -impl MonitorEnumerator { - pub fn new_refreshed() -> Result { - let mut enumerator = Self::default(); - enumerator.refresh()?; - Ok(enumerator) - } - - pub fn refresh(&mut self) -> Result<()> { - self.handles.clear(); - - unsafe extern "system" fn get_handles_proc( - hmonitor: HMONITOR, - _hdc: HDC, - _rect_clip: *mut RECT, - lparam: LPARAM, - ) -> BOOL { - let data_ptr = lparam.0 as *mut Vec; - if let Some(data) = data_ptr.as_mut() { - data.push(hmonitor); - } - true.into() - } - - WindowsApi::enum_display_monitors( - Some(get_handles_proc), - &mut self.handles as *mut _ as isize, - ) - } - - pub fn iter(&self) -> Iter<'_, HMONITOR> { - self.handles.iter() - } -} +use std::slice::Iter; + +use windows::Win32::{ + Foundation::{BOOL, HWND, LPARAM, RECT}, + Graphics::Gdi::{HDC, HMONITOR}, +}; + +use crate::{error_handler::Result, windows_api::WindowsApi}; + +#[derive(Debug, Clone, Default)] +pub struct WindowEnumerator { + handles: Vec, +} + +impl IntoIterator for WindowEnumerator { + type Item = HWND; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.handles.into_iter() + } +} + +impl WindowEnumerator { + pub fn new_refreshed() -> Result { + let mut enumerator = Self::default(); + enumerator.refresh()?; + Ok(enumerator) + } + + pub fn refresh(&mut self) -> Result<()> { + self.handles.clear(); + + unsafe extern "system" fn get_handles_proc(hwnd: HWND, lparam: LPARAM) -> BOOL { + let data_ptr = lparam.0 as *mut Vec; + if let Some(data) = data_ptr.as_mut() { + data.push(hwnd); + } + true.into() + } + + WindowsApi::enum_windows(Some(get_handles_proc), &mut self.handles as *mut _ as isize) + } + + pub fn iter(&self) -> Iter<'_, HWND> { + self.handles.iter() + } +} + +#[derive(Debug, Clone, Default)] +pub struct MonitorEnumerator { + handles: Vec, +} + +impl IntoIterator for MonitorEnumerator { + type Item = HMONITOR; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.handles.into_iter() + } +} + +impl MonitorEnumerator { + pub fn new_refreshed() -> Result { + let mut enumerator = Self::default(); + enumerator.refresh()?; + Ok(enumerator) + } + + pub fn refresh(&mut self) -> Result<()> { + self.handles.clear(); + + unsafe extern "system" fn get_handles_proc( + hmonitor: HMONITOR, + _hdc: HDC, + _rect_clip: *mut RECT, + lparam: LPARAM, + ) -> BOOL { + let data_ptr = lparam.0 as *mut Vec; + if let Some(data) = data_ptr.as_mut() { + data.push(hmonitor); + } + true.into() + } + + WindowsApi::enum_display_monitors( + Some(get_handles_proc), + &mut self.handles as *mut _ as isize, + ) + } + + pub fn iter(&self) -> Iter<'_, HMONITOR> { + self.handles.iter() + } +} diff --git a/src/background/windows_api/mod.rs b/src/background/windows_api/mod.rs index 7c60da16..349c0e31 100644 --- a/src/background/windows_api/mod.rs +++ b/src/background/windows_api/mod.rs @@ -1,692 +1,692 @@ -mod app_bar; -mod com; -mod iterator; - -pub use app_bar::*; -pub use com::*; -pub use iterator::*; -use itertools::Itertools; -use widestring::U16CStr; - -use std::{ffi::c_void, path::PathBuf, thread::sleep, time::Duration}; - -use color_eyre::eyre::eyre; -use windows::{ - core::{GUID, PCWSTR, PWSTR}, - Storage::Streams::{ - DataReader, IRandomAccessStreamReference, IRandomAccessStreamWithContentType, - }, - Win32::{ - Devices::Display::{ - GetNumberOfPhysicalMonitorsFromHMONITOR, GetPhysicalMonitorsFromHMONITOR, - PHYSICAL_MONITOR, - }, - Foundation::{CloseHandle, HANDLE, HMODULE, HWND, LPARAM, LUID, MAX_PATH, RECT}, - Graphics::{ - Dwm::{ - DwmGetWindowAttribute, DWMWA_CLOAKED, DWMWA_EXTENDED_FRAME_BOUNDS, - DWMWINDOWATTRIBUTE, DWM_CLOAKED_APP, DWM_CLOAKED_INHERITED, DWM_CLOAKED_SHELL, - }, - Gdi::{ - EnumDisplayMonitors, GetMonitorInfoW, MonitorFromWindow, HDC, HMONITOR, - MONITORENUMPROC, MONITORINFOEXW, MONITOR_DEFAULTTOPRIMARY, - }, - }, - Security::{ - GetTokenInformation, LookupPrivilegeValueW, TokenElevation, TOKEN_ADJUST_PRIVILEGES, - TOKEN_ELEVATION, TOKEN_QUERY, - }, - Storage::EnhancedStorage::PKEY_FileDescription, - System::{ - LibraryLoader::GetModuleHandleW, - Power::{GetSystemPowerStatus, SetSuspendState, SYSTEM_POWER_STATUS}, - RemoteDesktop::ProcessIdToSessionId, - Shutdown::{ExitWindowsEx, EXIT_WINDOWS_FLAGS, SHUTDOWN_REASON}, - Threading::{ - GetCurrentProcess, GetCurrentProcessId, OpenProcess, OpenProcessToken, - QueryFullProcessImageNameW, PROCESS_ACCESS_RIGHTS, PROCESS_NAME_WIN32, - PROCESS_QUERY_INFORMATION, - }, - }, - UI::{ - HiDpi::{GetDpiForMonitor, MDT_EFFECTIVE_DPI}, - Shell::{ - IShellItem2, IVirtualDesktopManager, SHCreateItemFromParsingName, - VirtualDesktopManager, SIGDN_NORMALDISPLAY, - }, - WindowsAndMessaging::{ - EnumWindows, GetClassNameW, GetDesktopWindow, GetForegroundWindow, GetParent, - GetWindow, GetWindowLongW, GetWindowRect, GetWindowTextW, GetWindowThreadProcessId, - IsIconic, IsWindow, IsWindowVisible, IsZoomed, SetWindowPos, ShowWindow, - ShowWindowAsync, SystemParametersInfoW, ANIMATIONINFO, EVENT_SYSTEM_FOREGROUND, - GWL_EXSTYLE, GWL_STYLE, GW_OWNER, SET_WINDOW_POS_FLAGS, SHOW_WINDOW_CMD, - SPIF_SENDCHANGE, SPIF_UPDATEINIFILE, SPI_GETANIMATION, SPI_GETDESKWALLPAPER, - SPI_SETANIMATION, SPI_SETDESKWALLPAPER, SWP_ASYNCWINDOWPOS, SWP_NOACTIVATE, - SWP_NOMOVE, SWP_NOSIZE, SWP_NOZORDER, SW_MINIMIZE, SW_NORMAL, SW_RESTORE, - SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS, WINDOW_EX_STYLE, WINDOW_STYLE, WNDENUMPROC, - }, - }, - }, -}; - -use crate::{ - error_handler::{AppError, Result}, - hook::HOOK_MANAGER, - log_error, trace_lock, - utils::is_windows_11, - winevent::WinEvent, -}; - -#[macro_export] -macro_rules! pcstr { - ($s:literal) => { - windows::core::s!($s) - }; -} - -#[macro_export] -macro_rules! pcwstr { - ($s:literal) => { - windows::core::w!($s) - }; -} - -#[macro_export] -macro_rules! hstring { - ($s:literal) => { - windows::core::h!($s) - }; -} - -pub struct WindowsApi {} -impl WindowsApi { - pub fn module_handle_w() -> Result { - Ok(unsafe { GetModuleHandleW(None) }?) - } - - pub fn enum_display_monitors( - callback: MONITORENUMPROC, - callback_data_address: isize, - ) -> Result<()> { - unsafe { EnumDisplayMonitors(HDC(0), None, callback, LPARAM(callback_data_address)) } - .ok()?; - Ok(()) - } - - pub fn enum_windows(callback: WNDENUMPROC, callback_data_address: isize) -> Result<()> { - unsafe { EnumWindows(callback, LPARAM(callback_data_address))? }; - Ok(()) - } - - pub fn get_device_pixel_ratio(hmonitor: HMONITOR) -> Result { - let mut dpi_x: u32 = 0; - let mut _dpi_y: u32 = 0; - unsafe { GetDpiForMonitor(hmonitor, MDT_EFFECTIVE_DPI, &mut dpi_x, &mut _dpi_y)? }; - // 96 is the default DPI value on Windows - Ok(dpi_x as f32 / 96_f32) - } - - pub fn window_thread_process_id(hwnd: HWND) -> (u32, u32) { - let mut process_id: u32 = 0; - - // Behaviour is undefined if an invalid HWND is given - // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowthreadprocessid - let thread_id = unsafe { - GetWindowThreadProcessId(hwnd, Option::from(std::ptr::addr_of_mut!(process_id))) - }; - - (process_id, thread_id) - } - - pub fn current_process() -> HANDLE { - unsafe { GetCurrentProcess() } - } - - pub fn current_process_id() -> u32 { - unsafe { GetCurrentProcessId() } - } - - pub fn current_session_id() -> Result { - let process_id = Self::current_process_id(); - let mut session_id = 0; - - unsafe { - if ProcessIdToSessionId(process_id, &mut session_id).is_ok() { - Ok(session_id) - } else { - Err(eyre!("could not determine current session id").into()) - } - } - } - - pub fn get_foreground_window() -> HWND { - unsafe { GetForegroundWindow() } - } - - pub fn is_window(hwnd: HWND) -> bool { - unsafe { IsWindow(hwnd) }.into() - } - - pub fn is_window_visible(hwnd: HWND) -> bool { - unsafe { IsWindowVisible(hwnd) }.into() - } - - pub fn is_iconic(hwnd: HWND) -> bool { - unsafe { IsIconic(hwnd) }.into() - } - - pub fn is_maximized(hwnd: HWND) -> bool { - unsafe { IsZoomed(hwnd) }.into() - } - - pub fn is_fullscreen(hwnd: HWND) -> Result { - let rc_monitor = WindowsApi::monitor_rect(WindowsApi::monitor_from_window(hwnd))?; - let window_rect = WindowsApi::get_window_rect(hwnd); - Ok(window_rect.left <= rc_monitor.left - && window_rect.top <= rc_monitor.top - && window_rect.right >= rc_monitor.right - && window_rect.bottom >= rc_monitor.bottom) - } - - pub fn is_cloaked(hwnd: HWND) -> Result { - let mut cloaked: u32 = 0; - Self::dwm_get_window_attribute(hwnd, DWMWA_CLOAKED, &mut cloaked)?; - Ok(matches!( - cloaked, - DWM_CLOAKED_APP | DWM_CLOAKED_SHELL | DWM_CLOAKED_INHERITED - )) - } - - pub fn show_window(hwnd: HWND, command: SHOW_WINDOW_CMD) -> Result<()> { - // BOOL is returned but does not signify whether or not the operation was succesful - // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow - let result = unsafe { ShowWindow(hwnd, command) }.ok(); - if let Err(error) = result { - if !error.code().is_ok() { - return Err(error.into()); - } - } - Ok(()) - } - - pub fn show_window_async(hwnd: HWND, command: SHOW_WINDOW_CMD) -> Result<()> { - // BOOL is returned but does not signify whether or not the operation was succesful - // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindowasync - let result = unsafe { ShowWindowAsync(hwnd, command) }.ok(); - if let Err(error) = result { - if !error.code().is_ok() { - return Err(error.into()); - } - } - Ok(()) - } - - pub fn unmaximize_window(hwnd: HWND) -> Result<()> { - Self::show_window(hwnd, SW_NORMAL) - } - - pub fn get_styles(hwnd: HWND) -> WINDOW_STYLE { - WINDOW_STYLE(unsafe { GetWindowLongW(hwnd, GWL_STYLE) } as u32) - } - - pub fn get_ex_styles(hwnd: HWND) -> WINDOW_EX_STYLE { - WINDOW_EX_STYLE(unsafe { GetWindowLongW(hwnd, GWL_EXSTYLE) } as u32) - } - - fn _set_position( - hwnd: HWND, - order: HWND, - rect: RECT, - flags: SET_WINDOW_POS_FLAGS, - ) -> Result<()> { - unsafe { - SetWindowPos( - hwnd, - order, - rect.left, - rect.top, - (rect.right - rect.left).abs(), - (rect.bottom - rect.top).abs(), - flags, - )?; - } - Ok(()) - } - - pub fn set_position( - hwnd: HWND, - order: Option, - rect: &RECT, - flags: SET_WINDOW_POS_FLAGS, - ) -> Result<()> { - let uflags = match order { - Some(_) => flags, - None => SWP_NOZORDER | flags, - }; - let order = order.unwrap_or(HWND(0)); - - if uflags.contains(SWP_ASYNCWINDOWPOS) { - let rect = *rect; - std::thread::spawn(move || Self::_set_position(hwnd, order, rect, uflags)); - return Ok(()); - } - - Self::_set_position(hwnd, order, *rect, uflags) - } - - pub fn move_window(hwnd: HWND, rect: &RECT) -> Result<()> { - Self::set_position(hwnd, None, rect, SWP_NOSIZE | SWP_NOACTIVATE) - } - - pub fn bring_to(hwnd: HWND, after: HWND) -> Result<()> { - Self::set_position( - hwnd, - Some(after), - &Default::default(), - SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE, - )?; - Ok(()) - } - - pub fn async_force_set_foreground(hwnd: HWND) { - std::thread::spawn(move || log_error!(Self::force_set_foreground(hwnd))); - } - - pub fn force_set_foreground(hwnd: HWND) -> Result<()> { - Self::set_minimize_animation(false)?; - - let mut hook_manager = trace_lock!(HOOK_MANAGER); - hook_manager.pause_and_resume_after(WinEvent::SystemMinimizeEnd, hwnd); - hook_manager.set_resume_callback(move |hook_manager| { - log_error!(Self::set_minimize_animation(true)); - hook_manager.emit_fake_win_event(EVENT_SYSTEM_FOREGROUND, hwnd); - }); - - Self::show_window_async(hwnd, SW_MINIMIZE)?; - Self::show_window_async(hwnd, SW_RESTORE)?; - Ok(()) - } - - fn open_process( - access_rights: PROCESS_ACCESS_RIGHTS, - inherit_handle: bool, - process_id: u32, - ) -> Result { - unsafe { Ok(OpenProcess(access_rights, inherit_handle, process_id)?) } - } - - pub fn open_process_token() -> Result { - let mut token_handle: HANDLE = HANDLE(0); - unsafe { - OpenProcessToken( - Self::current_process(), - TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, - &mut token_handle, - )?; - } - Ok(token_handle) - } - - pub fn get_luid(system: PCWSTR, name: PCWSTR) -> Result { - let mut luid = LUID::default(); - unsafe { LookupPrivilegeValueW(system, name, &mut luid)? }; - Ok(luid) - } - - fn close_handle(handle: HANDLE) -> Result<()> { - unsafe { - CloseHandle(handle)?; - } - Ok(()) - } - - fn process_handle(process_id: u32) -> Result { - Self::open_process(PROCESS_QUERY_INFORMATION, false, process_id) - } - - pub fn get_parent(hwnd: HWND) -> HWND { - unsafe { GetParent(hwnd) } - } - - pub fn get_owner(hwnd: HWND) -> HWND { - unsafe { GetWindow(hwnd, GW_OWNER) } - } - - pub fn exe_path_by_process(process_id: u32) -> Result { - let mut len = 512_u32; - let mut path: Vec = vec![0; len as usize]; - let text_ptr = path.as_mut_ptr(); - - let handle = Self::process_handle(process_id)?; - unsafe { - QueryFullProcessImageNameW(handle, PROCESS_NAME_WIN32, PWSTR(text_ptr), &mut len)?; - } - Self::close_handle(handle)?; - - Ok(String::from_utf16(&path[..len as usize])?) - } - - pub fn exe_path(hwnd: HWND) -> Result { - let (process_id, _) = Self::window_thread_process_id(hwnd); - Self::exe_path_by_process(process_id) - } - - pub fn exe_path_v2(hwnd: HWND) -> Result { - let (process_id, _) = Self::window_thread_process_id(hwnd); - Ok(PathBuf::from(Self::exe_path_by_process(process_id)?)) - } - - pub fn exe(hwnd: HWND) -> Result { - Ok(Self::exe_path(hwnd)? - .split('\\') - .last() - .ok_or_else(|| eyre!("there is no last element"))? - .to_string()) - } - - pub fn get_class(hwnd: HWND) -> Result { - let mut text: [u16; 512] = [0; 512]; - let len = unsafe { GetClassNameW(hwnd, &mut text) }; - let length = usize::try_from(len).unwrap_or(0); - Ok(String::from_utf16(&text[..length])?) - } - - pub fn get_shell_item(path: &str) -> Result { - let wide_path: Vec = path.encode_utf16().chain(Some(0)).collect(); - let item = unsafe { SHCreateItemFromParsingName(PCWSTR(wide_path.as_ptr()), None)? }; - Ok(item) - } - - pub fn get_window_display_name(hwnd: HWND) -> Result { - let shell_item = Self::get_shell_item(&Self::exe_path(hwnd)?)?; - unsafe { - match shell_item.GetString(&PKEY_FileDescription) { - Ok(description) => Ok(description.to_string()?), - Err(_) => Ok(shell_item - .GetDisplayName(SIGDN_NORMALDISPLAY)? - .to_string()? - .replace(".exe", "")), - } - } - } - - pub fn get_window_text(hwnd: HWND) -> String { - let mut text: [u16; 512] = [0; 512]; - let len = unsafe { GetWindowTextW(hwnd, &mut text) }; - let length = usize::try_from(len).unwrap_or(0); - String::from_utf16(&text[..length]).unwrap_or("".to_owned()) - } - - pub fn dwm_get_window_attribute( - hwnd: HWND, - attribute: DWMWINDOWATTRIBUTE, - value: &mut T, - ) -> Result<()> { - unsafe { - DwmGetWindowAttribute( - hwnd, - attribute, - (value as *mut T).cast(), - u32::try_from(std::mem::size_of::())?, - )?; - } - - Ok(()) - } - - pub fn get_window_rect(hwnd: HWND) -> RECT { - let mut rect = unsafe { std::mem::zeroed() }; - unsafe { GetWindowRect(hwnd, &mut rect).ok() }; - rect - } - - // some windows like explorer.exe have a shadow margin - pub fn get_window_rect_without_margins(hwnd: HWND) -> RECT { - let mut rect = unsafe { std::mem::zeroed() }; - if Self::dwm_get_window_attribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &mut rect).is_ok() { - rect - } else { - unsafe { GetWindowRect(hwnd, &mut rect).ok() }; - rect - } - } - - pub fn desktop_window() -> HWND { - unsafe { GetDesktopWindow() } - } - - pub fn monitor_from_window(hwnd: HWND) -> HMONITOR { - unsafe { MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY) } - } - - pub fn primary_monitor() -> HMONITOR { - unsafe { MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTOPRIMARY) } - } - - /// handle of PHYSICAL_MONITOR is bugged and will be always 0 - pub fn primary_physical_monitor() -> Result { - let hmonitor = Self::primary_monitor(); - - let mut c_physical_monitors: u32 = 0; - let mut p_physical_monitors: Vec = Vec::new(); - - unsafe { - GetNumberOfPhysicalMonitorsFromHMONITOR(hmonitor, &mut c_physical_monitors)?; - p_physical_monitors.resize(c_physical_monitors as usize, std::mem::zeroed()); - GetPhysicalMonitorsFromHMONITOR(hmonitor, p_physical_monitors.as_mut())?; - }; - - Ok(p_physical_monitors[0]) - } - - pub fn monitor_name(hmonitor: HMONITOR) -> Result { - let ex_info = Self::monitor_info(hmonitor)?; - Ok(U16CStr::from_slice_truncate(&ex_info.szDevice) - .map_err(|_| AppError::Seelen("monitor name was not a valid u16 c string".to_owned()))? - .to_ustring() - .to_string_lossy() - .trim_start_matches(r"\\.\") - .to_string()) - } - - pub fn monitor_info(hmonitor: HMONITOR) -> Result { - let mut ex_info = MONITORINFOEXW::default(); - ex_info.monitorInfo.cbSize = u32::try_from(std::mem::size_of::())?; - unsafe { GetMonitorInfoW(hmonitor, &mut ex_info.monitorInfo).ok() }?; - Ok(ex_info) - } - - pub fn monitor_rect(hmonitor: HMONITOR) -> Result { - Ok(Self::monitor_info(hmonitor)?.monitorInfo.rcMonitor) - } - - pub fn shadow_rect(hwnd: HWND) -> Result { - let window_rect = Self::get_window_rect_without_margins(hwnd); - - let mut shadow_rect = Default::default(); - unsafe { GetWindowRect(hwnd, &mut shadow_rect)? }; - - Ok(RECT { - left: shadow_rect.left - window_rect.left, - top: shadow_rect.top - window_rect.top, - right: shadow_rect.right - window_rect.right, - bottom: shadow_rect.bottom - window_rect.bottom, - }) - } - - pub fn _get_virtual_desktop_manager() -> Result { - Com::create_instance(&VirtualDesktopManager) - } - - pub fn _get_virtual_desktop_id(hwnd: HWND) -> Result { - let manager = Self::_get_virtual_desktop_manager()?; - let mut desktop_id = GUID::zeroed(); - let mut attempt = 0; - while desktop_id.to_u128() == 0 && attempt < 10 { - attempt += 1; - sleep(Duration::from_millis(30)); - if let Ok(desktop) = unsafe { manager.GetWindowDesktopId(hwnd) } { - desktop_id = desktop - } - } - if desktop_id.to_u128() == 0 { - return Err(eyre!("Failed to get desktop id for: {hwnd:?}").into()); - } - Ok(desktop_id) - } - - pub fn get_wallpaper() -> Result { - let mut path = [0_u16; MAX_PATH as usize]; - unsafe { - SystemParametersInfoW( - SPI_GETDESKWALLPAPER, - MAX_PATH, - Some(path.as_mut_ptr() as _), - SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS(0), - )?; - } - Ok(PathBuf::from( - U16CStr::from_slice_truncate(&path)? - .to_ustring() - .to_string_lossy(), - )) - } - - pub fn set_wallpaper(path: String) -> Result<()> { - if !PathBuf::from(&path).exists() { - return Err("File not found".into()); - } - - if is_windows_11() { - for v_desktop in winvd::get_desktops()? { - v_desktop.set_wallpaper(&path)?; - } - } - - let mut path = path.encode_utf16().chain(Some(0)).collect_vec(); - unsafe { - SystemParametersInfoW( - SPI_SETDESKWALLPAPER, - MAX_PATH, - Some(path.as_mut_ptr() as _), - SPIF_SENDCHANGE | SPIF_UPDATEINIFILE, - )?; - } - Ok(()) - } - - pub fn get_min_animation_info() -> Result { - let mut anim_info: ANIMATIONINFO = unsafe { core::mem::zeroed() }; - anim_info.cbSize = core::mem::size_of::() as u32; - let uiparam = anim_info.cbSize; - unsafe { - SystemParametersInfoW( - SPI_GETANIMATION, - uiparam, - Some(&mut anim_info as *mut ANIMATIONINFO as *mut c_void), - SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS(0), - )?; - } - Ok(anim_info) - } - - pub fn set_minimize_animation(enable: bool) -> Result<()> { - let mut anim_info = Self::get_min_animation_info()?; - let uiparam = anim_info.cbSize; - unsafe { - anim_info.iMinAnimate = enable.into(); - SystemParametersInfoW( - SPI_SETANIMATION, - uiparam, - Some(&mut anim_info as *mut ANIMATIONINFO as *mut c_void), - SPIF_SENDCHANGE, - )?; - } - Ok(()) - } - - pub fn exit_windows(flags: EXIT_WINDOWS_FLAGS, reason: SHUTDOWN_REASON) -> Result<()> { - unsafe { ExitWindowsEx(flags, reason) }?; - Ok(()) - } - - pub fn set_suspend_state() -> Result<()> { - let success = unsafe { SetSuspendState(false, true, false).as_bool() }; - if !success { - return Err(eyre!("Failed to set suspend state").into()); - } - Ok(()) - } - - pub fn is_elevated() -> Result { - unsafe { - let mut elevation = TOKEN_ELEVATION::default(); - let mut ret_len = 0; - - let token_handle = Self::open_process_token()?; - - GetTokenInformation( - token_handle, - TokenElevation, - Some(&mut elevation as *mut _ as *mut _), - std::mem::size_of::() as u32, - &mut ret_len, - )?; - - CloseHandle(token_handle)?; - - Ok(elevation.TokenIsElevated != 0) - } - } - - pub fn get_system_power_status() -> Result { - let mut power_status = SYSTEM_POWER_STATUS::default(); - unsafe { - GetSystemPowerStatus(&mut power_status as _)?; - } - Ok(power_status) - } - - pub fn extract_thumbnail_from_stream( - stream: IRandomAccessStreamWithContentType, - ) -> Result { - let size = stream.Size()?; - let mut buffer = vec![0u8; size as usize]; - - let input_stream = stream.GetInputStreamAt(0)?; - let data_reader = DataReader::CreateDataReader(&input_stream)?; - - data_reader.LoadAsync(size as u32)?.get()?; - data_reader.ReadBytes(&mut buffer)?; - - let image = image::load_from_memory_with_format(&buffer, image::ImageFormat::Png)?; - let image_path = std::env::temp_dir().join(format!("{}.png", uuid::Uuid::new_v4())); - image.save(&image_path)?; - - Ok(image_path) - } - - pub fn extract_thumbnail_from_ref(stream: IRandomAccessStreamReference) -> Result { - Self::extract_thumbnail_from_stream(stream.OpenReadAsync()?.get()?) - } -} - -/* -may be this is useful later - -static CHILD_FROM_FRAME: AtomicIsize = AtoumicIsize::new(0); -unsafe extern "system" fn enum_childs_uwp(hwnd: HWND, _: LPARAM) -> BOOL { - let exe = WindowsApi::exe(hwnd).unwrap_or_default(); - println!("enum_childs_uwp {} {}", hwnd.0, exe); - if exe != "ApplicationFrameHost.exe" { - CHILD_FROM_FRAME.store(hwnd.0, Ordering::SeqCst); - return false.into(); - } - true.into() -} - -pub fn get_child_from_frame_host(hwnd: HWND) -> HWND { - CHILD_FROM_FRAME.store(0, Ordering::SeqCst); - unsafe { EnumChildWindows(hwnd, Some(enum_childs_uwp), LPARAM(0)) }; - HWND(CHILD_FROM_FRAME.load(Ordering::SeqCst)) -} */ +mod app_bar; +mod com; +mod iterator; + +pub use app_bar::*; +pub use com::*; +pub use iterator::*; +use itertools::Itertools; +use widestring::U16CStr; + +use std::{ffi::c_void, path::PathBuf, thread::sleep, time::Duration}; + +use color_eyre::eyre::eyre; +use windows::{ + core::{GUID, PCWSTR, PWSTR}, + Storage::Streams::{ + DataReader, IRandomAccessStreamReference, IRandomAccessStreamWithContentType, + }, + Win32::{ + Devices::Display::{ + GetNumberOfPhysicalMonitorsFromHMONITOR, GetPhysicalMonitorsFromHMONITOR, + PHYSICAL_MONITOR, + }, + Foundation::{CloseHandle, HANDLE, HMODULE, HWND, LPARAM, LUID, MAX_PATH, RECT}, + Graphics::{ + Dwm::{ + DwmGetWindowAttribute, DWMWA_CLOAKED, DWMWA_EXTENDED_FRAME_BOUNDS, + DWMWINDOWATTRIBUTE, DWM_CLOAKED_APP, DWM_CLOAKED_INHERITED, DWM_CLOAKED_SHELL, + }, + Gdi::{ + EnumDisplayMonitors, GetMonitorInfoW, MonitorFromWindow, HDC, HMONITOR, + MONITORENUMPROC, MONITORINFOEXW, MONITOR_DEFAULTTOPRIMARY, + }, + }, + Security::{ + GetTokenInformation, LookupPrivilegeValueW, TokenElevation, TOKEN_ADJUST_PRIVILEGES, + TOKEN_ELEVATION, TOKEN_QUERY, + }, + Storage::EnhancedStorage::PKEY_FileDescription, + System::{ + LibraryLoader::GetModuleHandleW, + Power::{GetSystemPowerStatus, SetSuspendState, SYSTEM_POWER_STATUS}, + RemoteDesktop::ProcessIdToSessionId, + Shutdown::{ExitWindowsEx, EXIT_WINDOWS_FLAGS, SHUTDOWN_REASON}, + Threading::{ + GetCurrentProcess, GetCurrentProcessId, OpenProcess, OpenProcessToken, + QueryFullProcessImageNameW, PROCESS_ACCESS_RIGHTS, PROCESS_NAME_WIN32, + PROCESS_QUERY_INFORMATION, + }, + }, + UI::{ + HiDpi::{GetDpiForMonitor, MDT_EFFECTIVE_DPI}, + Shell::{ + IShellItem2, IVirtualDesktopManager, SHCreateItemFromParsingName, + VirtualDesktopManager, SIGDN_NORMALDISPLAY, + }, + WindowsAndMessaging::{ + EnumWindows, GetClassNameW, GetDesktopWindow, GetForegroundWindow, GetParent, + GetWindow, GetWindowLongW, GetWindowRect, GetWindowTextW, GetWindowThreadProcessId, + IsIconic, IsWindow, IsWindowVisible, IsZoomed, SetWindowPos, ShowWindow, + ShowWindowAsync, SystemParametersInfoW, ANIMATIONINFO, EVENT_SYSTEM_FOREGROUND, + GWL_EXSTYLE, GWL_STYLE, GW_OWNER, SET_WINDOW_POS_FLAGS, SHOW_WINDOW_CMD, + SPIF_SENDCHANGE, SPIF_UPDATEINIFILE, SPI_GETANIMATION, SPI_GETDESKWALLPAPER, + SPI_SETANIMATION, SPI_SETDESKWALLPAPER, SWP_ASYNCWINDOWPOS, SWP_NOACTIVATE, + SWP_NOMOVE, SWP_NOSIZE, SWP_NOZORDER, SW_MINIMIZE, SW_NORMAL, SW_RESTORE, + SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS, WINDOW_EX_STYLE, WINDOW_STYLE, WNDENUMPROC, + }, + }, + }, +}; + +use crate::{ + error_handler::{AppError, Result}, + hook::HOOK_MANAGER, + log_error, trace_lock, + utils::is_windows_11, + winevent::WinEvent, +}; + +#[macro_export] +macro_rules! pcstr { + ($s:literal) => { + windows::core::s!($s) + }; +} + +#[macro_export] +macro_rules! pcwstr { + ($s:literal) => { + windows::core::w!($s) + }; +} + +#[macro_export] +macro_rules! hstring { + ($s:literal) => { + windows::core::h!($s) + }; +} + +pub struct WindowsApi {} +impl WindowsApi { + pub fn module_handle_w() -> Result { + Ok(unsafe { GetModuleHandleW(None) }?) + } + + pub fn enum_display_monitors( + callback: MONITORENUMPROC, + callback_data_address: isize, + ) -> Result<()> { + unsafe { EnumDisplayMonitors(HDC(0), None, callback, LPARAM(callback_data_address)) } + .ok()?; + Ok(()) + } + + pub fn enum_windows(callback: WNDENUMPROC, callback_data_address: isize) -> Result<()> { + unsafe { EnumWindows(callback, LPARAM(callback_data_address))? }; + Ok(()) + } + + pub fn get_device_pixel_ratio(hmonitor: HMONITOR) -> Result { + let mut dpi_x: u32 = 0; + let mut _dpi_y: u32 = 0; + unsafe { GetDpiForMonitor(hmonitor, MDT_EFFECTIVE_DPI, &mut dpi_x, &mut _dpi_y)? }; + // 96 is the default DPI value on Windows + Ok(dpi_x as f32 / 96_f32) + } + + pub fn window_thread_process_id(hwnd: HWND) -> (u32, u32) { + let mut process_id: u32 = 0; + + // Behaviour is undefined if an invalid HWND is given + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowthreadprocessid + let thread_id = unsafe { + GetWindowThreadProcessId(hwnd, Option::from(std::ptr::addr_of_mut!(process_id))) + }; + + (process_id, thread_id) + } + + pub fn current_process() -> HANDLE { + unsafe { GetCurrentProcess() } + } + + pub fn current_process_id() -> u32 { + unsafe { GetCurrentProcessId() } + } + + pub fn current_session_id() -> Result { + let process_id = Self::current_process_id(); + let mut session_id = 0; + + unsafe { + if ProcessIdToSessionId(process_id, &mut session_id).is_ok() { + Ok(session_id) + } else { + Err(eyre!("could not determine current session id").into()) + } + } + } + + pub fn get_foreground_window() -> HWND { + unsafe { GetForegroundWindow() } + } + + pub fn is_window(hwnd: HWND) -> bool { + unsafe { IsWindow(hwnd) }.into() + } + + pub fn is_window_visible(hwnd: HWND) -> bool { + unsafe { IsWindowVisible(hwnd) }.into() + } + + pub fn is_iconic(hwnd: HWND) -> bool { + unsafe { IsIconic(hwnd) }.into() + } + + pub fn is_maximized(hwnd: HWND) -> bool { + unsafe { IsZoomed(hwnd) }.into() + } + + pub fn is_fullscreen(hwnd: HWND) -> Result { + let rc_monitor = WindowsApi::monitor_rect(WindowsApi::monitor_from_window(hwnd))?; + let window_rect = WindowsApi::get_window_rect(hwnd); + Ok(window_rect.left <= rc_monitor.left + && window_rect.top <= rc_monitor.top + && window_rect.right >= rc_monitor.right + && window_rect.bottom >= rc_monitor.bottom) + } + + pub fn is_cloaked(hwnd: HWND) -> Result { + let mut cloaked: u32 = 0; + Self::dwm_get_window_attribute(hwnd, DWMWA_CLOAKED, &mut cloaked)?; + Ok(matches!( + cloaked, + DWM_CLOAKED_APP | DWM_CLOAKED_SHELL | DWM_CLOAKED_INHERITED + )) + } + + pub fn show_window(hwnd: HWND, command: SHOW_WINDOW_CMD) -> Result<()> { + // BOOL is returned but does not signify whether or not the operation was succesful + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow + let result = unsafe { ShowWindow(hwnd, command) }.ok(); + if let Err(error) = result { + if !error.code().is_ok() { + return Err(error.into()); + } + } + Ok(()) + } + + pub fn show_window_async(hwnd: HWND, command: SHOW_WINDOW_CMD) -> Result<()> { + // BOOL is returned but does not signify whether or not the operation was succesful + // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindowasync + let result = unsafe { ShowWindowAsync(hwnd, command) }.ok(); + if let Err(error) = result { + if !error.code().is_ok() { + return Err(error.into()); + } + } + Ok(()) + } + + pub fn unmaximize_window(hwnd: HWND) -> Result<()> { + Self::show_window(hwnd, SW_NORMAL) + } + + pub fn get_styles(hwnd: HWND) -> WINDOW_STYLE { + WINDOW_STYLE(unsafe { GetWindowLongW(hwnd, GWL_STYLE) } as u32) + } + + pub fn get_ex_styles(hwnd: HWND) -> WINDOW_EX_STYLE { + WINDOW_EX_STYLE(unsafe { GetWindowLongW(hwnd, GWL_EXSTYLE) } as u32) + } + + fn _set_position( + hwnd: HWND, + order: HWND, + rect: RECT, + flags: SET_WINDOW_POS_FLAGS, + ) -> Result<()> { + unsafe { + SetWindowPos( + hwnd, + order, + rect.left, + rect.top, + (rect.right - rect.left).abs(), + (rect.bottom - rect.top).abs(), + flags, + )?; + } + Ok(()) + } + + pub fn set_position( + hwnd: HWND, + order: Option, + rect: &RECT, + flags: SET_WINDOW_POS_FLAGS, + ) -> Result<()> { + let uflags = match order { + Some(_) => flags, + None => SWP_NOZORDER | flags, + }; + let order = order.unwrap_or(HWND(0)); + + if uflags.contains(SWP_ASYNCWINDOWPOS) { + let rect = *rect; + std::thread::spawn(move || Self::_set_position(hwnd, order, rect, uflags)); + return Ok(()); + } + + Self::_set_position(hwnd, order, *rect, uflags) + } + + pub fn move_window(hwnd: HWND, rect: &RECT) -> Result<()> { + Self::set_position(hwnd, None, rect, SWP_NOSIZE | SWP_NOACTIVATE) + } + + pub fn bring_to(hwnd: HWND, after: HWND) -> Result<()> { + Self::set_position( + hwnd, + Some(after), + &Default::default(), + SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE, + )?; + Ok(()) + } + + pub fn async_force_set_foreground(hwnd: HWND) { + std::thread::spawn(move || log_error!(Self::force_set_foreground(hwnd))); + } + + pub fn force_set_foreground(hwnd: HWND) -> Result<()> { + Self::set_minimize_animation(false)?; + + let mut hook_manager = trace_lock!(HOOK_MANAGER); + hook_manager.pause_and_resume_after(WinEvent::SystemMinimizeEnd, hwnd); + hook_manager.set_resume_callback(move |hook_manager| { + log_error!(Self::set_minimize_animation(true)); + hook_manager.emit_fake_win_event(EVENT_SYSTEM_FOREGROUND, hwnd); + }); + + Self::show_window_async(hwnd, SW_MINIMIZE)?; + Self::show_window_async(hwnd, SW_RESTORE)?; + Ok(()) + } + + fn open_process( + access_rights: PROCESS_ACCESS_RIGHTS, + inherit_handle: bool, + process_id: u32, + ) -> Result { + unsafe { Ok(OpenProcess(access_rights, inherit_handle, process_id)?) } + } + + pub fn open_process_token() -> Result { + let mut token_handle: HANDLE = HANDLE(0); + unsafe { + OpenProcessToken( + Self::current_process(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, + &mut token_handle, + )?; + } + Ok(token_handle) + } + + pub fn get_luid(system: PCWSTR, name: PCWSTR) -> Result { + let mut luid = LUID::default(); + unsafe { LookupPrivilegeValueW(system, name, &mut luid)? }; + Ok(luid) + } + + fn close_handle(handle: HANDLE) -> Result<()> { + unsafe { + CloseHandle(handle)?; + } + Ok(()) + } + + fn process_handle(process_id: u32) -> Result { + Self::open_process(PROCESS_QUERY_INFORMATION, false, process_id) + } + + pub fn get_parent(hwnd: HWND) -> HWND { + unsafe { GetParent(hwnd) } + } + + pub fn get_owner(hwnd: HWND) -> HWND { + unsafe { GetWindow(hwnd, GW_OWNER) } + } + + pub fn exe_path_by_process(process_id: u32) -> Result { + let mut len = 512_u32; + let mut path: Vec = vec![0; len as usize]; + let text_ptr = path.as_mut_ptr(); + + let handle = Self::process_handle(process_id)?; + unsafe { + QueryFullProcessImageNameW(handle, PROCESS_NAME_WIN32, PWSTR(text_ptr), &mut len)?; + } + Self::close_handle(handle)?; + + Ok(String::from_utf16(&path[..len as usize])?) + } + + pub fn exe_path(hwnd: HWND) -> Result { + let (process_id, _) = Self::window_thread_process_id(hwnd); + Self::exe_path_by_process(process_id) + } + + pub fn exe_path_v2(hwnd: HWND) -> Result { + let (process_id, _) = Self::window_thread_process_id(hwnd); + Ok(PathBuf::from(Self::exe_path_by_process(process_id)?)) + } + + pub fn exe(hwnd: HWND) -> Result { + Ok(Self::exe_path(hwnd)? + .split('\\') + .last() + .ok_or_else(|| eyre!("there is no last element"))? + .to_string()) + } + + pub fn get_class(hwnd: HWND) -> Result { + let mut text: [u16; 512] = [0; 512]; + let len = unsafe { GetClassNameW(hwnd, &mut text) }; + let length = usize::try_from(len).unwrap_or(0); + Ok(String::from_utf16(&text[..length])?) + } + + pub fn get_shell_item(path: &str) -> Result { + let wide_path: Vec = path.encode_utf16().chain(Some(0)).collect(); + let item = unsafe { SHCreateItemFromParsingName(PCWSTR(wide_path.as_ptr()), None)? }; + Ok(item) + } + + pub fn get_window_display_name(hwnd: HWND) -> Result { + let shell_item = Self::get_shell_item(&Self::exe_path(hwnd)?)?; + unsafe { + match shell_item.GetString(&PKEY_FileDescription) { + Ok(description) => Ok(description.to_string()?), + Err(_) => Ok(shell_item + .GetDisplayName(SIGDN_NORMALDISPLAY)? + .to_string()? + .replace(".exe", "")), + } + } + } + + pub fn get_window_text(hwnd: HWND) -> String { + let mut text: [u16; 512] = [0; 512]; + let len = unsafe { GetWindowTextW(hwnd, &mut text) }; + let length = usize::try_from(len).unwrap_or(0); + String::from_utf16(&text[..length]).unwrap_or("".to_owned()) + } + + pub fn dwm_get_window_attribute( + hwnd: HWND, + attribute: DWMWINDOWATTRIBUTE, + value: &mut T, + ) -> Result<()> { + unsafe { + DwmGetWindowAttribute( + hwnd, + attribute, + (value as *mut T).cast(), + u32::try_from(std::mem::size_of::())?, + )?; + } + + Ok(()) + } + + pub fn get_window_rect(hwnd: HWND) -> RECT { + let mut rect = unsafe { std::mem::zeroed() }; + unsafe { GetWindowRect(hwnd, &mut rect).ok() }; + rect + } + + // some windows like explorer.exe have a shadow margin + pub fn get_window_rect_without_margins(hwnd: HWND) -> RECT { + let mut rect = unsafe { std::mem::zeroed() }; + if Self::dwm_get_window_attribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &mut rect).is_ok() { + rect + } else { + unsafe { GetWindowRect(hwnd, &mut rect).ok() }; + rect + } + } + + pub fn desktop_window() -> HWND { + unsafe { GetDesktopWindow() } + } + + pub fn monitor_from_window(hwnd: HWND) -> HMONITOR { + unsafe { MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY) } + } + + pub fn primary_monitor() -> HMONITOR { + unsafe { MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTOPRIMARY) } + } + + /// handle of PHYSICAL_MONITOR is bugged and will be always 0 + pub fn primary_physical_monitor() -> Result { + let hmonitor = Self::primary_monitor(); + + let mut c_physical_monitors: u32 = 0; + let mut p_physical_monitors: Vec = Vec::new(); + + unsafe { + GetNumberOfPhysicalMonitorsFromHMONITOR(hmonitor, &mut c_physical_monitors)?; + p_physical_monitors.resize(c_physical_monitors as usize, std::mem::zeroed()); + GetPhysicalMonitorsFromHMONITOR(hmonitor, p_physical_monitors.as_mut())?; + }; + + Ok(p_physical_monitors[0]) + } + + pub fn monitor_name(hmonitor: HMONITOR) -> Result { + let ex_info = Self::monitor_info(hmonitor)?; + Ok(U16CStr::from_slice_truncate(&ex_info.szDevice) + .map_err(|_| AppError::Seelen("monitor name was not a valid u16 c string".to_owned()))? + .to_ustring() + .to_string_lossy() + .trim_start_matches(r"\\.\") + .to_string()) + } + + pub fn monitor_info(hmonitor: HMONITOR) -> Result { + let mut ex_info = MONITORINFOEXW::default(); + ex_info.monitorInfo.cbSize = u32::try_from(std::mem::size_of::())?; + unsafe { GetMonitorInfoW(hmonitor, &mut ex_info.monitorInfo).ok() }?; + Ok(ex_info) + } + + pub fn monitor_rect(hmonitor: HMONITOR) -> Result { + Ok(Self::monitor_info(hmonitor)?.monitorInfo.rcMonitor) + } + + pub fn shadow_rect(hwnd: HWND) -> Result { + let window_rect = Self::get_window_rect_without_margins(hwnd); + + let mut shadow_rect = Default::default(); + unsafe { GetWindowRect(hwnd, &mut shadow_rect)? }; + + Ok(RECT { + left: shadow_rect.left - window_rect.left, + top: shadow_rect.top - window_rect.top, + right: shadow_rect.right - window_rect.right, + bottom: shadow_rect.bottom - window_rect.bottom, + }) + } + + pub fn _get_virtual_desktop_manager() -> Result { + Com::create_instance(&VirtualDesktopManager) + } + + pub fn _get_virtual_desktop_id(hwnd: HWND) -> Result { + let manager = Self::_get_virtual_desktop_manager()?; + let mut desktop_id = GUID::zeroed(); + let mut attempt = 0; + while desktop_id.to_u128() == 0 && attempt < 10 { + attempt += 1; + sleep(Duration::from_millis(30)); + if let Ok(desktop) = unsafe { manager.GetWindowDesktopId(hwnd) } { + desktop_id = desktop + } + } + if desktop_id.to_u128() == 0 { + return Err(eyre!("Failed to get desktop id for: {hwnd:?}").into()); + } + Ok(desktop_id) + } + + pub fn get_wallpaper() -> Result { + let mut path = [0_u16; MAX_PATH as usize]; + unsafe { + SystemParametersInfoW( + SPI_GETDESKWALLPAPER, + MAX_PATH, + Some(path.as_mut_ptr() as _), + SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS(0), + )?; + } + Ok(PathBuf::from( + U16CStr::from_slice_truncate(&path)? + .to_ustring() + .to_string_lossy(), + )) + } + + pub fn set_wallpaper(path: String) -> Result<()> { + if !PathBuf::from(&path).exists() { + return Err("File not found".into()); + } + + if is_windows_11() { + for v_desktop in winvd::get_desktops()? { + v_desktop.set_wallpaper(&path)?; + } + } + + let mut path = path.encode_utf16().chain(Some(0)).collect_vec(); + unsafe { + SystemParametersInfoW( + SPI_SETDESKWALLPAPER, + MAX_PATH, + Some(path.as_mut_ptr() as _), + SPIF_SENDCHANGE | SPIF_UPDATEINIFILE, + )?; + } + Ok(()) + } + + pub fn get_min_animation_info() -> Result { + let mut anim_info: ANIMATIONINFO = unsafe { core::mem::zeroed() }; + anim_info.cbSize = core::mem::size_of::() as u32; + let uiparam = anim_info.cbSize; + unsafe { + SystemParametersInfoW( + SPI_GETANIMATION, + uiparam, + Some(&mut anim_info as *mut ANIMATIONINFO as *mut c_void), + SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS(0), + )?; + } + Ok(anim_info) + } + + pub fn set_minimize_animation(enable: bool) -> Result<()> { + let mut anim_info = Self::get_min_animation_info()?; + let uiparam = anim_info.cbSize; + unsafe { + anim_info.iMinAnimate = enable.into(); + SystemParametersInfoW( + SPI_SETANIMATION, + uiparam, + Some(&mut anim_info as *mut ANIMATIONINFO as *mut c_void), + SPIF_SENDCHANGE, + )?; + } + Ok(()) + } + + pub fn exit_windows(flags: EXIT_WINDOWS_FLAGS, reason: SHUTDOWN_REASON) -> Result<()> { + unsafe { ExitWindowsEx(flags, reason) }?; + Ok(()) + } + + pub fn set_suspend_state() -> Result<()> { + let success = unsafe { SetSuspendState(false, true, false).as_bool() }; + if !success { + return Err(eyre!("Failed to set suspend state").into()); + } + Ok(()) + } + + pub fn is_elevated() -> Result { + unsafe { + let mut elevation = TOKEN_ELEVATION::default(); + let mut ret_len = 0; + + let token_handle = Self::open_process_token()?; + + GetTokenInformation( + token_handle, + TokenElevation, + Some(&mut elevation as *mut _ as *mut _), + std::mem::size_of::() as u32, + &mut ret_len, + )?; + + CloseHandle(token_handle)?; + + Ok(elevation.TokenIsElevated != 0) + } + } + + pub fn get_system_power_status() -> Result { + let mut power_status = SYSTEM_POWER_STATUS::default(); + unsafe { + GetSystemPowerStatus(&mut power_status as _)?; + } + Ok(power_status) + } + + pub fn extract_thumbnail_from_stream( + stream: IRandomAccessStreamWithContentType, + ) -> Result { + let size = stream.Size()?; + let mut buffer = vec![0u8; size as usize]; + + let input_stream = stream.GetInputStreamAt(0)?; + let data_reader = DataReader::CreateDataReader(&input_stream)?; + + data_reader.LoadAsync(size as u32)?.get()?; + data_reader.ReadBytes(&mut buffer)?; + + let image = image::load_from_memory_with_format(&buffer, image::ImageFormat::Png)?; + let image_path = std::env::temp_dir().join(format!("{}.png", uuid::Uuid::new_v4())); + image.save(&image_path)?; + + Ok(image_path) + } + + pub fn extract_thumbnail_from_ref(stream: IRandomAccessStreamReference) -> Result { + Self::extract_thumbnail_from_stream(stream.OpenReadAsync()?.get()?) + } +} + +/* +may be this is useful later + +static CHILD_FROM_FRAME: AtomicIsize = AtoumicIsize::new(0); +unsafe extern "system" fn enum_childs_uwp(hwnd: HWND, _: LPARAM) -> BOOL { + let exe = WindowsApi::exe(hwnd).unwrap_or_default(); + println!("enum_childs_uwp {} {}", hwnd.0, exe); + if exe != "ApplicationFrameHost.exe" { + CHILD_FROM_FRAME.store(hwnd.0, Ordering::SeqCst); + return false.into(); + } + true.into() +} + +pub fn get_child_from_frame_host(hwnd: HWND) -> HWND { + CHILD_FROM_FRAME.store(0, Ordering::SeqCst); + unsafe { EnumChildWindows(hwnd, Some(enum_childs_uwp), LPARAM(0)) }; + HWND(CHILD_FROM_FRAME.load(Ordering::SeqCst)) +} */ diff --git a/src/background/winevent.rs b/src/background/winevent.rs index 29446b78..2c42cabc 100644 --- a/src/background/winevent.rs +++ b/src/background/winevent.rs @@ -1,371 +1,371 @@ -#![allow(clippy::use_self)] - -use lazy_static::lazy_static; -use parking_lot::Mutex; - -use windows::Win32::Foundation::HWND; -use windows::Win32::Graphics::Gdi::HMONITOR; -use windows::Win32::UI::WindowsAndMessaging::EVENT_AIA_END; -use windows::Win32::UI::WindowsAndMessaging::EVENT_AIA_START; -use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_CARET; -use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_END; -use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_END_APPLICATION; -use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_LAYOUT; -use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_START_APPLICATION; -use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_UPDATE_REGION; -use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_UPDATE_SCROLL; -use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_UPDATE_SIMPLE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_ACCELERATORCHANGE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_CLOAKED; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_CONTENTSCROLLED; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_CREATE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DEFACTIONCHANGE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DESCRIPTIONCHANGE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DESTROY; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DRAGCANCEL; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DRAGCOMPLETE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DRAGDROPPED; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DRAGENTER; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DRAGLEAVE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DRAGSTART; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_END; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_FOCUS; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_HELPCHANGE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_HIDE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_HOSTEDOBJECTSINVALIDATED; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_IME_CHANGE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_IME_HIDE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_IME_SHOW; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_INVOKED; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_LIVEREGIONCHANGED; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_LOCATIONCHANGE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_NAMECHANGE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_PARENTCHANGE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_REORDER; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_SELECTION; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_SELECTIONADD; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_SELECTIONREMOVE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_SELECTIONWITHIN; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_SHOW; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_STATECHANGE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_TEXTEDIT_CONVERSIONTARGETCHANGED; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_TEXTSELECTIONCHANGED; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_UNCLOAKED; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_VALUECHANGE; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OEM_DEFINED_END; -use windows::Win32::UI::WindowsAndMessaging::EVENT_OEM_DEFINED_START; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_ALERT; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_ARRANGMENTPREVIEW; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_CAPTUREEND; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_CAPTURESTART; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_CONTEXTHELPEND; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_CONTEXTHELPSTART; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_DESKTOPSWITCH; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_DIALOGEND; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_DIALOGSTART; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_DRAGDROPEND; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_DRAGDROPSTART; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_END; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_FOREGROUND; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_IME_KEY_NOTIFICATION; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MENUEND; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MENUPOPUPEND; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MENUPOPUPSTART; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MENUSTART; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MINIMIZEEND; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MINIMIZESTART; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MOVESIZEEND; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MOVESIZESTART; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_SCROLLINGEND; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_SCROLLINGSTART; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_SOUND; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_SWITCHER_APPGRABBED; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_SWITCHER_APPOVERTARGET; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_SWITCHER_CANCELLED; -use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_SWITCHSTART; -use windows::Win32::UI::WindowsAndMessaging::EVENT_UIA_EVENTID_END; -use windows::Win32::UI::WindowsAndMessaging::EVENT_UIA_EVENTID_START; -use windows::Win32::UI::WindowsAndMessaging::EVENT_UIA_PROPID_END; -use windows::Win32::UI::WindowsAndMessaging::EVENT_UIA_PROPID_START; -use windows::Win32::UI::WindowsAndMessaging::{ - EVENT_SYSTEM_SWITCHEND, EVENT_SYSTEM_SWITCHER_APPDROPPED, -}; - -use crate::trace_lock; -use crate::utils::constants::IGNORE_FULLSCREEN; -use crate::windows_api::WindowsApi; - -lazy_static! { - static ref FULLSCREENED: Mutex> = Mutex::new(Vec::new()); -} - -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -#[repr(u32)] -#[allow(dead_code)] -pub enum WinEvent { - AiaEnd = EVENT_AIA_END, - AiaStart = EVENT_AIA_START, - ConsoleCaret = EVENT_CONSOLE_CARET, - ConsoleEnd = EVENT_CONSOLE_END, - ConsoleEndApplication = EVENT_CONSOLE_END_APPLICATION, - ConsoleLayout = EVENT_CONSOLE_LAYOUT, - ConsoleStartApplication = EVENT_CONSOLE_START_APPLICATION, - ConsoleUpdateRegion = EVENT_CONSOLE_UPDATE_REGION, - ConsoleUpdateScroll = EVENT_CONSOLE_UPDATE_SCROLL, - ConsoleUpdateSimple = EVENT_CONSOLE_UPDATE_SIMPLE, - ObjectAcceleratorChange = EVENT_OBJECT_ACCELERATORCHANGE, - ObjectCloaked = EVENT_OBJECT_CLOAKED, - ObjectContentScrolled = EVENT_OBJECT_CONTENTSCROLLED, - ObjectCreate = EVENT_OBJECT_CREATE, - ObjectDefActionChange = EVENT_OBJECT_DEFACTIONCHANGE, - ObjectDescriptionChange = EVENT_OBJECT_DESCRIPTIONCHANGE, - ObjectDestroy = EVENT_OBJECT_DESTROY, - ObjectDragCancel = EVENT_OBJECT_DRAGCANCEL, - ObjectDragComplete = EVENT_OBJECT_DRAGCOMPLETE, - ObjectDragDropped = EVENT_OBJECT_DRAGDROPPED, - ObjectDragEnter = EVENT_OBJECT_DRAGENTER, - ObjectDragLeave = EVENT_OBJECT_DRAGLEAVE, - ObjectDragStart = EVENT_OBJECT_DRAGSTART, - ObjectEnd = EVENT_OBJECT_END, - ObjectFocus = EVENT_OBJECT_FOCUS, - ObjectHelpChange = EVENT_OBJECT_HELPCHANGE, - ObjectHide = EVENT_OBJECT_HIDE, - ObjectHostedObjectsInvalidated = EVENT_OBJECT_HOSTEDOBJECTSINVALIDATED, - ObjectImeChange = EVENT_OBJECT_IME_CHANGE, - ObjectImeHide = EVENT_OBJECT_IME_HIDE, - ObjectImeShow = EVENT_OBJECT_IME_SHOW, - ObjectInvoked = EVENT_OBJECT_INVOKED, - ObjectLiveRegionChanged = EVENT_OBJECT_LIVEREGIONCHANGED, - ObjectLocationChange = EVENT_OBJECT_LOCATIONCHANGE, - ObjectNameChange = EVENT_OBJECT_NAMECHANGE, - ObjectParentChange = EVENT_OBJECT_PARENTCHANGE, - ObjectReorder = EVENT_OBJECT_REORDER, - ObjectSelection = EVENT_OBJECT_SELECTION, - ObjectSelectionAdd = EVENT_OBJECT_SELECTIONADD, - ObjectSelectionRemove = EVENT_OBJECT_SELECTIONREMOVE, - ObjectSelectionWithin = EVENT_OBJECT_SELECTIONWITHIN, - ObjectShow = EVENT_OBJECT_SHOW, - ObjectStateChange = EVENT_OBJECT_STATECHANGE, - ObjectTextEditConversionTargetChanged = EVENT_OBJECT_TEXTEDIT_CONVERSIONTARGETCHANGED, - ObjectTextSelectionChanged = EVENT_OBJECT_TEXTSELECTIONCHANGED, - ObjectUncloaked = EVENT_OBJECT_UNCLOAKED, - ObjectValueChange = EVENT_OBJECT_VALUECHANGE, - OemDefinedEnd = EVENT_OEM_DEFINED_END, - OemDefinedStart = EVENT_OEM_DEFINED_START, - SystemAlert = EVENT_SYSTEM_ALERT, - SystemArrangementPreview = EVENT_SYSTEM_ARRANGMENTPREVIEW, - SystemCaptureEnd = EVENT_SYSTEM_CAPTUREEND, - SystemCaptureStart = EVENT_SYSTEM_CAPTURESTART, - SystemContextHelpEnd = EVENT_SYSTEM_CONTEXTHELPEND, - SystemContextHelpStart = EVENT_SYSTEM_CONTEXTHELPSTART, - SystemDesktopSwitch = EVENT_SYSTEM_DESKTOPSWITCH, - SystemDialogEnd = EVENT_SYSTEM_DIALOGEND, - SystemDialogStart = EVENT_SYSTEM_DIALOGSTART, - SystemDragDropEnd = EVENT_SYSTEM_DRAGDROPEND, - SystemDragDropStart = EVENT_SYSTEM_DRAGDROPSTART, - SystemEnd = EVENT_SYSTEM_END, - SystemForeground = EVENT_SYSTEM_FOREGROUND, - SystemImeKeyNotification = EVENT_SYSTEM_IME_KEY_NOTIFICATION, - SystemMenuEnd = EVENT_SYSTEM_MENUEND, - SystemMenuPopupEnd = EVENT_SYSTEM_MENUPOPUPEND, - SystemMenuPopupStart = EVENT_SYSTEM_MENUPOPUPSTART, - SystemMenuStart = EVENT_SYSTEM_MENUSTART, - SystemMinimizeEnd = EVENT_SYSTEM_MINIMIZEEND, - SystemMinimizeStart = EVENT_SYSTEM_MINIMIZESTART, - SystemMoveSizeEnd = EVENT_SYSTEM_MOVESIZEEND, - SystemMoveSizeStart = EVENT_SYSTEM_MOVESIZESTART, - SystemScrollingEnd = EVENT_SYSTEM_SCROLLINGEND, - SystemScrollingStart = EVENT_SYSTEM_SCROLLINGSTART, - SystemSound = EVENT_SYSTEM_SOUND, - SystemSwitchEnd = EVENT_SYSTEM_SWITCHEND, - SystemSwitchStart = EVENT_SYSTEM_SWITCHSTART, - SystemSwitcherAppDropped = EVENT_SYSTEM_SWITCHER_APPDROPPED, - SystemSwitcherAppGrabbed = EVENT_SYSTEM_SWITCHER_APPGRABBED, - SystemSwitcherAppOverTarget = EVENT_SYSTEM_SWITCHER_APPOVERTARGET, - SystemSwitcherCancelled = EVENT_SYSTEM_SWITCHER_CANCELLED, - UiaEventIdSEnd = EVENT_UIA_EVENTID_END, - UiaEventIdStart = EVENT_UIA_EVENTID_START, - UiaPropIdSEnd = EVENT_UIA_PROPID_END, - UiaPropIdStart = EVENT_UIA_PROPID_START, - // ================== Synthetic events ================== - SyntheticFullscreenStart(SyntheticFullscreenData), - SyntheticFullscreenEnd(SyntheticFullscreenData), -} - -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct SyntheticFullscreenData { - pub handle: HWND, - pub monitor: HMONITOR, -} - -impl TryFrom for WinEvent { - type Error = (); - - fn try_from(value: u32) -> Result { - match value { - EVENT_AIA_END => Ok(Self::AiaEnd), - EVENT_AIA_START => Ok(Self::AiaStart), - EVENT_CONSOLE_CARET => Ok(Self::ConsoleCaret), - EVENT_CONSOLE_END => Ok(Self::ConsoleEnd), - EVENT_CONSOLE_END_APPLICATION => Ok(Self::ConsoleEndApplication), - EVENT_CONSOLE_LAYOUT => Ok(Self::ConsoleLayout), - EVENT_CONSOLE_START_APPLICATION => Ok(Self::ConsoleStartApplication), - EVENT_CONSOLE_UPDATE_REGION => Ok(Self::ConsoleUpdateRegion), - EVENT_CONSOLE_UPDATE_SCROLL => Ok(Self::ConsoleUpdateScroll), - EVENT_CONSOLE_UPDATE_SIMPLE => Ok(Self::ConsoleUpdateSimple), - EVENT_OBJECT_ACCELERATORCHANGE => Ok(Self::ObjectAcceleratorChange), - EVENT_OBJECT_CLOAKED => Ok(Self::ObjectCloaked), - EVENT_OBJECT_CONTENTSCROLLED => Ok(Self::ObjectContentScrolled), - EVENT_OBJECT_CREATE => Ok(Self::ObjectCreate), - EVENT_OBJECT_DEFACTIONCHANGE => Ok(Self::ObjectDefActionChange), - EVENT_OBJECT_DESCRIPTIONCHANGE => Ok(Self::ObjectDescriptionChange), - EVENT_OBJECT_DESTROY => Ok(Self::ObjectDestroy), - EVENT_OBJECT_DRAGCANCEL => Ok(Self::ObjectDragCancel), - EVENT_OBJECT_DRAGCOMPLETE => Ok(Self::ObjectDragComplete), - EVENT_OBJECT_DRAGDROPPED => Ok(Self::ObjectDragDropped), - EVENT_OBJECT_DRAGENTER => Ok(Self::ObjectDragEnter), - EVENT_OBJECT_DRAGLEAVE => Ok(Self::ObjectDragLeave), - EVENT_OBJECT_DRAGSTART => Ok(Self::ObjectDragStart), - EVENT_OBJECT_END => Ok(Self::ObjectEnd), - EVENT_OBJECT_FOCUS => Ok(Self::ObjectFocus), - EVENT_OBJECT_HELPCHANGE => Ok(Self::ObjectHelpChange), - EVENT_OBJECT_HIDE => Ok(Self::ObjectHide), - EVENT_OBJECT_HOSTEDOBJECTSINVALIDATED => Ok(Self::ObjectHostedObjectsInvalidated), - EVENT_OBJECT_IME_CHANGE => Ok(Self::ObjectImeChange), - EVENT_OBJECT_IME_HIDE => Ok(Self::ObjectImeHide), - EVENT_OBJECT_IME_SHOW => Ok(Self::ObjectImeShow), - EVENT_OBJECT_INVOKED => Ok(Self::ObjectInvoked), - EVENT_OBJECT_LIVEREGIONCHANGED => Ok(Self::ObjectLiveRegionChanged), - EVENT_OBJECT_LOCATIONCHANGE => Ok(Self::ObjectLocationChange), - EVENT_OBJECT_NAMECHANGE => Ok(Self::ObjectNameChange), - EVENT_OBJECT_PARENTCHANGE => Ok(Self::ObjectParentChange), - EVENT_OBJECT_REORDER => Ok(Self::ObjectReorder), - EVENT_OBJECT_SELECTION => Ok(Self::ObjectSelection), - EVENT_OBJECT_SELECTIONADD => Ok(Self::ObjectSelectionAdd), - EVENT_OBJECT_SELECTIONREMOVE => Ok(Self::ObjectSelectionRemove), - EVENT_OBJECT_SELECTIONWITHIN => Ok(Self::ObjectSelectionWithin), - EVENT_OBJECT_SHOW => Ok(Self::ObjectShow), - EVENT_OBJECT_STATECHANGE => Ok(Self::ObjectStateChange), - EVENT_OBJECT_TEXTEDIT_CONVERSIONTARGETCHANGED => { - Ok(Self::ObjectTextEditConversionTargetChanged) - } - EVENT_OBJECT_TEXTSELECTIONCHANGED => Ok(Self::ObjectTextSelectionChanged), - EVENT_OBJECT_UNCLOAKED => Ok(Self::ObjectUncloaked), - EVENT_OBJECT_VALUECHANGE => Ok(Self::ObjectValueChange), - EVENT_OEM_DEFINED_END => Ok(Self::OemDefinedEnd), - EVENT_OEM_DEFINED_START => Ok(Self::OemDefinedStart), - EVENT_SYSTEM_ALERT => Ok(Self::SystemAlert), - EVENT_SYSTEM_ARRANGMENTPREVIEW => Ok(Self::SystemArrangementPreview), - EVENT_SYSTEM_CAPTUREEND => Ok(Self::SystemCaptureEnd), - EVENT_SYSTEM_CAPTURESTART => Ok(Self::SystemCaptureStart), - EVENT_SYSTEM_CONTEXTHELPEND => Ok(Self::SystemContextHelpEnd), - EVENT_SYSTEM_CONTEXTHELPSTART => Ok(Self::SystemContextHelpStart), - EVENT_SYSTEM_DESKTOPSWITCH => Ok(Self::SystemDesktopSwitch), - EVENT_SYSTEM_DIALOGEND => Ok(Self::SystemDialogEnd), - EVENT_SYSTEM_DIALOGSTART => Ok(Self::SystemDialogStart), - EVENT_SYSTEM_DRAGDROPEND => Ok(Self::SystemDragDropEnd), - EVENT_SYSTEM_DRAGDROPSTART => Ok(Self::SystemDragDropStart), - EVENT_SYSTEM_END => Ok(Self::SystemEnd), - EVENT_SYSTEM_FOREGROUND => Ok(Self::SystemForeground), - EVENT_SYSTEM_IME_KEY_NOTIFICATION => Ok(Self::SystemImeKeyNotification), - EVENT_SYSTEM_MENUEND => Ok(Self::SystemMenuEnd), - EVENT_SYSTEM_MENUPOPUPEND => Ok(Self::SystemMenuPopupEnd), - EVENT_SYSTEM_MENUPOPUPSTART => Ok(Self::SystemMenuPopupStart), - EVENT_SYSTEM_MENUSTART => Ok(Self::SystemMenuStart), - EVENT_SYSTEM_MINIMIZEEND => Ok(Self::SystemMinimizeEnd), - EVENT_SYSTEM_MINIMIZESTART => Ok(Self::SystemMinimizeStart), - EVENT_SYSTEM_MOVESIZEEND => Ok(Self::SystemMoveSizeEnd), - EVENT_SYSTEM_MOVESIZESTART => Ok(Self::SystemMoveSizeStart), - EVENT_SYSTEM_SCROLLINGEND => Ok(Self::SystemScrollingEnd), - EVENT_SYSTEM_SCROLLINGSTART => Ok(Self::SystemScrollingStart), - EVENT_SYSTEM_SOUND => Ok(Self::SystemSound), - EVENT_SYSTEM_SWITCHEND => Ok(Self::SystemSwitchEnd), - EVENT_SYSTEM_SWITCHER_APPDROPPED => Ok(Self::SystemSwitcherAppDropped), - EVENT_SYSTEM_SWITCHER_APPGRABBED => Ok(Self::SystemSwitcherAppGrabbed), - EVENT_SYSTEM_SWITCHER_APPOVERTARGET => Ok(Self::SystemSwitcherAppOverTarget), - EVENT_SYSTEM_SWITCHER_CANCELLED => Ok(Self::SystemSwitcherCancelled), - EVENT_SYSTEM_SWITCHSTART => Ok(Self::SystemSwitchStart), - EVENT_UIA_EVENTID_END => Ok(Self::UiaEventIdSEnd), - EVENT_UIA_EVENTID_START => Ok(Self::UiaEventIdStart), - EVENT_UIA_PROPID_END => Ok(Self::UiaPropIdSEnd), - EVENT_UIA_PROPID_START => Ok(Self::UiaPropIdStart), - - _ => Err(()), - } - } -} - -impl WinEvent { - pub fn should_handle_fullscreen_events(&self, hwnd: HWND) -> bool { - let title = WindowsApi::get_window_text(hwnd); - let is_foreground_window = hwnd == WindowsApi::get_foreground_window(); - - (is_foreground_window || *self == Self::SystemMinimizeStart) - && !IGNORE_FULLSCREEN.contains(&title) - } - - pub fn get_synthetic(&self, origin: HWND) -> Option { - match self { - Self::ObjectShow - | Self::ObjectCreate - | Self::ObjectUncloaked - | Self::SystemMinimizeEnd => { - let is_creating_invisible_window = - *self == Self::ObjectCreate && !WindowsApi::is_window_visible(origin); - if is_creating_invisible_window || !self.should_handle_fullscreen_events(origin) { - return None; - } - - if WindowsApi::is_fullscreen(origin).ok()? { - let data = SyntheticFullscreenData { - handle: origin, - monitor: WindowsApi::monitor_from_window(origin), - }; - trace_lock!(FULLSCREENED).push(data); - Some(Self::SyntheticFullscreenStart(data)) - } else { - None - } - } - Self::ObjectHide - | Self::ObjectDestroy - | Self::ObjectCloaked - | Self::SystemMinimizeStart => { - let mut fullscreened = trace_lock!(FULLSCREENED); - if let Some(index) = fullscreened.iter().position(|x| x.handle == origin) { - let data = fullscreened.remove(index); - Some(Self::SyntheticFullscreenEnd(data)) - } else { - None - } - } - Self::ObjectLocationChange => { - if !self.should_handle_fullscreen_events(origin) { - return None; - } - - let mut fullscreened = trace_lock!(FULLSCREENED); - let was_fullscreen = fullscreened.iter().position(|x| x.handle == origin); - let is_fullscreen = WindowsApi::is_fullscreen(origin).ok()?; - - // state no changed - if was_fullscreen.is_some() == is_fullscreen { - return None; - } - - if let Some(index) = was_fullscreen { - let data = fullscreened.remove(index); - Some(Self::SyntheticFullscreenEnd(data)) - } else { - let data = SyntheticFullscreenData { - handle: origin, - monitor: WindowsApi::monitor_from_window(origin), - }; - fullscreened.push(data); - Some(Self::SyntheticFullscreenStart(data)) - } - } - _ => None, - } - } -} +#![allow(clippy::use_self)] + +use lazy_static::lazy_static; +use parking_lot::Mutex; + +use windows::Win32::Foundation::HWND; +use windows::Win32::Graphics::Gdi::HMONITOR; +use windows::Win32::UI::WindowsAndMessaging::EVENT_AIA_END; +use windows::Win32::UI::WindowsAndMessaging::EVENT_AIA_START; +use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_CARET; +use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_END; +use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_END_APPLICATION; +use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_LAYOUT; +use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_START_APPLICATION; +use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_UPDATE_REGION; +use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_UPDATE_SCROLL; +use windows::Win32::UI::WindowsAndMessaging::EVENT_CONSOLE_UPDATE_SIMPLE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_ACCELERATORCHANGE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_CLOAKED; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_CONTENTSCROLLED; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_CREATE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DEFACTIONCHANGE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DESCRIPTIONCHANGE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DESTROY; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DRAGCANCEL; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DRAGCOMPLETE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DRAGDROPPED; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DRAGENTER; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DRAGLEAVE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_DRAGSTART; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_END; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_FOCUS; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_HELPCHANGE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_HIDE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_HOSTEDOBJECTSINVALIDATED; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_IME_CHANGE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_IME_HIDE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_IME_SHOW; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_INVOKED; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_LIVEREGIONCHANGED; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_LOCATIONCHANGE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_NAMECHANGE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_PARENTCHANGE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_REORDER; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_SELECTION; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_SELECTIONADD; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_SELECTIONREMOVE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_SELECTIONWITHIN; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_SHOW; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_STATECHANGE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_TEXTEDIT_CONVERSIONTARGETCHANGED; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_TEXTSELECTIONCHANGED; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_UNCLOAKED; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OBJECT_VALUECHANGE; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OEM_DEFINED_END; +use windows::Win32::UI::WindowsAndMessaging::EVENT_OEM_DEFINED_START; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_ALERT; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_ARRANGMENTPREVIEW; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_CAPTUREEND; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_CAPTURESTART; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_CONTEXTHELPEND; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_CONTEXTHELPSTART; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_DESKTOPSWITCH; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_DIALOGEND; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_DIALOGSTART; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_DRAGDROPEND; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_DRAGDROPSTART; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_END; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_FOREGROUND; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_IME_KEY_NOTIFICATION; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MENUEND; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MENUPOPUPEND; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MENUPOPUPSTART; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MENUSTART; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MINIMIZEEND; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MINIMIZESTART; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MOVESIZEEND; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_MOVESIZESTART; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_SCROLLINGEND; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_SCROLLINGSTART; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_SOUND; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_SWITCHER_APPGRABBED; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_SWITCHER_APPOVERTARGET; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_SWITCHER_CANCELLED; +use windows::Win32::UI::WindowsAndMessaging::EVENT_SYSTEM_SWITCHSTART; +use windows::Win32::UI::WindowsAndMessaging::EVENT_UIA_EVENTID_END; +use windows::Win32::UI::WindowsAndMessaging::EVENT_UIA_EVENTID_START; +use windows::Win32::UI::WindowsAndMessaging::EVENT_UIA_PROPID_END; +use windows::Win32::UI::WindowsAndMessaging::EVENT_UIA_PROPID_START; +use windows::Win32::UI::WindowsAndMessaging::{ + EVENT_SYSTEM_SWITCHEND, EVENT_SYSTEM_SWITCHER_APPDROPPED, +}; + +use crate::trace_lock; +use crate::utils::constants::IGNORE_FULLSCREEN; +use crate::windows_api::WindowsApi; + +lazy_static! { + static ref FULLSCREENED: Mutex> = Mutex::new(Vec::new()); +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +#[repr(u32)] +#[allow(dead_code)] +pub enum WinEvent { + AiaEnd = EVENT_AIA_END, + AiaStart = EVENT_AIA_START, + ConsoleCaret = EVENT_CONSOLE_CARET, + ConsoleEnd = EVENT_CONSOLE_END, + ConsoleEndApplication = EVENT_CONSOLE_END_APPLICATION, + ConsoleLayout = EVENT_CONSOLE_LAYOUT, + ConsoleStartApplication = EVENT_CONSOLE_START_APPLICATION, + ConsoleUpdateRegion = EVENT_CONSOLE_UPDATE_REGION, + ConsoleUpdateScroll = EVENT_CONSOLE_UPDATE_SCROLL, + ConsoleUpdateSimple = EVENT_CONSOLE_UPDATE_SIMPLE, + ObjectAcceleratorChange = EVENT_OBJECT_ACCELERATORCHANGE, + ObjectCloaked = EVENT_OBJECT_CLOAKED, + ObjectContentScrolled = EVENT_OBJECT_CONTENTSCROLLED, + ObjectCreate = EVENT_OBJECT_CREATE, + ObjectDefActionChange = EVENT_OBJECT_DEFACTIONCHANGE, + ObjectDescriptionChange = EVENT_OBJECT_DESCRIPTIONCHANGE, + ObjectDestroy = EVENT_OBJECT_DESTROY, + ObjectDragCancel = EVENT_OBJECT_DRAGCANCEL, + ObjectDragComplete = EVENT_OBJECT_DRAGCOMPLETE, + ObjectDragDropped = EVENT_OBJECT_DRAGDROPPED, + ObjectDragEnter = EVENT_OBJECT_DRAGENTER, + ObjectDragLeave = EVENT_OBJECT_DRAGLEAVE, + ObjectDragStart = EVENT_OBJECT_DRAGSTART, + ObjectEnd = EVENT_OBJECT_END, + ObjectFocus = EVENT_OBJECT_FOCUS, + ObjectHelpChange = EVENT_OBJECT_HELPCHANGE, + ObjectHide = EVENT_OBJECT_HIDE, + ObjectHostedObjectsInvalidated = EVENT_OBJECT_HOSTEDOBJECTSINVALIDATED, + ObjectImeChange = EVENT_OBJECT_IME_CHANGE, + ObjectImeHide = EVENT_OBJECT_IME_HIDE, + ObjectImeShow = EVENT_OBJECT_IME_SHOW, + ObjectInvoked = EVENT_OBJECT_INVOKED, + ObjectLiveRegionChanged = EVENT_OBJECT_LIVEREGIONCHANGED, + ObjectLocationChange = EVENT_OBJECT_LOCATIONCHANGE, + ObjectNameChange = EVENT_OBJECT_NAMECHANGE, + ObjectParentChange = EVENT_OBJECT_PARENTCHANGE, + ObjectReorder = EVENT_OBJECT_REORDER, + ObjectSelection = EVENT_OBJECT_SELECTION, + ObjectSelectionAdd = EVENT_OBJECT_SELECTIONADD, + ObjectSelectionRemove = EVENT_OBJECT_SELECTIONREMOVE, + ObjectSelectionWithin = EVENT_OBJECT_SELECTIONWITHIN, + ObjectShow = EVENT_OBJECT_SHOW, + ObjectStateChange = EVENT_OBJECT_STATECHANGE, + ObjectTextEditConversionTargetChanged = EVENT_OBJECT_TEXTEDIT_CONVERSIONTARGETCHANGED, + ObjectTextSelectionChanged = EVENT_OBJECT_TEXTSELECTIONCHANGED, + ObjectUncloaked = EVENT_OBJECT_UNCLOAKED, + ObjectValueChange = EVENT_OBJECT_VALUECHANGE, + OemDefinedEnd = EVENT_OEM_DEFINED_END, + OemDefinedStart = EVENT_OEM_DEFINED_START, + SystemAlert = EVENT_SYSTEM_ALERT, + SystemArrangementPreview = EVENT_SYSTEM_ARRANGMENTPREVIEW, + SystemCaptureEnd = EVENT_SYSTEM_CAPTUREEND, + SystemCaptureStart = EVENT_SYSTEM_CAPTURESTART, + SystemContextHelpEnd = EVENT_SYSTEM_CONTEXTHELPEND, + SystemContextHelpStart = EVENT_SYSTEM_CONTEXTHELPSTART, + SystemDesktopSwitch = EVENT_SYSTEM_DESKTOPSWITCH, + SystemDialogEnd = EVENT_SYSTEM_DIALOGEND, + SystemDialogStart = EVENT_SYSTEM_DIALOGSTART, + SystemDragDropEnd = EVENT_SYSTEM_DRAGDROPEND, + SystemDragDropStart = EVENT_SYSTEM_DRAGDROPSTART, + SystemEnd = EVENT_SYSTEM_END, + SystemForeground = EVENT_SYSTEM_FOREGROUND, + SystemImeKeyNotification = EVENT_SYSTEM_IME_KEY_NOTIFICATION, + SystemMenuEnd = EVENT_SYSTEM_MENUEND, + SystemMenuPopupEnd = EVENT_SYSTEM_MENUPOPUPEND, + SystemMenuPopupStart = EVENT_SYSTEM_MENUPOPUPSTART, + SystemMenuStart = EVENT_SYSTEM_MENUSTART, + SystemMinimizeEnd = EVENT_SYSTEM_MINIMIZEEND, + SystemMinimizeStart = EVENT_SYSTEM_MINIMIZESTART, + SystemMoveSizeEnd = EVENT_SYSTEM_MOVESIZEEND, + SystemMoveSizeStart = EVENT_SYSTEM_MOVESIZESTART, + SystemScrollingEnd = EVENT_SYSTEM_SCROLLINGEND, + SystemScrollingStart = EVENT_SYSTEM_SCROLLINGSTART, + SystemSound = EVENT_SYSTEM_SOUND, + SystemSwitchEnd = EVENT_SYSTEM_SWITCHEND, + SystemSwitchStart = EVENT_SYSTEM_SWITCHSTART, + SystemSwitcherAppDropped = EVENT_SYSTEM_SWITCHER_APPDROPPED, + SystemSwitcherAppGrabbed = EVENT_SYSTEM_SWITCHER_APPGRABBED, + SystemSwitcherAppOverTarget = EVENT_SYSTEM_SWITCHER_APPOVERTARGET, + SystemSwitcherCancelled = EVENT_SYSTEM_SWITCHER_CANCELLED, + UiaEventIdSEnd = EVENT_UIA_EVENTID_END, + UiaEventIdStart = EVENT_UIA_EVENTID_START, + UiaPropIdSEnd = EVENT_UIA_PROPID_END, + UiaPropIdStart = EVENT_UIA_PROPID_START, + // ================== Synthetic events ================== + SyntheticFullscreenStart(SyntheticFullscreenData), + SyntheticFullscreenEnd(SyntheticFullscreenData), +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub struct SyntheticFullscreenData { + pub handle: HWND, + pub monitor: HMONITOR, +} + +impl TryFrom for WinEvent { + type Error = (); + + fn try_from(value: u32) -> Result { + match value { + EVENT_AIA_END => Ok(Self::AiaEnd), + EVENT_AIA_START => Ok(Self::AiaStart), + EVENT_CONSOLE_CARET => Ok(Self::ConsoleCaret), + EVENT_CONSOLE_END => Ok(Self::ConsoleEnd), + EVENT_CONSOLE_END_APPLICATION => Ok(Self::ConsoleEndApplication), + EVENT_CONSOLE_LAYOUT => Ok(Self::ConsoleLayout), + EVENT_CONSOLE_START_APPLICATION => Ok(Self::ConsoleStartApplication), + EVENT_CONSOLE_UPDATE_REGION => Ok(Self::ConsoleUpdateRegion), + EVENT_CONSOLE_UPDATE_SCROLL => Ok(Self::ConsoleUpdateScroll), + EVENT_CONSOLE_UPDATE_SIMPLE => Ok(Self::ConsoleUpdateSimple), + EVENT_OBJECT_ACCELERATORCHANGE => Ok(Self::ObjectAcceleratorChange), + EVENT_OBJECT_CLOAKED => Ok(Self::ObjectCloaked), + EVENT_OBJECT_CONTENTSCROLLED => Ok(Self::ObjectContentScrolled), + EVENT_OBJECT_CREATE => Ok(Self::ObjectCreate), + EVENT_OBJECT_DEFACTIONCHANGE => Ok(Self::ObjectDefActionChange), + EVENT_OBJECT_DESCRIPTIONCHANGE => Ok(Self::ObjectDescriptionChange), + EVENT_OBJECT_DESTROY => Ok(Self::ObjectDestroy), + EVENT_OBJECT_DRAGCANCEL => Ok(Self::ObjectDragCancel), + EVENT_OBJECT_DRAGCOMPLETE => Ok(Self::ObjectDragComplete), + EVENT_OBJECT_DRAGDROPPED => Ok(Self::ObjectDragDropped), + EVENT_OBJECT_DRAGENTER => Ok(Self::ObjectDragEnter), + EVENT_OBJECT_DRAGLEAVE => Ok(Self::ObjectDragLeave), + EVENT_OBJECT_DRAGSTART => Ok(Self::ObjectDragStart), + EVENT_OBJECT_END => Ok(Self::ObjectEnd), + EVENT_OBJECT_FOCUS => Ok(Self::ObjectFocus), + EVENT_OBJECT_HELPCHANGE => Ok(Self::ObjectHelpChange), + EVENT_OBJECT_HIDE => Ok(Self::ObjectHide), + EVENT_OBJECT_HOSTEDOBJECTSINVALIDATED => Ok(Self::ObjectHostedObjectsInvalidated), + EVENT_OBJECT_IME_CHANGE => Ok(Self::ObjectImeChange), + EVENT_OBJECT_IME_HIDE => Ok(Self::ObjectImeHide), + EVENT_OBJECT_IME_SHOW => Ok(Self::ObjectImeShow), + EVENT_OBJECT_INVOKED => Ok(Self::ObjectInvoked), + EVENT_OBJECT_LIVEREGIONCHANGED => Ok(Self::ObjectLiveRegionChanged), + EVENT_OBJECT_LOCATIONCHANGE => Ok(Self::ObjectLocationChange), + EVENT_OBJECT_NAMECHANGE => Ok(Self::ObjectNameChange), + EVENT_OBJECT_PARENTCHANGE => Ok(Self::ObjectParentChange), + EVENT_OBJECT_REORDER => Ok(Self::ObjectReorder), + EVENT_OBJECT_SELECTION => Ok(Self::ObjectSelection), + EVENT_OBJECT_SELECTIONADD => Ok(Self::ObjectSelectionAdd), + EVENT_OBJECT_SELECTIONREMOVE => Ok(Self::ObjectSelectionRemove), + EVENT_OBJECT_SELECTIONWITHIN => Ok(Self::ObjectSelectionWithin), + EVENT_OBJECT_SHOW => Ok(Self::ObjectShow), + EVENT_OBJECT_STATECHANGE => Ok(Self::ObjectStateChange), + EVENT_OBJECT_TEXTEDIT_CONVERSIONTARGETCHANGED => { + Ok(Self::ObjectTextEditConversionTargetChanged) + } + EVENT_OBJECT_TEXTSELECTIONCHANGED => Ok(Self::ObjectTextSelectionChanged), + EVENT_OBJECT_UNCLOAKED => Ok(Self::ObjectUncloaked), + EVENT_OBJECT_VALUECHANGE => Ok(Self::ObjectValueChange), + EVENT_OEM_DEFINED_END => Ok(Self::OemDefinedEnd), + EVENT_OEM_DEFINED_START => Ok(Self::OemDefinedStart), + EVENT_SYSTEM_ALERT => Ok(Self::SystemAlert), + EVENT_SYSTEM_ARRANGMENTPREVIEW => Ok(Self::SystemArrangementPreview), + EVENT_SYSTEM_CAPTUREEND => Ok(Self::SystemCaptureEnd), + EVENT_SYSTEM_CAPTURESTART => Ok(Self::SystemCaptureStart), + EVENT_SYSTEM_CONTEXTHELPEND => Ok(Self::SystemContextHelpEnd), + EVENT_SYSTEM_CONTEXTHELPSTART => Ok(Self::SystemContextHelpStart), + EVENT_SYSTEM_DESKTOPSWITCH => Ok(Self::SystemDesktopSwitch), + EVENT_SYSTEM_DIALOGEND => Ok(Self::SystemDialogEnd), + EVENT_SYSTEM_DIALOGSTART => Ok(Self::SystemDialogStart), + EVENT_SYSTEM_DRAGDROPEND => Ok(Self::SystemDragDropEnd), + EVENT_SYSTEM_DRAGDROPSTART => Ok(Self::SystemDragDropStart), + EVENT_SYSTEM_END => Ok(Self::SystemEnd), + EVENT_SYSTEM_FOREGROUND => Ok(Self::SystemForeground), + EVENT_SYSTEM_IME_KEY_NOTIFICATION => Ok(Self::SystemImeKeyNotification), + EVENT_SYSTEM_MENUEND => Ok(Self::SystemMenuEnd), + EVENT_SYSTEM_MENUPOPUPEND => Ok(Self::SystemMenuPopupEnd), + EVENT_SYSTEM_MENUPOPUPSTART => Ok(Self::SystemMenuPopupStart), + EVENT_SYSTEM_MENUSTART => Ok(Self::SystemMenuStart), + EVENT_SYSTEM_MINIMIZEEND => Ok(Self::SystemMinimizeEnd), + EVENT_SYSTEM_MINIMIZESTART => Ok(Self::SystemMinimizeStart), + EVENT_SYSTEM_MOVESIZEEND => Ok(Self::SystemMoveSizeEnd), + EVENT_SYSTEM_MOVESIZESTART => Ok(Self::SystemMoveSizeStart), + EVENT_SYSTEM_SCROLLINGEND => Ok(Self::SystemScrollingEnd), + EVENT_SYSTEM_SCROLLINGSTART => Ok(Self::SystemScrollingStart), + EVENT_SYSTEM_SOUND => Ok(Self::SystemSound), + EVENT_SYSTEM_SWITCHEND => Ok(Self::SystemSwitchEnd), + EVENT_SYSTEM_SWITCHER_APPDROPPED => Ok(Self::SystemSwitcherAppDropped), + EVENT_SYSTEM_SWITCHER_APPGRABBED => Ok(Self::SystemSwitcherAppGrabbed), + EVENT_SYSTEM_SWITCHER_APPOVERTARGET => Ok(Self::SystemSwitcherAppOverTarget), + EVENT_SYSTEM_SWITCHER_CANCELLED => Ok(Self::SystemSwitcherCancelled), + EVENT_SYSTEM_SWITCHSTART => Ok(Self::SystemSwitchStart), + EVENT_UIA_EVENTID_END => Ok(Self::UiaEventIdSEnd), + EVENT_UIA_EVENTID_START => Ok(Self::UiaEventIdStart), + EVENT_UIA_PROPID_END => Ok(Self::UiaPropIdSEnd), + EVENT_UIA_PROPID_START => Ok(Self::UiaPropIdStart), + + _ => Err(()), + } + } +} + +impl WinEvent { + pub fn should_handle_fullscreen_events(&self, hwnd: HWND) -> bool { + let title = WindowsApi::get_window_text(hwnd); + let is_foreground_window = hwnd == WindowsApi::get_foreground_window(); + + (is_foreground_window || *self == Self::SystemMinimizeStart) + && !IGNORE_FULLSCREEN.contains(&title) + } + + pub fn get_synthetic(&self, origin: HWND) -> Option { + match self { + Self::ObjectShow + | Self::ObjectCreate + | Self::ObjectUncloaked + | Self::SystemMinimizeEnd => { + let is_creating_invisible_window = + *self == Self::ObjectCreate && !WindowsApi::is_window_visible(origin); + if is_creating_invisible_window || !self.should_handle_fullscreen_events(origin) { + return None; + } + + if WindowsApi::is_fullscreen(origin).ok()? { + let data = SyntheticFullscreenData { + handle: origin, + monitor: WindowsApi::monitor_from_window(origin), + }; + trace_lock!(FULLSCREENED).push(data); + Some(Self::SyntheticFullscreenStart(data)) + } else { + None + } + } + Self::ObjectHide + | Self::ObjectDestroy + | Self::ObjectCloaked + | Self::SystemMinimizeStart => { + let mut fullscreened = trace_lock!(FULLSCREENED); + if let Some(index) = fullscreened.iter().position(|x| x.handle == origin) { + let data = fullscreened.remove(index); + Some(Self::SyntheticFullscreenEnd(data)) + } else { + None + } + } + Self::ObjectLocationChange => { + if !self.should_handle_fullscreen_events(origin) { + return None; + } + + let mut fullscreened = trace_lock!(FULLSCREENED); + let was_fullscreen = fullscreened.iter().position(|x| x.handle == origin); + let is_fullscreen = WindowsApi::is_fullscreen(origin).ok()?; + + // state no changed + if was_fullscreen.is_some() == is_fullscreen { + return None; + } + + if let Some(index) = was_fullscreen { + let data = fullscreened.remove(index); + Some(Self::SyntheticFullscreenEnd(data)) + } else { + let data = SyntheticFullscreenData { + handle: origin, + monitor: WindowsApi::monitor_from_window(origin), + }; + fullscreened.push(data); + Some(Self::SyntheticFullscreenStart(data)) + } + } + _ => None, + } + } +} diff --git a/src/globals.d.ts b/src/globals.d.ts index 8bddd370..a1846586 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -1,12 +1,12 @@ -declare module '*.module.css' { - const classnames: Record; - export default classnames; -} - -declare module '*.yml' { - export default string; -} - -interface ObjectConstructor { - keys(o: T): (keyof T)[]; -} +declare module '*.module.css' { + const classnames: Record; + export default classnames; +} + +declare module '*.yml' { + export default string; +} + +interface ObjectConstructor { + keys(o: T): (keyof T)[]; +} diff --git a/src/shared.interfaces.ts b/src/shared.interfaces.ts index 2a413c33..310da16c 100644 --- a/src/shared.interfaces.ts +++ b/src/shared.interfaces.ts @@ -1,29 +1,29 @@ -import { Layout, LayoutSchema, NoFallbackBehavior } from './apps/shared/schemas/Layout'; -import { Placeholder } from './apps/shared/schemas/Placeholders'; -import { ISettings } from './apps/shared/schemas/Settings'; -import { Theme } from './apps/shared/schemas/Theme'; - -export interface IRootState { - settings: T; -} - -export interface UserSettings { - jsonSettings: ISettings; - yamlSettings: anyObject[]; - themes: Theme[]; - layouts: Layout[]; - placeholders: Placeholder[]; - env: Record; - /** wallpaper url */ - wallpaper: string | null; -} - -const _defaultLayout = LayoutSchema.parse({}); -export const defaultLayout: Layout = { - ..._defaultLayout, - info: { - ..._defaultLayout.info, - filename: 'unknown', - }, - noFallbackBehavior: NoFallbackBehavior.Unmanaged, -}; +import { Layout, LayoutSchema, NoFallbackBehavior } from './apps/shared/schemas/Layout'; +import { Placeholder } from './apps/shared/schemas/Placeholders'; +import { ISettings } from './apps/shared/schemas/Settings'; +import { Theme } from './apps/shared/schemas/Theme'; + +export interface IRootState { + settings: T; +} + +export interface UserSettings { + jsonSettings: ISettings; + yamlSettings: anyObject[]; + themes: Theme[]; + layouts: Layout[]; + placeholders: Placeholder[]; + env: Record; + /** wallpaper url */ + wallpaper: string | null; +} + +const _defaultLayout = LayoutSchema.parse({}); +export const defaultLayout: Layout = { + ..._defaultLayout, + info: { + ..._defaultLayout.info, + filename: 'unknown', + }, + noFallbackBehavior: NoFallbackBehavior.Unmanaged, +}; diff --git a/static/apps_templates/adobe.yml b/static/apps_templates/adobe.yml index 00218081..7330afa4 100644 --- a/static/apps_templates/adobe.yml +++ b/static/apps_templates/adobe.yml @@ -1,7 +1,7 @@ -- name: Photoshop Dialogs - identifier: - id: PSDialogBox - kind: Class - matching_strategy: Equals - options: +- name: Photoshop Dialogs + identifier: + id: PSDialogBox + kind: Class + matching_strategy: Equals + options: - unmanage \ No newline at end of file diff --git a/static/apps_templates/browser.yml b/static/apps_templates/browser.yml index 4674cdb8..1df75060 100644 --- a/static/apps_templates/browser.yml +++ b/static/apps_templates/browser.yml @@ -1,7 +1,7 @@ -- name: Picture in Picture - identifier: - id: Picture-in-Picture - kind: Title - matching_strategy: Equals - options: +- name: Picture in Picture + identifier: + id: Picture-in-Picture + kind: Title + matching_strategy: Equals + options: - pinned \ No newline at end of file diff --git a/static/apps_templates/core.yml b/static/apps_templates/core.yml index a6ea99a3..995de5c4 100644 --- a/static/apps_templates/core.yml +++ b/static/apps_templates/core.yml @@ -1,14 +1,14 @@ -- name: Base - identifier: - id: (?i)((install)|(setup)|(complete)|(menu)|(notification)) - kind: Title - matching_strategy: Regex - options: - - unmanage -- name: Seelen - identifier: - id: seelen-ui.exe - kind: exe - matching_strategy: equals - options: +- name: Base + identifier: + id: (?i)((install)|(setup)|(complete)|(menu)|(notification)) + kind: Title + matching_strategy: Regex + options: + - unmanage +- name: Seelen + identifier: + id: seelen-ui.exe + kind: exe + matching_strategy: equals + options: - unmanage \ No newline at end of file diff --git a/static/apps_templates/development.yml b/static/apps_templates/development.yml index 8c0926fd..05387caa 100644 --- a/static/apps_templates/development.yml +++ b/static/apps_templates/development.yml @@ -1,7 +1,7 @@ -- name: Pinetry - identifier: - id: pinentry.exe - kind: Exe - matching_strategy: Legacy - options: +- name: Pinetry + identifier: + id: pinentry.exe + kind: Exe + matching_strategy: Legacy + options: - unmanage \ No newline at end of file diff --git a/static/apps_templates/gaming.yml b/static/apps_templates/gaming.yml index 6ef87624..bde4ad9f 100644 --- a/static/apps_templates/gaming.yml +++ b/static/apps_templates/gaming.yml @@ -1,20 +1,20 @@ -- name: Steam - identifier: - id: (steamwebhelper.exe)|(steam.exe) - kind: Exe - matching_strategy: Regex - and: - - id: Steam - kind: Title - matching_strategy: equals - negation: true - options: - - unmanage - -- name: Steam Apps/Games - identifier: - id: steamapps - kind: path - matching_strategy: contains - options: +- name: Steam + identifier: + id: (steamwebhelper.exe)|(steam.exe) + kind: Exe + matching_strategy: Regex + and: + - id: Steam + kind: Title + matching_strategy: equals + negation: true + options: + - unmanage + +- name: Steam Apps/Games + identifier: + id: steamapps + kind: path + matching_strategy: contains + options: - unmanage \ No newline at end of file diff --git a/static/apps_templates/uncategorized.yml b/static/apps_templates/uncategorized.yml index 22e554eb..aecbf235 100644 --- a/static/apps_templates/uncategorized.yml +++ b/static/apps_templates/uncategorized.yml @@ -1,595 +1,595 @@ -- name: Guitar Rig 7.exe - identifier: - id: Guitar Rig 7.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: 1Password.exe - identifier: - id: 1Password.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: AbletonVstPlugClass - identifier: - id: AbletonVstPlugClass - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: Vst3PlugWindow - identifier: - id: Vst3PlugWindow - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: DroverLord - Window Class - identifier: - id: DroverLord - Window Class - kind: Class - matching_strategy: Equals - options: - - unmanage -- name: Affinity Photo 2 - identifier: - id: Affinity Photo 2 - kind: Title - matching_strategy: Legacy - options: - - force -- name: Photo.exe - identifier: - id: Photo.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: Window Spy - identifier: - id: Window Spy - kind: Title - matching_strategy: StartsWith - options: - - unmanage -- name: AutoHotkeyUX.exe - identifier: - id: AutoHotkeyUX.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: Bloxstrap.exe - identifier: - id: Bloxstrap.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: SunAwtDialog - identifier: - id: SunAwtDialog - kind: Class - matching_strategy: Equals - options: - - unmanage -- name: Calculator - identifier: - id: Calculator - kind: Title - matching_strategy: Equals - options: - - unmanage -- name: SelfService.exe - identifier: - id: SelfService.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: CredentialUIBroker.exe - identifier: - id: CredentialUIBroker.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: TApplication - identifier: - id: TApplication - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: TWizardForm - identifier: - id: TWizardForm - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: Dropbox.exe - identifier: - id: Dropbox.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: Elephicon.exe - identifier: - id: Elephicon.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: Camera Hub.exe - identifier: - id: Camera Hub.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: ControlCenter.exe - identifier: - id: ControlCenter.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: WaveLink.exe - identifier: - id: WaveLink.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: Everything1.5a - identifier: - id: EVERYTHING_(1.5a) - kind: Class - matching_strategy: Legacy - options: - - force -- name: GOG Galaxy - identifier: - id: GalaxyClient.exe - kind: Exe - matching_strategy: Equals - options: - - force -- name: Chrome_RenderWidgetHostHWND - identifier: - id: Chrome_RenderWidgetHostHWND - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: git-credential-manager.exe - identifier: - id: git-credential-manager.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: Godot Manager - identifier: - id: GodotManager.exe - kind: Exe - matching_strategy: Equals - options: - - force -- name: GoogleDriveFS.exe - identifier: - id: GoogleDriveFS.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: SunAwtDialog - identifier: - id: SunAwtDialog - kind: Class - matching_strategy: Equals - options: - - unmanage -- name: keyviz.exe - identifier: - id: keyviz.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: LogiBolt.exe - identifier: - id: LogiBolt.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: LogiTune.exe - identifier: - id: LogiTune.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: LogiOptionsUI.exe - identifier: - id: LogiOptionsUI.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: ManicTime - identifier: - id: ManicTimeClient.exe - kind: Exe - matching_strategy: Equals - options: - - force -- name: _WwB - identifier: - id: _WwB - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: _WwB - identifier: - id: _WwB - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: MSPCManager.exe - identifier: - id: MSPCManager.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: _WwB - identifier: - id: _WwB - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: Microsoft Teams Notification - identifier: - id: Microsoft Teams Notification - kind: Title - matching_strategy: Legacy - options: - - unmanage -- name: Microsoft Teams Call - identifier: - id: Microsoft Teams Call - kind: Title - matching_strategy: Legacy - options: - - unmanage -- name: _WwB - identifier: - id: _WwB - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: MozillaTaskbarPreviewClass - identifier: - id: MozillaTaskbarPreviewClass - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: NiceHash Miner - identifier: - id: nhm_app.exe - kind: Exe - matching_strategy: Equals - options: - - force -- name: NohBoard.exe - identifier: - id: NohBoard.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: Obsidian - identifier: - id: Obsidian.exe - kind: Exe - matching_strategy: Equals - options: - - force -- name: OneDriveReactNativeWin32WindowClass - identifier: - id: OneDriveReactNativeWin32WindowClass - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: Paradox Launcher.exe - identifier: - id: Paradox Launcher.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: Playnite.FullscreenApp.exe - identifier: - id: Playnite.FullscreenApp.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: PowerToys.ColorPickerUI.exe - identifier: - id: PowerToys.ColorPickerUI.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: PowerToys.CropAndLock.exe - identifier: - id: PowerToys.CropAndLock.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: PowerToys.ImageResizer.exe - identifier: - id: PowerToys.ImageResizer.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: PowerToys.Peek.UI.exe - identifier: - id: PowerToys.Peek.UI.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: PowerToys.PowerLauncher.exe - identifier: - id: PowerToys.PowerLauncher.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: PowerToys.PowerAccent.exe - identifier: - id: PowerToys.PowerAccent.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: ProcessHacker.exe - identifier: - id: ProcessHacker.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: SunAwtDialog - identifier: - id: SunAwtDialog - kind: Class - matching_strategy: Equals - options: - - unmanage -- name: QuickLook.exe - identifier: - id: QuickLook.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: RepoZ.exe - identifier: - id: RepoZ.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: SunAwtDialog - identifier: - id: SunAwtDialog - kind: Class - matching_strategy: Equals - options: - - unmanage -- name: PopupMessageWindow - identifier: - id: PopupMessageWindow - kind: Title - matching_strategy: Legacy - options: - - unmanage -- name: RoundedTB.exe - identifier: - id: RoundedTB.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: SunAwtDialog - identifier: - id: SunAwtDialog - kind: Class - matching_strategy: Equals - options: - - unmanage -- name: sideloadly.exe - identifier: - id: sideloadly.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: Chrome_RenderWidgetHostHWND - identifier: - id: Chrome_RenderWidgetHostHWND - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: Chrome_RenderWidgetHostHWND - identifier: - id: Chrome_RenderWidgetHostHWND - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: obj_App - identifier: - id: obj_App - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: obj_Form - identifier: - id: obj_Form - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: SnippingTool.exe - identifier: - id: SnippingTool.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: notificationtoasts_ - identifier: - id: notificationtoasts_ - kind: Title - matching_strategy: Legacy - options: - - unmanage -- name: SystemInformer.exe - identifier: - id: SystemInformer.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: Shell_Dialog - identifier: - id: Shell_Dialog - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: TaskManagerWindow - identifier: - id: TaskManagerWindow - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: TDLG2FILEACTIONMIN - identifier: - id: TDLG2FILEACTIONMIN - kind: Class - matching_strategy: Equals - options: - - unmanage -- name: tcconfig.exe - identifier: - id: tcconfig.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: TranslucentTB.exe - identifier: - id: TranslucentTB.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: SunAwtDialog - identifier: - id: SunAwtDialog - kind: Class - matching_strategy: Equals - options: - - unmanage -- name: winzip32.exe - identifier: - id: winzip32.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: winzip64.exe - identifier: - id: winzip64.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: OperationStatusWindow - identifier: - id: OperationStatusWindow - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: Control Panel - identifier: - id: Control Panel - kind: Title - matching_strategy: Legacy - options: - - unmanage -- name: msiexec.exe - identifier: - id: msiexec.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: android(splash) - identifier: - id: android(splash) - kind: Class - matching_strategy: Legacy - options: - - unmanage -- name: Hotkey sink - identifier: - id: Hotkey sink - kind: Title - matching_strategy: Legacy - options: - - unmanage -- name: Zoom.exe - identifier: - id: Zoom.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: paintdotnet.exe - identifier: - id: paintdotnet.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage -- name: ueli.exe - identifier: - id: ueli.exe - kind: Exe - matching_strategy: Equals - options: - - unmanage +- name: Guitar Rig 7.exe + identifier: + id: Guitar Rig 7.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: 1Password.exe + identifier: + id: 1Password.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: AbletonVstPlugClass + identifier: + id: AbletonVstPlugClass + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: Vst3PlugWindow + identifier: + id: Vst3PlugWindow + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: DroverLord - Window Class + identifier: + id: DroverLord - Window Class + kind: Class + matching_strategy: Equals + options: + - unmanage +- name: Affinity Photo 2 + identifier: + id: Affinity Photo 2 + kind: Title + matching_strategy: Legacy + options: + - force +- name: Photo.exe + identifier: + id: Photo.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: Window Spy + identifier: + id: Window Spy + kind: Title + matching_strategy: StartsWith + options: + - unmanage +- name: AutoHotkeyUX.exe + identifier: + id: AutoHotkeyUX.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: Bloxstrap.exe + identifier: + id: Bloxstrap.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: SunAwtDialog + identifier: + id: SunAwtDialog + kind: Class + matching_strategy: Equals + options: + - unmanage +- name: Calculator + identifier: + id: Calculator + kind: Title + matching_strategy: Equals + options: + - unmanage +- name: SelfService.exe + identifier: + id: SelfService.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: CredentialUIBroker.exe + identifier: + id: CredentialUIBroker.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: TApplication + identifier: + id: TApplication + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: TWizardForm + identifier: + id: TWizardForm + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: Dropbox.exe + identifier: + id: Dropbox.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: Elephicon.exe + identifier: + id: Elephicon.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: Camera Hub.exe + identifier: + id: Camera Hub.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: ControlCenter.exe + identifier: + id: ControlCenter.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: WaveLink.exe + identifier: + id: WaveLink.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: Everything1.5a + identifier: + id: EVERYTHING_(1.5a) + kind: Class + matching_strategy: Legacy + options: + - force +- name: GOG Galaxy + identifier: + id: GalaxyClient.exe + kind: Exe + matching_strategy: Equals + options: + - force +- name: Chrome_RenderWidgetHostHWND + identifier: + id: Chrome_RenderWidgetHostHWND + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: git-credential-manager.exe + identifier: + id: git-credential-manager.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: Godot Manager + identifier: + id: GodotManager.exe + kind: Exe + matching_strategy: Equals + options: + - force +- name: GoogleDriveFS.exe + identifier: + id: GoogleDriveFS.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: SunAwtDialog + identifier: + id: SunAwtDialog + kind: Class + matching_strategy: Equals + options: + - unmanage +- name: keyviz.exe + identifier: + id: keyviz.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: LogiBolt.exe + identifier: + id: LogiBolt.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: LogiTune.exe + identifier: + id: LogiTune.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: LogiOptionsUI.exe + identifier: + id: LogiOptionsUI.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: ManicTime + identifier: + id: ManicTimeClient.exe + kind: Exe + matching_strategy: Equals + options: + - force +- name: _WwB + identifier: + id: _WwB + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: _WwB + identifier: + id: _WwB + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: MSPCManager.exe + identifier: + id: MSPCManager.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: _WwB + identifier: + id: _WwB + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: Microsoft Teams Notification + identifier: + id: Microsoft Teams Notification + kind: Title + matching_strategy: Legacy + options: + - unmanage +- name: Microsoft Teams Call + identifier: + id: Microsoft Teams Call + kind: Title + matching_strategy: Legacy + options: + - unmanage +- name: _WwB + identifier: + id: _WwB + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: MozillaTaskbarPreviewClass + identifier: + id: MozillaTaskbarPreviewClass + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: NiceHash Miner + identifier: + id: nhm_app.exe + kind: Exe + matching_strategy: Equals + options: + - force +- name: NohBoard.exe + identifier: + id: NohBoard.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: Obsidian + identifier: + id: Obsidian.exe + kind: Exe + matching_strategy: Equals + options: + - force +- name: OneDriveReactNativeWin32WindowClass + identifier: + id: OneDriveReactNativeWin32WindowClass + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: Paradox Launcher.exe + identifier: + id: Paradox Launcher.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: Playnite.FullscreenApp.exe + identifier: + id: Playnite.FullscreenApp.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: PowerToys.ColorPickerUI.exe + identifier: + id: PowerToys.ColorPickerUI.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: PowerToys.CropAndLock.exe + identifier: + id: PowerToys.CropAndLock.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: PowerToys.ImageResizer.exe + identifier: + id: PowerToys.ImageResizer.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: PowerToys.Peek.UI.exe + identifier: + id: PowerToys.Peek.UI.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: PowerToys.PowerLauncher.exe + identifier: + id: PowerToys.PowerLauncher.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: PowerToys.PowerAccent.exe + identifier: + id: PowerToys.PowerAccent.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: ProcessHacker.exe + identifier: + id: ProcessHacker.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: SunAwtDialog + identifier: + id: SunAwtDialog + kind: Class + matching_strategy: Equals + options: + - unmanage +- name: QuickLook.exe + identifier: + id: QuickLook.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: RepoZ.exe + identifier: + id: RepoZ.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: SunAwtDialog + identifier: + id: SunAwtDialog + kind: Class + matching_strategy: Equals + options: + - unmanage +- name: PopupMessageWindow + identifier: + id: PopupMessageWindow + kind: Title + matching_strategy: Legacy + options: + - unmanage +- name: RoundedTB.exe + identifier: + id: RoundedTB.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: SunAwtDialog + identifier: + id: SunAwtDialog + kind: Class + matching_strategy: Equals + options: + - unmanage +- name: sideloadly.exe + identifier: + id: sideloadly.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: Chrome_RenderWidgetHostHWND + identifier: + id: Chrome_RenderWidgetHostHWND + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: Chrome_RenderWidgetHostHWND + identifier: + id: Chrome_RenderWidgetHostHWND + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: obj_App + identifier: + id: obj_App + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: obj_Form + identifier: + id: obj_Form + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: SnippingTool.exe + identifier: + id: SnippingTool.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: notificationtoasts_ + identifier: + id: notificationtoasts_ + kind: Title + matching_strategy: Legacy + options: + - unmanage +- name: SystemInformer.exe + identifier: + id: SystemInformer.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: Shell_Dialog + identifier: + id: Shell_Dialog + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: TaskManagerWindow + identifier: + id: TaskManagerWindow + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: TDLG2FILEACTIONMIN + identifier: + id: TDLG2FILEACTIONMIN + kind: Class + matching_strategy: Equals + options: + - unmanage +- name: tcconfig.exe + identifier: + id: tcconfig.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: TranslucentTB.exe + identifier: + id: TranslucentTB.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: SunAwtDialog + identifier: + id: SunAwtDialog + kind: Class + matching_strategy: Equals + options: + - unmanage +- name: winzip32.exe + identifier: + id: winzip32.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: winzip64.exe + identifier: + id: winzip64.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: OperationStatusWindow + identifier: + id: OperationStatusWindow + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: Control Panel + identifier: + id: Control Panel + kind: Title + matching_strategy: Legacy + options: + - unmanage +- name: msiexec.exe + identifier: + id: msiexec.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: android(splash) + identifier: + id: android(splash) + kind: Class + matching_strategy: Legacy + options: + - unmanage +- name: Hotkey sink + identifier: + id: Hotkey sink + kind: Title + matching_strategy: Legacy + options: + - unmanage +- name: Zoom.exe + identifier: + id: Zoom.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: paintdotnet.exe + identifier: + id: paintdotnet.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage +- name: ueli.exe + identifier: + id: ueli.exe + kind: Exe + matching_strategy: Equals + options: + - unmanage diff --git a/static/icons/icon.svg b/static/icons/icon.svg index dbf78f7a..90d69197 100644 --- a/static/icons/icon.svg +++ b/static/icons/icon.svg @@ -1,14 +1,14 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/static/layouts/BSP.json b/static/layouts/BSP.json index 7514ea34..2f41ee87 100644 --- a/static/layouts/BSP.json +++ b/static/layouts/BSP.json @@ -1,44 +1,44 @@ -{ - "$schema": "https://raw.githubusercontent.com/eythaann/Seelen-UI/master/documentation/schemas/layout.schema.json", - "info": { - "displayName": "BSP", - "author": "eythaann", - "description": "bspwm default tile layout" - }, - "no_fallback_behavior": "Float", - "structure": { - "type": "Horizontal", - "children": [ - { - "type": "Leaf" - }, - { - "type": "Vertical", - "children": [ - { - "type": "Leaf" - }, - { - "type": "Horizontal", - "children": [ - { - "type": "Leaf" - }, - { - "type": "Vertical", - "children": [ - { - "type": "Leaf" - }, - { - "type": "Leaf" - } - ] - } - ] - } - ] - } - ] - } +{ + "$schema": "https://raw.githubusercontent.com/eythaann/Seelen-UI/master/documentation/schemas/layout.schema.json", + "info": { + "displayName": "BSP", + "author": "eythaann", + "description": "bspwm default tile layout" + }, + "no_fallback_behavior": "Float", + "structure": { + "type": "Horizontal", + "children": [ + { + "type": "Leaf" + }, + { + "type": "Vertical", + "children": [ + { + "type": "Leaf" + }, + { + "type": "Horizontal", + "children": [ + { + "type": "Leaf" + }, + { + "type": "Vertical", + "children": [ + { + "type": "Leaf" + }, + { + "type": "Leaf" + } + ] + } + ] + } + ] + } + ] + } } \ No newline at end of file diff --git a/static/layouts/Grid.json b/static/layouts/Grid.json index 5c3fc511..2610345c 100644 --- a/static/layouts/Grid.json +++ b/static/layouts/Grid.json @@ -1,74 +1,74 @@ -{ - "$schema": "https://raw.githubusercontent.com/eythaann/Seelen-UI/master/documentation/schemas/layout.schema.json", - "info": { - "displayName": "Grid", - "author": "eythaann", - "description": "Grid Layout useful for big monitors" - }, - "no_fallback_behavior": "Float", - "structure": { - "type": "Horizontal", - "children": [ - { - "type": "Vertical", - "priority": 3, - "condition": "total >= 5", - "children": [ - { - "type": "Leaf", - "condition": "total >= 8" - }, - { - "type": "Leaf" - }, - { - "type": "Leaf" - } - ] - }, - { - "type": "Leaf", - "priority": 1, - "condition": "total == 5" - }, - { - "type": "Vertical", - "priority": 1, - "condition": "total != 5", - "children": [ - { - "type": "Leaf", - "priority": 3, - "condition": "total >= 9" - }, - { - "type": "Leaf", - "priority": 1 - }, - { - "type": "Leaf", - "condition": "total == 4 or total >= 6", - "priority": 2 - } - ] - }, - { - "type": "Vertical", - "priority": 2, - "condition": "total > 1", - "children": [ - { - "type": "Leaf", - "condition": "total >= 7" - }, - { - "type": "Leaf" - }, - { - "type": "Leaf" - } - ] - } - ] - } +{ + "$schema": "https://raw.githubusercontent.com/eythaann/Seelen-UI/master/documentation/schemas/layout.schema.json", + "info": { + "displayName": "Grid", + "author": "eythaann", + "description": "Grid Layout useful for big monitors" + }, + "no_fallback_behavior": "Float", + "structure": { + "type": "Horizontal", + "children": [ + { + "type": "Vertical", + "priority": 3, + "condition": "total >= 5", + "children": [ + { + "type": "Leaf", + "condition": "total >= 8" + }, + { + "type": "Leaf" + }, + { + "type": "Leaf" + } + ] + }, + { + "type": "Leaf", + "priority": 1, + "condition": "total == 5" + }, + { + "type": "Vertical", + "priority": 1, + "condition": "total != 5", + "children": [ + { + "type": "Leaf", + "priority": 3, + "condition": "total >= 9" + }, + { + "type": "Leaf", + "priority": 1 + }, + { + "type": "Leaf", + "condition": "total == 4 or total >= 6", + "priority": 2 + } + ] + }, + { + "type": "Vertical", + "priority": 2, + "condition": "total > 1", + "children": [ + { + "type": "Leaf", + "condition": "total >= 7" + }, + { + "type": "Leaf" + }, + { + "type": "Leaf" + } + ] + } + ] + } } \ No newline at end of file diff --git a/static/layouts/Tall.json b/static/layouts/Tall.json index 4e25eaf8..914be777 100644 --- a/static/layouts/Tall.json +++ b/static/layouts/Tall.json @@ -1,35 +1,35 @@ -{ - "$schema": "https://raw.githubusercontent.com/eythaann/Seelen-UI/master/documentation/schemas/layout.schema.json", - "info": { - "displayName": "Tall", - "author": "eythaann", - "description": "Tall Layout" - }, - "structure": { - "type": "Horizontal", - "children": [ - { - "type": "Leaf", - "growFactor": 1.5 - }, - { - "type": "Vertical", - "children": [ - { - "type": "Leaf" - }, - { - "type": "Leaf" - }, - { - "type": "Leaf" - }, - { - "type": "Leaf" - } - ] - } - ] - }, - "no_fallback_behavior": "Float" +{ + "$schema": "https://raw.githubusercontent.com/eythaann/Seelen-UI/master/documentation/schemas/layout.schema.json", + "info": { + "displayName": "Tall", + "author": "eythaann", + "description": "Tall Layout" + }, + "structure": { + "type": "Horizontal", + "children": [ + { + "type": "Leaf", + "growFactor": 1.5 + }, + { + "type": "Vertical", + "children": [ + { + "type": "Leaf" + }, + { + "type": "Leaf" + }, + { + "type": "Leaf" + }, + { + "type": "Leaf" + } + ] + } + ] + }, + "no_fallback_behavior": "Float" } \ No newline at end of file diff --git a/static/layouts/Wide.json b/static/layouts/Wide.json index 089c68a4..c9f8e464 100644 --- a/static/layouts/Wide.json +++ b/static/layouts/Wide.json @@ -1,35 +1,35 @@ -{ - "$schema": "https://raw.githubusercontent.com/eythaann/Seelen-UI/master/documentation/schemas/layout.schema.json", - "info": { - "displayName": "Wide", - "author": "eythaann", - "description": "Wide Layout" - }, - "structure": { - "type": "Vertical", - "children": [ - { - "type": "Leaf", - "growFactor": 1.5 - }, - { - "type": "Horizontal", - "children": [ - { - "type": "Leaf" - }, - { - "type": "Leaf" - }, - { - "type": "Leaf" - }, - { - "type": "Leaf" - } - ] - } - ] - }, - "no_fallback_behavior": "Float" +{ + "$schema": "https://raw.githubusercontent.com/eythaann/Seelen-UI/master/documentation/schemas/layout.schema.json", + "info": { + "displayName": "Wide", + "author": "eythaann", + "description": "Wide Layout" + }, + "structure": { + "type": "Vertical", + "children": [ + { + "type": "Leaf", + "growFactor": 1.5 + }, + { + "type": "Horizontal", + "children": [ + { + "type": "Leaf" + }, + { + "type": "Leaf" + }, + { + "type": "Leaf" + }, + { + "type": "Leaf" + } + ] + } + ] + }, + "no_fallback_behavior": "Float" } \ No newline at end of file diff --git a/static/placeholders/default.yml b/static/placeholders/default.yml index 74aa4865..5d48eb96 100644 --- a/static/placeholders/default.yml +++ b/static/placeholders/default.yml @@ -1,108 +1,108 @@ -info: - displayName: Default - author: eythaann, - description: Default toolbar layout good for many devices. -left: - - type: generic - template: concat("@", env.USERNAME) - onClickV2: open(env.USERPROFILE) - tooltip: t("placeholder.open_user_folder") - style: - flexShrink: 0 - - - type: generic - template: '"|"' - - - type: generic - template: concat(imgFromExe(window.exe), " ", window.name) - style: - flexShrink: 0 - - - type: generic - template: > - window.title ? "-" : "" - - - type: generic - template: window.title - style: - flexShrink: 2 - -center: - - type: date - each: minute - format: ddd D MMM, hh:mm A - template: date - -right: - - type: tray - template: icon.BsThreeDots - tooltip: t("placeholder.open_system_tray") - - - type: device - template: icon.TbBluetoothConnected - onClick: open -> "ms-settings:connecteddevices" - tooltip: t("placeholder.bluetooth_devices") - - - type: network - withWlanSelector: true - tooltip: >- - online ? t("placeholder.ethernet_connected") : t("placeholder.ethernet_disconnected") - template: >- - online - ? ( - unequal(usingInterface, null) and equalText(usingInterface.type, "IEEE80211") - ? "[ICON:FaWifi:14]" - : icon.FaComputer - ) - : icon.TbWorldCancel - - - type: media - withMediaControls: true - template: >- - isMuted - ? icon.IoVolumeMuteOutline - : volume >= 0.66 - ? icon.IoVolumeHighOutline - : volume >= 0.33 - ? icon.IoVolumeMediumOutline - : volume != 0 - ? icon.IoVolumeLowOutline - : icon.IoVolumeOffOutline - tooltip: >- - concat(t("placeholder.volume"), ": ", string(round(volume * 100)), "%") - - - type: power - tooltip: >- - concat(string(battery.percentage), t("placeholder.battery_remaining"), battery.smartCharging ? t("placeholder.smart_charge") : "") - template: >- - concat( - string(equalText(battery.state, "charging") ? "[ICON:MdOutlineElectricBolt:12] " : ""), - string(battery.smartCharging ? "[ICON:FaHeart:12] " : ""), - string( - battery.percentage > 90 - ? icon.PiBatteryFullFill - : battery.percentage > 66 - ? icon.PiBatteryHighFill - : battery.percentage > 33 - ? icon.PiBatteryMediumFill - : battery.percentage > 5 - ? icon.PiBatteryLowFill - : icon.PiBatteryWarning - ), - " ", - string(battery.percentage), - "%" - ) - onClick: open -> "ms-settings:powersleep" - - - type: notifications - template: >- - count > 0 ? icon.MdNotificationsActive : icon.MdOutlineNotifications - badge: >- - count > 0 ? count : "" - tooltip: >- - concat(t("placeholder.notifications"), ": ", string(count)) - - - type: settings - template: icon.LuSettings2 - tooltip: t("placeholder.settings") +info: + displayName: Default + author: eythaann, + description: Default toolbar layout good for many devices. +left: + - type: generic + template: concat("@", env.USERNAME) + onClickV2: open(env.USERPROFILE) + tooltip: t("placeholder.open_user_folder") + style: + flexShrink: 0 + + - type: generic + template: '"|"' + + - type: generic + template: concat(imgFromExe(window.exe), " ", window.name) + style: + flexShrink: 0 + + - type: generic + template: > + window.title ? "-" : "" + + - type: generic + template: window.title + style: + flexShrink: 2 + +center: + - type: date + each: minute + format: ddd D MMM, hh:mm A + template: date + +right: + - type: tray + template: icon.BsThreeDots + tooltip: t("placeholder.open_system_tray") + + - type: device + template: icon.TbBluetoothConnected + onClick: open -> "ms-settings:connecteddevices" + tooltip: t("placeholder.bluetooth_devices") + + - type: network + withWlanSelector: true + tooltip: >- + online ? t("placeholder.ethernet_connected") : t("placeholder.ethernet_disconnected") + template: >- + online + ? ( + unequal(usingInterface, null) and equalText(usingInterface.type, "IEEE80211") + ? "[ICON:FaWifi:14]" + : icon.FaComputer + ) + : icon.TbWorldCancel + + - type: media + withMediaControls: true + template: >- + isMuted + ? icon.IoVolumeMuteOutline + : volume >= 0.66 + ? icon.IoVolumeHighOutline + : volume >= 0.33 + ? icon.IoVolumeMediumOutline + : volume != 0 + ? icon.IoVolumeLowOutline + : icon.IoVolumeOffOutline + tooltip: >- + concat(t("placeholder.volume"), ": ", string(round(volume * 100)), "%") + + - type: power + tooltip: >- + concat(string(battery.percentage), t("placeholder.battery_remaining"), battery.smartCharging ? t("placeholder.smart_charge") : "") + template: >- + concat( + string(equalText(battery.state, "charging") ? "[ICON:MdOutlineElectricBolt:12] " : ""), + string(battery.smartCharging ? "[ICON:FaHeart:12] " : ""), + string( + battery.percentage > 90 + ? icon.PiBatteryFullFill + : battery.percentage > 66 + ? icon.PiBatteryHighFill + : battery.percentage > 33 + ? icon.PiBatteryMediumFill + : battery.percentage > 5 + ? icon.PiBatteryLowFill + : icon.PiBatteryWarning + ), + " ", + string(battery.percentage), + "%" + ) + onClick: open -> "ms-settings:powersleep" + + - type: notifications + template: >- + count > 0 ? icon.MdNotificationsActive : icon.MdOutlineNotifications + badge: >- + count > 0 ? count : "" + tooltip: >- + concat(t("placeholder.notifications"), ": ", string(count)) + + - type: settings + template: icon.LuSettings2 + tooltip: t("placeholder.settings") diff --git a/static/placeholders/default_alter.yml b/static/placeholders/default_alter.yml index d315cf1e..e7c2b2f9 100644 --- a/static/placeholders/default_alter.yml +++ b/static/placeholders/default_alter.yml @@ -1,112 +1,112 @@ -info: - displayName: Default-Alter - author: eythaann, - description: Alternative to the default layout with workspaces. - -left: - - type: generic - template: concat("@", env.USERNAME) - onClickV2: open(env.USERPROFILE) - tooltip: t("placeholder.open_user_folder") - style: - flexShrink: 0 - - - type: generic - template: '"|"' - - - type: generic - template: concat(imgFromExe(window.exe), " ", window.name) - style: - flexShrink: 0 - - - type: generic - template: > - window.title ? "-" : "" - - - type: generic - template: window.title - style: - flexShrink: 2 - -center: - - type: workspaces - mode: dotted - -right: - - type: tray - template: icon.BsThreeDots - tooltip: t("placeholder.open_system_tray") - - - type: device - template: icon.TbBluetoothConnected - onClickV2: open("ms-settings:connecteddevices") - tooltip: t("placeholder.bluetooth_devices") - - - type: network - withWlanSelector: true - tooltip: >- - online ? t("placeholder.ethernet_connected") : t("placeholder.ethernet_disconnected") - template: >- - online - ? ( - unequal(usingInterface, null) and equalText(usingInterface.type, "IEEE80211") - ? "[ICON:FaWifi:14]" - : icon.FaComputer - ) - : icon.TbWorldCancel - - - type: media - withMediaControls: true - template: >- - isMuted - ? icon.IoVolumeMuteOutline - : volume >= 0.66 - ? icon.IoVolumeHighOutline - : volume >= 0.33 - ? icon.IoVolumeMediumOutline - : volume != 0 - ? icon.IoVolumeLowOutline - : icon.IoVolumeOffOutline - tooltip: >- - concat(t("placeholder.volume"), ": ", string(round(volume * 100)), "%") - - - type: power - tooltip: >- - concat(string(battery.percentage), t("placeholder.battery_remaining"), battery.smartCharging ? t("placeholder.smart_charge") : "") - template: >- - concat( - string(equalText(battery.state, "charging") ? "[ICON:MdOutlineElectricBolt:12] " : ""), - string(battery.smartCharging ? "[ICON:FaHeart:12] " : ""), - string( - battery.percentage > 90 - ? icon.PiBatteryFullFill - : battery.percentage > 66 - ? icon.PiBatteryHighFill - : battery.percentage > 33 - ? icon.PiBatteryMediumFill - : battery.percentage > 5 - ? icon.PiBatteryLowFill - : icon.PiBatteryWarning - ), - " ", - string(battery.percentage), - "%" - ) - onClickV2: open("ms-settings:powersleep") - - - type: date - each: minute - format: ddd D MMM, hh:mm A - template: date - - - type: notifications - template: >- - count > 0 ? icon.MdNotificationsActive : icon.MdOutlineNotifications - badge: >- - count > 0 ? count : "" - tooltip: >- - concat(t("placeholder.notifications"), ": ", string(count)) - - - type: settings - template: icon.LuSettings2 - tooltip: t("placeholder.settings") +info: + displayName: Default-Alter + author: eythaann, + description: Alternative to the default layout with workspaces. + +left: + - type: generic + template: concat("@", env.USERNAME) + onClickV2: open(env.USERPROFILE) + tooltip: t("placeholder.open_user_folder") + style: + flexShrink: 0 + + - type: generic + template: '"|"' + + - type: generic + template: concat(imgFromExe(window.exe), " ", window.name) + style: + flexShrink: 0 + + - type: generic + template: > + window.title ? "-" : "" + + - type: generic + template: window.title + style: + flexShrink: 2 + +center: + - type: workspaces + mode: dotted + +right: + - type: tray + template: icon.BsThreeDots + tooltip: t("placeholder.open_system_tray") + + - type: device + template: icon.TbBluetoothConnected + onClickV2: open("ms-settings:connecteddevices") + tooltip: t("placeholder.bluetooth_devices") + + - type: network + withWlanSelector: true + tooltip: >- + online ? t("placeholder.ethernet_connected") : t("placeholder.ethernet_disconnected") + template: >- + online + ? ( + unequal(usingInterface, null) and equalText(usingInterface.type, "IEEE80211") + ? "[ICON:FaWifi:14]" + : icon.FaComputer + ) + : icon.TbWorldCancel + + - type: media + withMediaControls: true + template: >- + isMuted + ? icon.IoVolumeMuteOutline + : volume >= 0.66 + ? icon.IoVolumeHighOutline + : volume >= 0.33 + ? icon.IoVolumeMediumOutline + : volume != 0 + ? icon.IoVolumeLowOutline + : icon.IoVolumeOffOutline + tooltip: >- + concat(t("placeholder.volume"), ": ", string(round(volume * 100)), "%") + + - type: power + tooltip: >- + concat(string(battery.percentage), t("placeholder.battery_remaining"), battery.smartCharging ? t("placeholder.smart_charge") : "") + template: >- + concat( + string(equalText(battery.state, "charging") ? "[ICON:MdOutlineElectricBolt:12] " : ""), + string(battery.smartCharging ? "[ICON:FaHeart:12] " : ""), + string( + battery.percentage > 90 + ? icon.PiBatteryFullFill + : battery.percentage > 66 + ? icon.PiBatteryHighFill + : battery.percentage > 33 + ? icon.PiBatteryMediumFill + : battery.percentage > 5 + ? icon.PiBatteryLowFill + : icon.PiBatteryWarning + ), + " ", + string(battery.percentage), + "%" + ) + onClickV2: open("ms-settings:powersleep") + + - type: date + each: minute + format: ddd D MMM, hh:mm A + template: date + + - type: notifications + template: >- + count > 0 ? icon.MdNotificationsActive : icon.MdOutlineNotifications + badge: >- + count > 0 ? count : "" + tooltip: >- + concat(t("placeholder.notifications"), ": ", string(count)) + + - type: settings + template: icon.LuSettings2 + tooltip: t("placeholder.settings") diff --git a/static/themes/bubbles.yml b/static/themes/bubbles.yml index 1486a725..ecce7c24 100644 --- a/static/themes/bubbles.yml +++ b/static/themes/bubbles.yml @@ -1,32 +1,32 @@ -info: - displayName: Bubbles - author: eythaann - description: Bubbles says pop. - tags: ["toolbar"] -styles: - toolbar: | - .ft-bar-bg-layer-1 { - display: none; - } - - .ft-bar-bg-layer-2 { - display: none; - } - - .ft-bar-item { - background: #121212; - border-radius: 10px; - padding: 2px 8px; - border: 1px solid #a0a0a0; - height: 25px; - transition: background-color 300ms ease-in-out; - - &.ft-bar-item-clickable { - padding: 2px 8px; - border-radius: 10px; - - &:hover { - background-color: #323232; - } - } - } +info: + displayName: Bubbles + author: eythaann + description: Bubbles says pop. + tags: ["toolbar"] +styles: + toolbar: | + .ft-bar-bg-layer-1 { + display: none; + } + + .ft-bar-bg-layer-2 { + display: none; + } + + .ft-bar-item { + background: #121212; + border-radius: 10px; + padding: 2px 8px; + border: 1px solid #a0a0a0; + height: 25px; + transition: background-color 300ms ease-in-out; + + &.ft-bar-item-clickable { + padding: 2px 8px; + border-radius: 10px; + + &:hover { + background-color: #323232; + } + } + } diff --git a/static/themes/default/theme.toolbar.css b/static/themes/default/theme.toolbar.css index 67734330..2e39f0b4 100644 --- a/static/themes/default/theme.toolbar.css +++ b/static/themes/default/theme.toolbar.css @@ -1,416 +1,416 @@ -@keyframes leftToRight { - 0%, - 25% { - transform: translateX(0%); - left: 0%; - } - 75%, - 100% { - transform: translateX(-100%); - left: 100%; - } -} - -#root { - font-size: 0.8rem; - font-weight: 500; - - --popups-margin: 4px; - - ::-webkit-scrollbar { - width: 8px; - height: 8px; - } - - ::-webkit-scrollbar-track { - background-color: transparent; - } - - ::-webkit-scrollbar-thumb { - background-color: var(--color-gray-400); - border-radius: 8px; - } - - ::-webkit-scrollbar-thumb:hover { - background-color: var(--color-gray-500); - } -} - -.ft-bar { - color: #fefefe; - - .ft-bar-bg-layer-1 { - opacity: 0.3; - filter: saturate(0); - background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 250 250' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='10' numOctaves='3' stitchTiles='stitch '/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E"); - background-size: cover; - } - - .ft-bar-bg-layer-2 { - background-color: #121212bb; - } -} - -.ft-bar-item { - .workspace-dot { - background-color: #efefef; - transition-property: width, border-radius, background-color; - transition-duration: 200ms; - transition-timing-function: ease-out; - - &.workspace-dot-active { - background-color: var(--config-accent-color); - } - } -} - -.ft-bar-item-clickable { - padding: 4px; - border-radius: 6px; - - &:hover { - backdrop-filter: brightness(3); - } -} - -.ft-bar-item-active { - color: var(--config-accent-color); -} - -.ft-bar-item-content { - position: relative; -} - -.ft-bar-item-badge { - display: flex; - align-items: center; - justify-content: center; - position: absolute; - top: 0; - right: 0; - transform: translate(25%, -25%); - background-color: var(--config-accent-color); - height: 12px; - min-width: 12px; - font-size: 10px; - border-radius: 8px; -} - -.fast-settings { - padding: 12px 16px; - margin: var(--popups-margin); - - .fast-settings-bg-layer-1 { - background-color: var(--color-gray-50); - border-radius: 10px; - } -} - -.fast-settings-item-button { - border: 1px solid var(--color-gray-600); - border-radius: 8px; - - &:hover { - background-color: var(--color-gray-200); - } -} - -.tray { - margin: var(--popups-margin); - - .tray-bg-layer-1 { - background-color: var(--color-gray-50); - border-radius: 10px; - box-shadow: 0 0 10px 10px #0001; - } -} - -.tray-list { - padding: 10px; - max-height: 50vh; - display: flex; - flex-direction: column; - overflow-y: auto; - gap: 4px; -} - -.tray-item { - display: flex; - align-items: center; - border-radius: 8px; - padding: 8px; - gap: 6px; - height: min-content; - - &:hover { - background-color: rgba(var(--config-accent-color-rgb), 0.2); - } -} - -.tray-item-icon { - width: 1rem; - height: 1rem; - min-height: 1rem; - min-width: 1rem; -} - -.tray-item-label { - font-size: 0.7rem; - font-weight: 600; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.wlan-selector { - margin: var(--popups-margin); - width: 260px; - max-height: 50vh; - box-shadow: 0 0 10px 10px #0001; - display: flex; - flex-direction: column; - - .wlan-selector-bg-layer-1 { - background-color: var(--color-gray-50); - border-radius: 10px; - } -} - -.wlan-selector-entries { - padding: 8px; - flex: 1; - overflow-y: auto; - - .wlan-selector-empty { - font-style: italic; - } -} - -.wlan-entry { - min-height: min-content; - padding: 12px 10px; - border-radius: 8px; - gap: 10px; - - &:hover { - background-color: var(--color-gray-200); - } - - &.wlan-entry-selected { - background-color: rgba(var(--config-accent-color-rgb), 0.2); - } -} - -.wlan-entry-info { - font-weight: 600; - gap: 10px; -} - -.wlan-entry-info-ssid { - color: var(--color-gray-800); - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} - -.wlan-selector-footer { - border-top: solid 1px var(--color-gray-300); - padding: 8px 16px; - font-weight: 600; - font-size: 0.8rem; - - > span { - padding: 2px 6px; - border-radius: 8px; - - &:hover { - background-color: var(--color-gray-200); - } - } -} - -.media-control { - margin: var(--popups-margin); - width: 300px; - padding: 10px; - - .bg-layer-1 { - background-color: var(--color-gray-50); - border-radius: 10px; - } -} - -.media-control-volume { - display: flex; - gap: 4px; - align-items: center; - width: 100%; -} - -.fast-settings-label, -.media-control-label { - font-size: 0.8rem; - font-weight: 600; - color: var(--color-gray-600); - margin-bottom: 4px; - display: block; - width: 100%; - - &:not(:first-of-type) { - margin-top: 10px; - padding-top: 4px; - border-top: solid 1px var(--color-gray-300); - } -} - -.media-device { - font-weight: 600; - font-size: 0.8rem; - color: var(--color-gray-700); -} - -.media-control-session-list { - display: flex; - flex-direction: column; - margin-top: 6px; - gap: 4px; -} - -.media-session { - display: grid; - grid-template-columns: 80px 1fr; - justify-content: center; - align-items: center; - border-radius: 8px; - padding: 8px; - gap: 8px; - height: min-content; -} - -.media-session-thumbnail { - border-radius: 8px; - width: 100%; - aspect-ratio: 1/1; - object-fit: contain; - background: #0004; -} - -.media-session-info { - width: 100%; - display: flex; - flex-direction: column; - align-items: center; - overflow: hidden; - white-space: nowrap; -} - -.media-session-title, -.media-session-author { - position: relative; - align-self: flex-start; - font-size: 0.7rem; - text-align: center; - min-width: 100%; - animation: leftToRight 5s infinite alternate ease-in-out; -} - -.media-session-title { - font-weight: 600; - font-size: 1rem; -} - -.media-session-actions { - display: flex; - justify-content: center; - gap: 8px; - margin-top: 4px; -} - -.notifications { - margin: var(--popups-margin); - width: 350px; - padding: 10px; - display: flex; - flex-direction: column; - gap: 10px; - max-height: calc(100vh - var(--config-height) - (var(--popups-margin) * 2)); - - .bg-layer-1 { - opacity: 0.4; - filter: saturate(0); - background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 250 250' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='10' numOctaves='3' stitchTiles='stitch '/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E"); - background-size: cover; - border-radius: 12px; - } - - .bg-layer-2 { - opacity: 0.95; - background-color: var(--color-gray-100); - border-radius: 12px; - } -} - -.notifications-header { - display: flex; - align-items: center; - justify-content: space-between; - font-weight: 600; -} - -.notifications-body { - overflow-y: auto; - padding: 5px 10px; - margin: 0 -10px; - display: flex; - flex-direction: column; - gap: 10px; -} - -.notifications-footer { - > button { - font-size: 0.8rem; - font-weight: 600; - } -} - -.notifications-empty { - display: flex; - align-items: center; - justify-content: center; - color: var(--color-gray-500); - font-weight: 600; - font-size: 0.8rem; -} - -.notification { - border-radius: 12px; - background-color: var(--color-gray-100); - box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.4); - padding: 10px; -} - -.notification-header { - display: flex; - align-items: center; - justify-content: space-between; - gap: 16px; - padding-bottom: 5px; - border-bottom: solid 1px var(--color-gray-300); - margin-bottom: 5px; -} - -.notification-header-info { - display: flex; - align-items: center; - gap: 8px; - font-size: 0.8rem; - color: var(--color-gray-800); -} - -.notification-body { - word-break: break-word; - - .notification-body-title { - font-weight: 600; - } -} +@keyframes leftToRight { + 0%, + 25% { + transform: translateX(0%); + left: 0%; + } + 75%, + 100% { + transform: translateX(-100%); + left: 100%; + } +} + +#root { + font-size: 0.8rem; + font-weight: 500; + + --popups-margin: 4px; + + ::-webkit-scrollbar { + width: 8px; + height: 8px; + } + + ::-webkit-scrollbar-track { + background-color: transparent; + } + + ::-webkit-scrollbar-thumb { + background-color: var(--color-gray-400); + border-radius: 8px; + } + + ::-webkit-scrollbar-thumb:hover { + background-color: var(--color-gray-500); + } +} + +.ft-bar { + color: #fefefe; + + .ft-bar-bg-layer-1 { + opacity: 0.3; + filter: saturate(0); + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 250 250' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='10' numOctaves='3' stitchTiles='stitch '/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E"); + background-size: cover; + } + + .ft-bar-bg-layer-2 { + background-color: #121212bb; + } +} + +.ft-bar-item { + .workspace-dot { + background-color: #efefef; + transition-property: width, border-radius, background-color; + transition-duration: 200ms; + transition-timing-function: ease-out; + + &.workspace-dot-active { + background-color: var(--config-accent-color); + } + } +} + +.ft-bar-item-clickable { + padding: 4px; + border-radius: 6px; + + &:hover { + backdrop-filter: brightness(3); + } +} + +.ft-bar-item-active { + color: var(--config-accent-color); +} + +.ft-bar-item-content { + position: relative; +} + +.ft-bar-item-badge { + display: flex; + align-items: center; + justify-content: center; + position: absolute; + top: 0; + right: 0; + transform: translate(25%, -25%); + background-color: var(--config-accent-color); + height: 12px; + min-width: 12px; + font-size: 10px; + border-radius: 8px; +} + +.fast-settings { + padding: 12px 16px; + margin: var(--popups-margin); + + .fast-settings-bg-layer-1 { + background-color: var(--color-gray-50); + border-radius: 10px; + } +} + +.fast-settings-item-button { + border: 1px solid var(--color-gray-600); + border-radius: 8px; + + &:hover { + background-color: var(--color-gray-200); + } +} + +.tray { + margin: var(--popups-margin); + + .tray-bg-layer-1 { + background-color: var(--color-gray-50); + border-radius: 10px; + box-shadow: 0 0 10px 10px #0001; + } +} + +.tray-list { + padding: 10px; + max-height: 50vh; + display: flex; + flex-direction: column; + overflow-y: auto; + gap: 4px; +} + +.tray-item { + display: flex; + align-items: center; + border-radius: 8px; + padding: 8px; + gap: 6px; + height: min-content; + + &:hover { + background-color: rgba(var(--config-accent-color-rgb), 0.2); + } +} + +.tray-item-icon { + width: 1rem; + height: 1rem; + min-height: 1rem; + min-width: 1rem; +} + +.tray-item-label { + font-size: 0.7rem; + font-weight: 600; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.wlan-selector { + margin: var(--popups-margin); + width: 260px; + max-height: 50vh; + box-shadow: 0 0 10px 10px #0001; + display: flex; + flex-direction: column; + + .wlan-selector-bg-layer-1 { + background-color: var(--color-gray-50); + border-radius: 10px; + } +} + +.wlan-selector-entries { + padding: 8px; + flex: 1; + overflow-y: auto; + + .wlan-selector-empty { + font-style: italic; + } +} + +.wlan-entry { + min-height: min-content; + padding: 12px 10px; + border-radius: 8px; + gap: 10px; + + &:hover { + background-color: var(--color-gray-200); + } + + &.wlan-entry-selected { + background-color: rgba(var(--config-accent-color-rgb), 0.2); + } +} + +.wlan-entry-info { + font-weight: 600; + gap: 10px; +} + +.wlan-entry-info-ssid { + color: var(--color-gray-800); + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.wlan-selector-footer { + border-top: solid 1px var(--color-gray-300); + padding: 8px 16px; + font-weight: 600; + font-size: 0.8rem; + + > span { + padding: 2px 6px; + border-radius: 8px; + + &:hover { + background-color: var(--color-gray-200); + } + } +} + +.media-control { + margin: var(--popups-margin); + width: 300px; + padding: 10px; + + .bg-layer-1 { + background-color: var(--color-gray-50); + border-radius: 10px; + } +} + +.media-control-volume { + display: flex; + gap: 4px; + align-items: center; + width: 100%; +} + +.fast-settings-label, +.media-control-label { + font-size: 0.8rem; + font-weight: 600; + color: var(--color-gray-600); + margin-bottom: 4px; + display: block; + width: 100%; + + &:not(:first-of-type) { + margin-top: 10px; + padding-top: 4px; + border-top: solid 1px var(--color-gray-300); + } +} + +.media-device { + font-weight: 600; + font-size: 0.8rem; + color: var(--color-gray-700); +} + +.media-control-session-list { + display: flex; + flex-direction: column; + margin-top: 6px; + gap: 4px; +} + +.media-session { + display: grid; + grid-template-columns: 80px 1fr; + justify-content: center; + align-items: center; + border-radius: 8px; + padding: 8px; + gap: 8px; + height: min-content; +} + +.media-session-thumbnail { + border-radius: 8px; + width: 100%; + aspect-ratio: 1/1; + object-fit: contain; + background: #0004; +} + +.media-session-info { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + overflow: hidden; + white-space: nowrap; +} + +.media-session-title, +.media-session-author { + position: relative; + align-self: flex-start; + font-size: 0.7rem; + text-align: center; + min-width: 100%; + animation: leftToRight 5s infinite alternate ease-in-out; +} + +.media-session-title { + font-weight: 600; + font-size: 1rem; +} + +.media-session-actions { + display: flex; + justify-content: center; + gap: 8px; + margin-top: 4px; +} + +.notifications { + margin: var(--popups-margin); + width: 350px; + padding: 10px; + display: flex; + flex-direction: column; + gap: 10px; + max-height: calc(100vh - var(--config-height) - (var(--popups-margin) * 2)); + + .bg-layer-1 { + opacity: 0.4; + filter: saturate(0); + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 250 250' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='10' numOctaves='3' stitchTiles='stitch '/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E"); + background-size: cover; + border-radius: 12px; + } + + .bg-layer-2 { + opacity: 0.95; + background-color: var(--color-gray-100); + border-radius: 12px; + } +} + +.notifications-header { + display: flex; + align-items: center; + justify-content: space-between; + font-weight: 600; +} + +.notifications-body { + overflow-y: auto; + padding: 5px 10px; + margin: 0 -10px; + display: flex; + flex-direction: column; + gap: 10px; +} + +.notifications-footer { + > button { + font-size: 0.8rem; + font-weight: 600; + } +} + +.notifications-empty { + display: flex; + align-items: center; + justify-content: center; + color: var(--color-gray-500); + font-weight: 600; + font-size: 0.8rem; +} + +.notification { + border-radius: 12px; + background-color: var(--color-gray-100); + box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.4); + padding: 10px; +} + +.notification-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + padding-bottom: 5px; + border-bottom: solid 1px var(--color-gray-300); + margin-bottom: 5px; +} + +.notification-header-info { + display: flex; + align-items: center; + gap: 8px; + font-size: 0.8rem; + color: var(--color-gray-800); +} + +.notification-body { + word-break: break-word; + + .notification-body-title { + font-weight: 600; + } +} diff --git a/static/themes/default/theme.weg.css b/static/themes/default/theme.weg.css index f24b38cf..401b73d7 100644 --- a/static/themes/default/theme.weg.css +++ b/static/themes/default/theme.weg.css @@ -1,154 +1,154 @@ -.taskbar { - .taskbar-bg-layer-1 { - opacity: 0.3; - filter: saturate(0); - background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 250 250' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='10' numOctaves='3' stitchTiles='stitch '/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E"); - background-size: cover; - border-radius: 15px; - } - - .taskbar-bg-layer-2 { - opacity: 0.8; - background-color: var(--color-gray-100); - border-radius: 15px; - } -} - -.weg-separator { - .horizontal & { - &.weg-separator-1 { - border-left: 1px solid var(--color-gray-400); - } - &.weg-separator-2 { - border-right: 1px solid var(--color-gray-400); - } - } - - .vertical & { - &.weg-separator-1 { - border-top: 1px solid var(--color-gray-400); - } - &.weg-separator-2 { - border-bottom: 1px solid var(--color-gray-400); - } - } -} - -.weg-item { - .item-bg-layer-1 { - background-color: var(--color-gray-100); - border-radius: 25%; - box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5); - transition: background-color 0.2s ease-in-out; - } - - &:hover { - .item-bg-layer-1 { - background-color: var(--color-gray-400); - } - } - - &:active { - filter: brightness(0.4); - } - - &:not(:active) { - transition-property: filter; - transition-duration: 0.2s; - transition-timing-function: ease-in-out; - } -} - -.weg-item-icon { - width: 65%; - height: 65%; - filter: drop-shadow(0px 0px 1px #0000009a); - object-fit: contain; -} - -.weg-item-icon-start { - width: 100%; - height: 100%; - filter: brightness(1.2); - background: linear-gradient(150deg, var(--config-accent-color) 10%, #000 150%); - mask-image: url('data:image/svg+xml;charset=utf-8,'); - mask-repeat: no-repeat; - mask-size: contain; - mask-position: center; -} - -.weg-item-open-sign { - transition-property: width, height, opacity, background-color, border-radius; - transition-duration: 0.2s; - transition-timing-function: linear; - border-radius: 4px; - - &.weg-item-open-sign-active { - --empty-rule: "delete me on use"; - } - - &.weg-item-open-sign-focused { - .vertical & { - height: 50%; - } - - .horizontal & { - width: 50%; - } - } -} - -.weg-context-menu-container { - padding: 6px; - - .menu-bg-layer-1 { - background-color: var(--color-gray-100); - border-radius: 10px; - } - - .weg-context-menu { - --empty-rule: "delete me on use"; - } -} - -.weg-item-preview-container { - padding: 10px; - border-radius: 10px; - - .preview-bg-layer-1 { - background-color: var(--color-gray-100); - border-radius: 10px; - } -} - -.weg-item-preview { - padding: 6px 10px 10px 10px; - border-radius: 10px; -} - -.weg-item-preview-topbar { - margin: 0 0 8px 0; -} - -.weg-item-preview-title { - font-size: 14px; - font-weight: 600; - color: var(--color-gray-900); -} - -.weg-item-preview-close { - --empty-rule: "delete me on use"; -} - -.weg-item-preview-image-container { - border-radius: 10px; - border: 1px solid var(--color-gray-300); -} - -.weg-item-preview-image { - --empty-rule: "delete me on use"; -} - -.weg-item-preview-spin { - --empty-rule: "delete me on use"; -} +.taskbar { + .taskbar-bg-layer-1 { + opacity: 0.3; + filter: saturate(0); + background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 250 250' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='10' numOctaves='3' stitchTiles='stitch '/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E"); + background-size: cover; + border-radius: 15px; + } + + .taskbar-bg-layer-2 { + opacity: 0.8; + background-color: var(--color-gray-100); + border-radius: 15px; + } +} + +.weg-separator { + .horizontal & { + &.weg-separator-1 { + border-left: 1px solid var(--color-gray-400); + } + &.weg-separator-2 { + border-right: 1px solid var(--color-gray-400); + } + } + + .vertical & { + &.weg-separator-1 { + border-top: 1px solid var(--color-gray-400); + } + &.weg-separator-2 { + border-bottom: 1px solid var(--color-gray-400); + } + } +} + +.weg-item { + .item-bg-layer-1 { + background-color: var(--color-gray-100); + border-radius: 25%; + box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5); + transition: background-color 0.2s ease-in-out; + } + + &:hover { + .item-bg-layer-1 { + background-color: var(--color-gray-400); + } + } + + &:active { + filter: brightness(0.4); + } + + &:not(:active) { + transition-property: filter; + transition-duration: 0.2s; + transition-timing-function: ease-in-out; + } +} + +.weg-item-icon { + width: 65%; + height: 65%; + filter: drop-shadow(0px 0px 1px #0000009a); + object-fit: contain; +} + +.weg-item-icon-start { + width: 100%; + height: 100%; + filter: brightness(1.2); + background: linear-gradient(150deg, var(--config-accent-color) 10%, #000 150%); + mask-image: url('data:image/svg+xml;charset=utf-8,'); + mask-repeat: no-repeat; + mask-size: contain; + mask-position: center; +} + +.weg-item-open-sign { + transition-property: width, height, opacity, background-color, border-radius; + transition-duration: 0.2s; + transition-timing-function: linear; + border-radius: 4px; + + &.weg-item-open-sign-active { + --empty-rule: "delete me on use"; + } + + &.weg-item-open-sign-focused { + .vertical & { + height: 50%; + } + + .horizontal & { + width: 50%; + } + } +} + +.weg-context-menu-container { + padding: 6px; + + .menu-bg-layer-1 { + background-color: var(--color-gray-100); + border-radius: 10px; + } + + .weg-context-menu { + --empty-rule: "delete me on use"; + } +} + +.weg-item-preview-container { + padding: 10px; + border-radius: 10px; + + .preview-bg-layer-1 { + background-color: var(--color-gray-100); + border-radius: 10px; + } +} + +.weg-item-preview { + padding: 6px 10px 10px 10px; + border-radius: 10px; +} + +.weg-item-preview-topbar { + margin: 0 0 8px 0; +} + +.weg-item-preview-title { + font-size: 14px; + font-weight: 600; + color: var(--color-gray-900); +} + +.weg-item-preview-close { + --empty-rule: "delete me on use"; +} + +.weg-item-preview-image-container { + border-radius: 10px; + border: 1px solid var(--color-gray-300); +} + +.weg-item-preview-image { + --empty-rule: "delete me on use"; +} + +.weg-item-preview-spin { + --empty-rule: "delete me on use"; +} diff --git a/static/themes/default/theme.wm.css b/static/themes/default/theme.wm.css index 6c7c8dca..01fddce4 100644 --- a/static/themes/default/theme.wm.css +++ b/static/themes/default/theme.wm.css @@ -1,28 +1,28 @@ -.wm-leaf { - &.wm-leaf-with-borders { - border-style: solid; - border-width: var(--config-border-width); - border-color: var(--config-accent-dark-color); - - &.wm-leaf-focused { - border-color: var(--config-accent-lighter-color); - } - } -} - -.wm-stack { - .wm-stack-bar { - background-color: #222222; - color: #fefefe; - - &.wm-stack-bar-with-borders { - border-style: solid; - border-width: var(--config-border-width); - border-color: var(--config-accent-dark-color); - } - } -} - -.wm-reserved { - background-color: var(--color-accent-lighter-color); -} +.wm-leaf { + &.wm-leaf-with-borders { + border-style: solid; + border-width: var(--config-border-width); + border-color: var(--config-accent-dark-color); + + &.wm-leaf-focused { + border-color: var(--config-accent-lighter-color); + } + } +} + +.wm-stack { + .wm-stack-bar { + background-color: #222222; + color: #fefefe; + + &.wm-stack-bar-with-borders { + border-style: solid; + border-width: var(--config-border-width); + border-color: var(--config-accent-dark-color); + } + } +} + +.wm-reserved { + background-color: var(--color-accent-lighter-color); +} diff --git a/static/themes/default/theme.yml b/static/themes/default/theme.yml index 01ce785f..72dcc5de 100644 --- a/static/themes/default/theme.yml +++ b/static/themes/default/theme.yml @@ -1,10 +1,10 @@ -info: - displayName: Default - author: eythaann - description: Default Seelen Theme - tags: ['weg', 'toolbar', 'window-manager'] -layers: - weg: - bg: 2 - toolbar: - bg: 2 +info: + displayName: Default + author: eythaann + description: Default Seelen Theme + tags: ['weg', 'toolbar', 'window-manager'] +layers: + weg: + bg: 2 + toolbar: + bg: 2 diff --git a/static/themes/rainbow.yml b/static/themes/rainbow.yml index a32851b5..db8d3fd6 100644 --- a/static/themes/rainbow.yml +++ b/static/themes/rainbow.yml @@ -1,35 +1,35 @@ -info: - displayName: Rainbow - author: eythaann - description: COLORS EVERYWHERE!!! - tags: ['weg'] -layers: - weg: - bg: 2 -styles: - weg: | - @keyframes rainbow { - to { - background-position: 0 -200%; - } - } - - .taskbar-bg-layer-2 { - opacity: 0.8; - background: linear-gradient( - rgba(255, 0, 0, 1) 0%, - rgba(255, 154, 0, 1) 10%, - rgba(208, 222, 33, 1) 20%, - rgba(79, 220, 74, 1) 30%, - rgba(63, 218, 216, 1) 40%, - rgba(47, 201, 226, 1) 50%, - rgba(28, 127, 238, 1) 60%, - rgba(95, 21, 242, 1) 70%, - rgba(186, 12, 248, 1) 80%, - rgba(251, 7, 217, 1) 90%, - rgba(255, 0, 0, 1) 100% - ) - 0 0/100% 200%; - animation: rainbow 2s linear infinite; - border-radius: 15px; +info: + displayName: Rainbow + author: eythaann + description: COLORS EVERYWHERE!!! + tags: ['weg'] +layers: + weg: + bg: 2 +styles: + weg: | + @keyframes rainbow { + to { + background-position: 0 -200%; + } + } + + .taskbar-bg-layer-2 { + opacity: 0.8; + background: linear-gradient( + rgba(255, 0, 0, 1) 0%, + rgba(255, 154, 0, 1) 10%, + rgba(208, 222, 33, 1) 20%, + rgba(79, 220, 74, 1) 30%, + rgba(63, 218, 216, 1) 40%, + rgba(47, 201, 226, 1) 50%, + rgba(28, 127, 238, 1) 60%, + rgba(95, 21, 242, 1) 70%, + rgba(186, 12, 248, 1) 80%, + rgba(251, 7, 217, 1) 90%, + rgba(255, 0, 0, 1) 100% + ) + 0 0/100% 200%; + animation: rainbow 2s linear infinite; + border-radius: 15px; } \ No newline at end of file diff --git a/tauri.conf.json b/tauri.conf.json index 047e22df..b001072c 100644 --- a/tauri.conf.json +++ b/tauri.conf.json @@ -1,88 +1,88 @@ -{ - "$schema": "node_modules/@tauri-apps/cli/schema.json", - "productName": "Seelen UI", - "identifier": "com.seelen.seelen-ui", - "version": "package.json", - "app": { - "security": { - "assetProtocol": { - "enable": true, - "scope": [ - "$RESOURCE/**/*", - "$TEMP/**/*", - "$DATA/**/*", - "**/*.jpg", - "**/*.jpeg", - "**/*.png", - "**/*.gif", - "**/*.bmp", - "**/*.tif", - "**/*.tiff" - ] - } - } - }, - "build": { - "beforeBuildCommand": "npm run build:ui", - "frontendDist": "dist", - "features": [] - }, - "bundle": { - "active": true, - "createUpdaterArtifacts": "v1Compatible", - "resources": [ - "static/**/*" - ], - "targets": [ - "nsis" - ], - "icon": [ - "static/icons/icon.ico" - ], - "windows": { - "certificateThumbprint": null, - "digestAlgorithm": "sha256", - "nsis": { - "installerIcon": "static/icons/icon.ico", - "sidebarImage": "static/icons/banner.bmp", - "template": "templates/installer.nsi", - "installMode": "perMachine", - "startMenuFolder": "Seelen" - } - }, - "publisher": "Seelen", - "category": "Utility", - "copyright": "Copyright © 2024", - "shortDescription": "Seelen UI", - "longDescription": "Seelen UI Fully Customizable Desktop Environment for Windows", - "licenseFile": "LICENSE", - "homepage": "https://github.com/eythaann/Seelen-UI", - "fileAssociations": [ - { - "ext": [ - ".slu" - ], - "name": "seelen-ui.file", - "description": "Seelen UI File", - "mimeType": "text/plain", - "role": "Viewer" - } - ] - }, - "plugins": { - "updater": { - "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDQ4QjU1RUI0NEM0NzBERUIKUldUckRVZE10RjYxU0lpaERvdklYL05DVlg0Sk9EVngvaEgzZjMvU1NNemJTZXZ1K0dNVXU3ZkQK", - "endpoints": [ - "https://github.com/eythaann/Seelen-UI/releases/latest/download/latest.json" - ] - }, - "deep-link": { - "mobile": [], - "desktop": { - "schemes": [ - "seelen-ui.uri" - ] - } - } - } +{ + "$schema": "node_modules/@tauri-apps/cli/schema.json", + "productName": "Seelen UI", + "identifier": "com.seelen.seelen-ui", + "version": "package.json", + "app": { + "security": { + "assetProtocol": { + "enable": true, + "scope": [ + "$RESOURCE/**/*", + "$TEMP/**/*", + "$DATA/**/*", + "**/*.jpg", + "**/*.jpeg", + "**/*.png", + "**/*.gif", + "**/*.bmp", + "**/*.tif", + "**/*.tiff" + ] + } + } + }, + "build": { + "beforeBuildCommand": "npm run build:ui", + "frontendDist": "dist", + "features": [] + }, + "bundle": { + "active": true, + "createUpdaterArtifacts": "v1Compatible", + "resources": [ + "static/**/*" + ], + "targets": [ + "nsis" + ], + "icon": [ + "static/icons/icon.ico" + ], + "windows": { + "certificateThumbprint": null, + "digestAlgorithm": "sha256", + "nsis": { + "installerIcon": "static/icons/icon.ico", + "sidebarImage": "static/icons/banner.bmp", + "template": "templates/installer.nsi", + "installMode": "perMachine", + "startMenuFolder": "Seelen" + } + }, + "publisher": "Seelen", + "category": "Utility", + "copyright": "Copyright © 2024", + "shortDescription": "Seelen UI", + "longDescription": "Seelen UI Fully Customizable Desktop Environment for Windows", + "licenseFile": "LICENSE", + "homepage": "https://github.com/eythaann/Seelen-UI", + "fileAssociations": [ + { + "ext": [ + ".slu" + ], + "name": "seelen-ui.file", + "description": "Seelen UI File", + "mimeType": "text/plain", + "role": "Viewer" + } + ] + }, + "plugins": { + "updater": { + "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDQ4QjU1RUI0NEM0NzBERUIKUldUckRVZE10RjYxU0lpaERvdklYL05DVlg0Sk9EVngvaEgzZjMvU1NNemJTZXZ1K0dNVXU3ZkQK", + "endpoints": [ + "https://github.com/eythaann/Seelen-UI/releases/latest/download/latest.json" + ] + }, + "deep-link": { + "mobile": [], + "desktop": { + "schemes": [ + "seelen-ui.uri" + ] + } + } + } } \ No newline at end of file diff --git a/templates/installer.nsi b/templates/installer.nsi index 1f29d2fe..cd7b111b 100644 --- a/templates/installer.nsi +++ b/templates/installer.nsi @@ -1,880 +1,880 @@ -Unicode true -ManifestDPIAware true -; Add in `dpiAwareness` `PerMonitorV2` to manifest for Windows 10 1607+ (note this should not affect lower versions since they should be able to ignore this and pick up `dpiAware` `true` set by `ManifestDPIAware true`) -; Currently undocumented on NSIS's website but is in the Docs folder of source tree, see -; https://github.com/kichik/nsis/blob/5fc0b87b819a9eec006df4967d08e522ddd651c9/Docs/src/attributes.but#L286-L300 -; https://github.com/tauri-apps/tauri/pull/10106 -ManifestDPIAwareness PerMonitorV2 - -!if "{{compression}}" == "none" - SetCompress off -!else - ; Set the compression algorithm. We default to LZMA. - SetCompressor /SOLID "{{compression}}" -!endif - -!include MUI2.nsh -!include FileFunc.nsh -!include x64.nsh -!include WordFunc.nsh -!include "utils.nsh" -!include "FileAssociation.nsh" -!include "Win\COM.nsh" -!include "Win\Propkey.nsh" -!include "StrFunc.nsh" -${StrCase} -${StrLoc} - -{{#if installer_hooks}} -!include "{{installer_hooks}}" -{{/if}} - -!define MANUFACTURER "{{manufacturer}}" -!define PRODUCTNAME "{{product_name}}" -!define VERSION "{{version}}" -!define VERSIONWITHBUILD "{{version_with_build}}" -!define SHORTDESCRIPTION "{{short_description}}" -!define HOMEPAGE "{{homepage}}" -!define INSTALLMODE "{{install_mode}}" -!define LICENSE "{{license}}" -!define INSTALLERICON "{{installer_icon}}" -!define SIDEBARIMAGE "{{sidebar_image}}" -!define HEADERIMAGE "{{header_image}}" -!define MAINBINARYNAME "{{main_binary_name}}" -!define MAINBINARYSRCPATH "{{main_binary_path}}" -!define BUNDLEID "{{bundle_id}}" -!define COPYRIGHT "{{copyright}}" -!define OUTFILE "{{out_file}}" -!define ARCH "{{arch}}" -!define PLUGINSPATH "{{additional_plugins_path}}" -!define ALLOWDOWNGRADES "{{allow_downgrades}}" -!define DISPLAYLANGUAGESELECTOR "{{display_language_selector}}" -!define INSTALLWEBVIEW2MODE "{{install_webview2_mode}}" -!define WEBVIEW2INSTALLERARGS "{{webview2_installer_args}}" -!define WEBVIEW2BOOTSTRAPPERPATH "{{webview2_bootstrapper_path}}" -!define WEBVIEW2INSTALLERPATH "{{webview2_installer_path}}" -!define UNINSTKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCTNAME}" -!define APPPATHKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\${MAINBINARYNAME}.exe" -!define MANUPRODUCTKEY "Software\${MANUFACTURER}\${PRODUCTNAME}" -!define UNINSTALLERSIGNCOMMAND "{{uninstaller_sign_cmd}}" -!define ESTIMATEDSIZE "{{estimated_size}}" -!define STARTMENUFOLDER "{{start_menu_folder}}" - -Var PassiveMode -Var UpdateMode -Var NoShortcutMode - -Name "${PRODUCTNAME}" -BrandingText "${COPYRIGHT}" -OutFile "${OUTFILE}" - -; We don't actually use this value as default install path, -; it's just for nsis to append the product name folder in the directory selector -; https://nsis.sourceforge.io/Reference/InstallDir -!define PLACEHOLDER_INSTALL_DIR "placeholder\${MANUFACTURER}\${PRODUCTNAME}" -InstallDir "${PLACEHOLDER_INSTALL_DIR}" - -VIProductVersion "${VERSIONWITHBUILD}" -VIAddVersionKey "ProductName" "${PRODUCTNAME}" -VIAddVersionKey "FileDescription" "${SHORTDESCRIPTION}" -VIAddVersionKey "LegalCopyright" "${COPYRIGHT}" -VIAddVersionKey "FileVersion" "${VERSION}" -VIAddVersionKey "ProductVersion" "${VERSION}" - -; Plugins path, currently exists for linux only -!if "${PLUGINSPATH}" != "" - !addplugindir "${PLUGINSPATH}" -!endif - -; Uninstaller signing command -!if "${UNINSTALLERSIGNCOMMAND}" != "" - !uninstfinalize '${UNINSTALLERSIGNCOMMAND}' -!endif - -; Handle install mode, `perUser`, `perMachine` or `both` -!if "${INSTALLMODE}" == "perMachine" - RequestExecutionLevel highest -!endif - -!if "${INSTALLMODE}" == "currentUser" - RequestExecutionLevel user -!endif - -!if "${INSTALLMODE}" == "both" - !define MULTIUSER_MUI - !define MULTIUSER_INSTALLMODE_INSTDIR "${MANUFACTURER}\${PRODUCTNAME}" - !define MULTIUSER_INSTALLMODE_COMMANDLINE - !if "${ARCH}" == "x64" - !define MULTIUSER_USE_PROGRAMFILES64 - !else if "${ARCH}" == "arm64" - !define MULTIUSER_USE_PROGRAMFILES64 - !endif - !define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "${UNINSTKEY}" - !define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME "CurrentUser" - !define MULTIUSER_INSTALLMODEPAGE_SHOWUSERNAME - !define MULTIUSER_INSTALLMODE_FUNCTION RestorePreviousInstallLocation - !define MULTIUSER_EXECUTIONLEVEL Highest - !include MultiUser.nsh -!endif - -; Installer & Unistaller icon -!if "${INSTALLERICON}" != "" - !define MUI_ICON "${INSTALLERICON}" - !define MUI_UNICON "${INSTALLERICON}" -!endif - -; Installer sidebar image -!if "${SIDEBARIMAGE}" != "" - !define MUI_WELCOMEFINISHPAGE_BITMAP "${SIDEBARIMAGE}" -!endif - -; Installer header image -!if "${HEADERIMAGE}" != "" - !define MUI_HEADERIMAGE - !define MUI_HEADERIMAGE_BITMAP "${HEADERIMAGE}" -!endif - -; Define registry key to store installer language -!define MUI_LANGDLL_REGISTRY_ROOT "HKCU" -!define MUI_LANGDLL_REGISTRY_KEY "${MANUPRODUCTKEY}" -!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language" - -; =============================================================================================== -; ====================================== INSTALLER PAGES ======================================== -; =============================================================================================== -!define MUI_BGCOLOR 222228 -!define MUI_TEXTCOLOR fdfdfd -!define MUI_FINISHPAGE_TEXT_COLOR fdfdfd - -; 1. Welcome Page -!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive -!insertmacro MUI_PAGE_WELCOME - -; 2. License Page (if defined) -!if "${LICENSE}" != "" - !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive - !insertmacro MUI_PAGE_LICENSE "${LICENSE}" -!endif - -; 3. Install mode (if it is set to `both`) -!if "${INSTALLMODE}" == "both" - !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive - !insertmacro MULTIUSER_PAGE_INSTALLMODE -!endif - -; 4. Custom page to ask user if he wants to reinstall/uninstall -; only if a previous installation was detected -Var ReinstallPageCheck -Page custom PageReinstall PageLeaveReinstall -Function PageReinstall - ; Uninstall previous WiX installation if exists. - ; - ; A WiX installer stores the installation info in registry - ; using a UUID and so we have to loop through all keys under - ; `HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall` - ; and check if `DisplayName` and `Publisher` keys match ${PRODUCTNAME} and ${MANUFACTURER} - ; - ; This has a potential issue that there maybe another installation that matches - ; our ${PRODUCTNAME} and ${MANUFACTURER} but wasn't installed by our WiX installer, - ; however, this should be fine since the user will have to confirm the uninstallation - ; and they can chose to abort it if doesn't make sense. - StrCpy $0 0 - wix_loop: - EnumRegKey $1 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" $0 - StrCmp $1 "" wix_done ; Exit loop if there is no more keys to loop on - IntOp $0 $0 + 1 - ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "DisplayName" - ReadRegStr $R1 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "Publisher" - StrCmp "$R0$R1" "${PRODUCTNAME}${MANUFACTURER}" 0 wix_loop - ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "UninstallString" - ${StrCase} $R1 $R0 "L" - ${StrLoc} $R0 $R1 "msiexec" ">" - StrCmp $R0 0 0 wix_done - StrCpy $R7 "wix" - StrCpy $R6 "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" - Goto compare_version - wix_done: - - ; Check if there is an existing installation, if not, abort the reinstall page - ReadRegStr $R0 SHCTX "${UNINSTKEY}" "" - ReadRegStr $R1 SHCTX "${UNINSTKEY}" "UninstallString" - ${IfThen} "$R0$R1" == "" ${|} Abort ${|} - - ; Compare this installar version with the existing installation - ; and modify the messages presented to the user accordingly - compare_version: - StrCpy $R4 "$(older)" - ${If} $R7 == "wix" - ReadRegStr $R0 HKLM "$R6" "DisplayVersion" - ${Else} - ReadRegStr $R0 SHCTX "${UNINSTKEY}" "DisplayVersion" - ${EndIf} - ${IfThen} $R0 == "" ${|} StrCpy $R4 "$(unknown)" ${|} - - nsis_tauri_utils::SemverCompare "${VERSION}" $R0 - Pop $R0 - ; Reinstalling the same version - ${If} $R0 = 0 - StrCpy $R1 "$(alreadyInstalledLong)" - StrCpy $R2 "$(addOrReinstall)" - StrCpy $R3 "$(uninstallApp)" - !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(chooseMaintenanceOption)" - StrCpy $R5 "2" - ; Upgrading - ${ElseIf} $R0 = 1 - StrCpy $R1 "$(olderOrUnknownVersionInstalled)" - StrCpy $R2 "$(uninstallBeforeInstalling)" - StrCpy $R3 "$(dontUninstall)" - !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(choowHowToInstall)" - StrCpy $R5 "1" - ; Downgrading - ${ElseIf} $R0 = -1 - StrCpy $R1 "$(newerVersionInstalled)" - StrCpy $R2 "$(uninstallBeforeInstalling)" - !if "${ALLOWDOWNGRADES}" == "true" - StrCpy $R3 "$(dontUninstall)" - !else - StrCpy $R3 "$(dontUninstallDowngrade)" - !endif - !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(choowHowToInstall)" - StrCpy $R5 "1" - ${Else} - Abort - ${EndIf} - - ; Skip showing the page if passive - ; - ; Note that we don't call this earlier at the begining - ; of this function because we need to populate some variables - ; related to current installed version if detected and whether - ; we are downgrading or not. - Call SkipIfPassive - - nsDialogs::Create 1018 - Pop $R4 - ${IfThen} $(^RTL) = 1 ${|} nsDialogs::SetRTL $(^RTL) ${|} - - ${NSD_CreateLabel} 0 0 100% 24u $R1 - Pop $R1 - - ${NSD_CreateRadioButton} 30u 50u -30u 8u $R2 - Pop $R2 - ${NSD_OnClick} $R2 PageReinstallUpdateSelection - - ${NSD_CreateRadioButton} 30u 70u -30u 8u $R3 - Pop $R3 - ; Disable this radio button if downgrading and downgrades are disabled - !if "${ALLOWDOWNGRADES}" == "false" - ${IfThen} $R0 = -1 ${|} EnableWindow $R3 0 ${|} - !endif - ${NSD_OnClick} $R3 PageReinstallUpdateSelection - - ; Check the first radio button if this the first time - ; we enter this page or if the second button wasn't - ; selected the last time we were on this page - ${If} $ReinstallPageCheck <> 2 - SendMessage $R2 ${BM_SETCHECK} ${BST_CHECKED} 0 - ${Else} - SendMessage $R3 ${BM_SETCHECK} ${BST_CHECKED} 0 - ${EndIf} - - ${NSD_SetFocus} $R2 - nsDialogs::Show -FunctionEnd -Function PageReinstallUpdateSelection - ${NSD_GetState} $R2 $R1 - ${If} $R1 == ${BST_CHECKED} - StrCpy $ReinstallPageCheck 1 - ${Else} - StrCpy $ReinstallPageCheck 2 - ${EndIf} -FunctionEnd -Function PageLeaveReinstall - ${NSD_GetState} $R2 $R1 - - ; $R5 holds whether we are reinstalling the same version or not - ; $R5 == "1" -> different versions - ; $R5 == "2" -> same version - ; - ; $R1 holds the radio buttons state. its meaning is dependent on the context - StrCmp $R5 "1" 0 +2 ; Existing install is not the same version? - StrCmp $R1 "1" reinst_uninstall reinst_done ; $R1 == "1", then user chose to uninstall existing version, otherwise skip uninstalling - StrCmp $R1 "1" reinst_done ; Same version? skip uninstalling - - reinst_uninstall: - HideWindow - ClearErrors - - ${If} $R7 == "wix" - ReadRegStr $R1 HKLM "$R6" "UninstallString" - ExecWait '$R1' $0 - ${Else} - ReadRegStr $4 SHCTX "${MANUPRODUCTKEY}" "" - ReadRegStr $R1 SHCTX "${UNINSTKEY}" "UninstallString" - ${If} $UpdateMode = 1 - ExecWait '$R1 /UPDATE /P _?=$4' $0 - ${Else} - ExecWait '$R1 /P _?=$4' $0 - ${EndIf} - ${EndIf} - - BringToFront - - ${IfThen} ${Errors} ${|} StrCpy $0 2 ${|} ; ExecWait failed, set fake exit code - - ${If} $0 <> 0 - ${OrIf} ${FileExists} "$INSTDIR\${MAINBINARYNAME}.exe" - ${If} $0 = 1 ; User aborted uninstaller? - StrCmp $R5 "2" 0 +2 ; Is the existing install the same version? - Quit ; ...yes, already installed, we are done - Abort - ${EndIf} - MessageBox MB_ICONEXCLAMATION "$(unableToUninstall)" - Abort - ${Else} - StrCpy $0 $R1 1 - ${IfThen} $0 == '"' ${|} StrCpy $R1 $R1 -1 1 ${|} ; Strip quotes from UninstallString - Delete $R1 - RMDir $INSTDIR - ${EndIf} - reinst_done: -FunctionEnd - -; 5. Choose install directory page -!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive -!insertmacro MUI_PAGE_DIRECTORY - -; 6. Start menu shortcut page -Var AppStartMenuFolder -!if "${STARTMENUFOLDER}" != "" - !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive - !define MUI_STARTMENUPAGE_DEFAULTFOLDER "${STARTMENUFOLDER}" -!else - !define MUI_PAGE_CUSTOMFUNCTION_PRE Skip -!endif -!insertmacro MUI_PAGE_STARTMENU Application $AppStartMenuFolder - -; 7. Installation page -!insertmacro MUI_PAGE_INSTFILES - -; 8. Finish page -; -; Don't auto jump to finish page after installation page, -; because the installation page has useful info that can be used debug any issues with the installer. -!define MUI_FINISHPAGE_NOAUTOCLOSE -; Show sponsor link -!define MUI_FINISHPAGE_LINK_COLOR 59a7f6 -!define MUI_FINISHPAGE_LINK "Join us on Discord! 🤍" -!define MUI_FINISHPAGE_LINK_LOCATION "https://discord.gg/ABfASx5ZAJ" - -Function RunMainBinary - Exec '"$INSTDIR\${MAINBINARYNAME}.exe"' -FunctionEnd - -!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive -!define MUI_PAGE_CUSTOMFUNCTION_LEAVE RunMainBinary -!insertmacro MUI_PAGE_FINISH - -; Uninstaller Pages -; 1. Confirm uninstall page -Var DeleteAppDataCheckbox -Var DeleteAppDataCheckboxState -!define /ifndef WS_EX_LAYOUTRTL 0x00400000 -!define MUI_PAGE_CUSTOMFUNCTION_SHOW un.ConfirmShow -Function un.ConfirmShow ; Add add a `Delete app data` check box - ; $1 inner dialog HWND - ; $2 window DPI - ; $3 style - ; $4 x - ; $5 y - ; $6 width - ; $7 height - FindWindow $1 "#32770" "" $HWNDPARENT ; Find inner dialog - System::Call "user32::GetDpiForWindow(p r1) i .r2" - ${If} $(^RTL) = 1 - StrCpy $3 "${__NSD_CheckBox_EXSTYLE} | ${WS_EX_LAYOUTRTL}" - IntOp $4 50 * $2 - ${Else} - StrCpy $3 "${__NSD_CheckBox_EXSTYLE}" - IntOp $4 0 * $2 - ${EndIf} - IntOp $5 100 * $2 - IntOp $6 400 * $2 - IntOp $7 25 * $2 - IntOp $4 $4 / 96 - IntOp $5 $5 / 96 - IntOp $6 $6 / 96 - IntOp $7 $7 / 96 - System::Call 'user32::CreateWindowEx(i r3, w "${__NSD_CheckBox_CLASS}", w "$(deleteAppData)", i ${__NSD_CheckBox_STYLE}, i r4, i r5, i r6, i r7, p r1, i0, i0, i0) i .s' - Pop $DeleteAppDataCheckbox - SendMessage $HWNDPARENT ${WM_GETFONT} 0 0 $1 - SendMessage $DeleteAppDataCheckbox ${WM_SETFONT} $1 1 -FunctionEnd -!define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.ConfirmLeave -Function un.ConfirmLeave - SendMessage $DeleteAppDataCheckbox ${BM_GETCHECK} 0 0 $DeleteAppDataCheckboxState -FunctionEnd -!insertmacro MUI_UNPAGE_CONFIRM - -; 2. Uninstalling Page -!insertmacro MUI_UNPAGE_INSTFILES - -;Languages -{{#each languages}} -!insertmacro MUI_LANGUAGE "{{this}}" -{{/each}} -!insertmacro MUI_RESERVEFILE_LANGDLL -{{#each language_files}} - !include "{{this}}" -{{/each}} - -Function .onInit - ${GetOptions} $CMDLINE "/P" $PassiveMode - ${IfNot} ${Errors} - StrCpy $PassiveMode 1 - ${EndIf} - - ${GetOptions} $CMDLINE "/NS" $NoShortcutMode - ${IfNot} ${Errors} - StrCpy $NoShortcutMode 1 - ${EndIf} - - ${GetOptions} $CMDLINE "/UPDATE" $UpdateMode - ${IfNot} ${Errors} - StrCpy $UpdateMode 1 - ${EndIf} - - !if "${DISPLAYLANGUAGESELECTOR}" == "true" - !insertmacro MUI_LANGDLL_DISPLAY - !endif - - !insertmacro SetContext - - ${If} $INSTDIR == "${PLACEHOLDER_INSTALL_DIR}" - ; Set default install location - !if "${INSTALLMODE}" == "perMachine" - ${If} ${RunningX64} - !if "${ARCH}" == "x64" - StrCpy $INSTDIR "$PROGRAMFILES64\${MANUFACTURER}\${PRODUCTNAME}" - !else if "${ARCH}" == "arm64" - StrCpy $INSTDIR "$PROGRAMFILES64\${MANUFACTURER}\${PRODUCTNAME}" - !else - StrCpy $INSTDIR "$PROGRAMFILES\${MANUFACTURER}\${PRODUCTNAME}" - !endif - ${Else} - StrCpy $INSTDIR "$PROGRAMFILES\${MANUFACTURER}\${PRODUCTNAME}" - ${EndIf} - !else if "${INSTALLMODE}" == "currentUser" - StrCpy $INSTDIR "$LOCALAPPDATA\${MANUFACTURER}\${PRODUCTNAME}" - !endif - - Call RestorePreviousInstallLocation - ${EndIf} - - - !if "${INSTALLMODE}" == "both" - !insertmacro MULTIUSER_INIT - !endif -FunctionEnd - - -Section EarlyChecks - ; Abort silent installer if downgrades is disabled - !if "${ALLOWDOWNGRADES}" == "false" - ${If} ${Silent} - ; If downgrading - ${If} $R0 = -1 - System::Call 'kernel32::AttachConsole(i -1)i.r0' - ${If} $0 <> 0 - System::Call 'kernel32::GetStdHandle(i -11)i.r0' - System::call 'kernel32::SetConsoleTextAttribute(i r0, i 0x0004)' ; set red color - FileWrite $0 "$(silentDowngrades)" - ${EndIf} - Abort - ${EndIf} - ${EndIf} - !endif - -SectionEnd - -Section WebView2 - ; Check if Webview2 is already installed and skip this section - ${If} ${RunningX64} - ReadRegStr $4 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" - ${Else} - ReadRegStr $4 HKLM "SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" - ${EndIf} - ReadRegStr $5 HKCU "SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" - - StrCmp $4 "" 0 webview2_done - StrCmp $5 "" 0 webview2_done - - ; Webview2 installation - ; - ; Skip if updating - ${If} $UpdateMode <> 1 - !if "${INSTALLWEBVIEW2MODE}" == "downloadBootstrapper" - Delete "$TEMP\MicrosoftEdgeWebview2Setup.exe" - DetailPrint "$(webview2Downloading)" - NSISdl::download "https://go.microsoft.com/fwlink/p/?LinkId=2124703" "$TEMP\MicrosoftEdgeWebview2Setup.exe" - Pop $0 - ${If} $0 = 0 - DetailPrint "$(webview2DownloadSuccess)" - ${Else} - DetailPrint "$(webview2DownloadError)" - Abort "$(webview2AbortError)" - ${EndIf} - StrCpy $6 "$TEMP\MicrosoftEdgeWebview2Setup.exe" - Goto install_webview2 - !endif - - !if "${INSTALLWEBVIEW2MODE}" == "embedBootstrapper" - Delete "$TEMP\MicrosoftEdgeWebview2Setup.exe" - File "/oname=$TEMP\MicrosoftEdgeWebview2Setup.exe" "${WEBVIEW2BOOTSTRAPPERPATH}" - DetailPrint "$(installingWebview2)" - StrCpy $6 "$TEMP\MicrosoftEdgeWebview2Setup.exe" - Goto install_webview2 - !endif - - !if "${INSTALLWEBVIEW2MODE}" == "offlineInstaller" - Delete "$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe" - File "/oname=$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe" "${WEBVIEW2INSTALLERPATH}" - DetailPrint "$(installingWebview2)" - StrCpy $6 "$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe" - Goto install_webview2 - !endif - - Goto webview2_done - - install_webview2: - DetailPrint "$(installingWebview2)" - ; $6 holds the path to the webview2 installer - ExecWait "$6 ${WEBVIEW2INSTALLERARGS} /install" $1 - ${If} $1 = 0 - DetailPrint "$(webview2InstallSuccess)" - ${Else} - DetailPrint "$(webview2InstallError)" - Abort "$(webview2AbortError)" - ${EndIf} - webview2_done: - ${EndIf} -SectionEnd - -Section Install - SetOutPath $INSTDIR - - !ifmacrodef NSIS_HOOK_PREINSTALL - !insertmacro NSIS_HOOK_PREINSTALL - !endif - - !insertmacro CheckIfAppIsRunning - - ; Copy main executable - File "${MAINBINARYSRCPATH}" - - ; Copy resources - {{#each resources_dirs}} - CreateDirectory "$INSTDIR\\{{this}}" - {{/each}} - {{#each resources}} - File /a "/oname={{this.[1]}}" "{{@key}}" - {{/each}} - - ; Copy external binaries - {{#each binaries}} - File /a "/oname={{this}}" "{{@key}}" - {{/each}} - - ; Create file associations - {{#each file_associations as |association| ~}} - {{#each association.ext as |ext| ~}} - !insertmacro APP_ASSOCIATE "{{ext}}" "{{or association.name ext}}" "{{association-description association.description ext}}" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\",0" "Open with ${PRODUCTNAME}" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\" $\"%1$\"" - {{/each}} - {{/each}} - - ; Register deep links - {{#each deep_link_protocols as |protocol| ~}} - WriteRegStr SHCTX "Software\Classes\\{{protocol}}" "URL Protocol" "" - WriteRegStr SHCTX "Software\Classes\\{{protocol}}" "" "URL:${BUNDLEID} protocol" - WriteRegStr SHCTX "Software\Classes\\{{protocol}}\DefaultIcon" "" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\",0" - WriteRegStr SHCTX "Software\Classes\\{{protocol}}\shell\open\command" "" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\" $\"%1$\"" - {{/each}} - - ; Refresh file associations icons - !insertmacro UPDATEFILEASSOC - - ; Create uninstaller - WriteUninstaller "$INSTDIR\uninstall.exe" - - ; Save $INSTDIR in registry for future installations - WriteRegStr SHCTX "${MANUPRODUCTKEY}" "" $INSTDIR - - !if "${INSTALLMODE}" == "both" - ; Save install mode to be selected by default for the next installation such as updating - ; or when uninstalling - WriteRegStr SHCTX "${UNINSTKEY}" $MultiUser.InstallMode 1 - !endif - - ; Registry information for add/remove programs - WriteRegStr SHCTX "${UNINSTKEY}" "DisplayName" "${PRODUCTNAME}" - WriteRegStr SHCTX "${UNINSTKEY}" "DisplayIcon" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\"" - WriteRegStr SHCTX "${UNINSTKEY}" "DisplayVersion" "${VERSION}" - WriteRegStr SHCTX "${UNINSTKEY}" "Publisher" "${MANUFACTURER}" - WriteRegStr SHCTX "${UNINSTKEY}" "InstallLocation" "$\"$INSTDIR$\"" - WriteRegStr SHCTX "${UNINSTKEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" - WriteRegDWORD SHCTX "${UNINSTKEY}" "NoModify" "1" - WriteRegDWORD SHCTX "${UNINSTKEY}" "NoRepair" "1" - - ${GetSize} "$INSTDIR" "/M=uninstall.exe /S=0K /G=0" $0 $1 $2 - IntOp $0 $0 + ${ESTIMATEDSIZE} - IntFmt $0 "0x%08X" $0 - WriteRegDWORD SHCTX "${UNINSTKEY}" "EstimatedSize" "$0" - - !if "${HOMEPAGE}" != "" - WriteRegStr SHCTX "${UNINSTKEY}" "URLInfoAbout" "${HOMEPAGE}" - WriteRegStr SHCTX "${UNINSTKEY}" "URLUpdateInfo" "${HOMEPAGE}" - WriteRegStr SHCTX "${UNINSTKEY}" "HelpLink" "${HOMEPAGE}" - !endif - - ; Register Main Binary path to Apps Paths - WriteRegStr SHCTX "${APPPATHKEY}" "" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\"" - WriteRegStr SHCTX "${APPPATHKEY}" "Path" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\"" - - ; Create start menu shortcut - !insertmacro MUI_STARTMENU_WRITE_BEGIN Application - Call CreateOrUpdateStartMenuShortcut - !insertmacro MUI_STARTMENU_WRITE_END - - ; Create desktop shortcut and run Executable for silent and passive installers - ; because finish page will be skipped - ${If} $PassiveMode = 1 - ${OrIf} ${Silent} - Call CreateOrUpdateDesktopShortcut - Call RunMainBinary - ${EndIf} - - !ifmacrodef NSIS_HOOK_POSTINSTALL - !insertmacro NSIS_HOOK_POSTINSTALL - !endif - - ; Auto close this page for passive mode - ${If} $PassiveMode = 1 - SetAutoClose true - ${EndIf} -SectionEnd - -Function .onInstSuccess - ; Check for `/R` flag only in silent and passive installers because - ; GUI installer has a toggle for the user to (re)start the app - ${If} $PassiveMode = 1 - ${OrIf} ${Silent} - ${GetOptions} $CMDLINE "/R" $R0 - ${IfNot} ${Errors} - ${GetOptions} $CMDLINE "/ARGS" $R0 - nsis_tauri_utils::RunAsUser "$INSTDIR\${MAINBINARYNAME}.exe" "$R0" - ${EndIf} - ${EndIf} -FunctionEnd - -Function un.onInit - !insertmacro SetContext - - !if "${INSTALLMODE}" == "both" - !insertmacro MULTIUSER_UNINIT - !endif - - !insertmacro MUI_UNGETLANGUAGE - - ${GetOptions} $CMDLINE "/P" $PassiveMode - ${IfNot} ${Errors} - StrCpy $PassiveMode 1 - ${EndIf} - - ${GetOptions} $CMDLINE "/UPDATE" $UpdateMode - ${IfNot} ${Errors} - StrCpy $UpdateMode 1 - ${EndIf} -FunctionEnd - -Section Uninstall - - !ifmacrodef NSIS_HOOK_PREUNINSTALL - !insertmacro NSIS_HOOK_PREUNINSTALL - !endif - - !insertmacro CheckIfAppIsRunning - - ; Delete the app directory and its content from disk - ; Copy main executable - Delete "$INSTDIR\${MAINBINARYNAME}.exe" - - ; Delete resources - {{#each resources}} - Delete "$INSTDIR\\{{this.[1]}}" - {{/each}} - - ; Delete external binaries - {{#each binaries}} - Delete "$INSTDIR\\{{this}}" - {{/each}} - - ; Delete app associations - {{#each file_associations as |association| ~}} - {{#each association.ext as |ext| ~}} - !insertmacro APP_UNASSOCIATE "{{ext}}" "{{or association.name ext}}" - {{/each}} - {{/each}} - - ; Delete deep links - {{#each deep_link_protocols as |protocol| ~}} - ReadRegStr $R7 SHCTX "Software\Classes\\{{protocol}}\shell\open\command" "" - ${If} $R7 == "$\"$INSTDIR\${MAINBINARYNAME}.exe$\" $\"%1$\"" - DeleteRegKey SHCTX "Software\Classes\\{{protocol}}" - ${EndIf} - {{/each}} - - ; Refresh file associations icons - !insertmacro UPDATEFILEASSOC - - ; Delete uninstaller - Delete "$INSTDIR\uninstall.exe" - - {{#each resources_ancestors}} - RMDir /REBOOTOK "$INSTDIR\\{{this}}" - {{/each}} - RMDir "$INSTDIR" - - ; Remove shortcuts if not updating - ${If} $UpdateMode <> 1 - !insertmacro DeleteAppUserModelId - - ; Remove start menu shortcut - !insertmacro MUI_STARTMENU_GETFOLDER Application $AppStartMenuFolder - !insertmacro IsShortcutTarget "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - Pop $0 - ${If} $0 = 1 - !insertmacro UnpinShortcut "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" - Delete "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" - RMDir "$SMPROGRAMS\$AppStartMenuFolder" - ${EndIf} - !insertmacro IsShortcutTarget "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - Pop $0 - ${If} $0 = 1 - !insertmacro UnpinShortcut "$SMPROGRAMS\${PRODUCTNAME}.lnk" - Delete "$SMPROGRAMS\${PRODUCTNAME}.lnk" - ${EndIf} - - ; Remove desktop shortcuts - !insertmacro IsShortcutTarget "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - Pop $0 - ${If} $0 = 1 - !insertmacro UnpinShortcut "$DESKTOP\${PRODUCTNAME}.lnk" - Delete "$DESKTOP\${PRODUCTNAME}.lnk" - ${EndIf} - ${EndIf} - - ; Remove registry information for add/remove programs - !if "${INSTALLMODE}" == "both" - DeleteRegKey SHCTX "${UNINSTKEY}" - DeleteRegKey SHCTX "${APPPATHKEY}" - !else if "${INSTALLMODE}" == "perMachine" - DeleteRegKey HKLM "${UNINSTKEY}" - DeleteRegKey HKLM "${APPPATHKEY}" - !else - DeleteRegKey HKCU "${UNINSTKEY}" - DeleteRegKey HKCU "${APPPATHKEY}" - !endif - - DeleteRegValue HKCU "${MANUPRODUCTKEY}" "Installer Language" - - ; Delete app data if the checkbox is selected - ; and if not updating - ${If} $DeleteAppDataCheckboxState = 1 - ${AndIf} $UpdateMode <> 1 - SetShellVarContext current - RmDir /r "$APPDATA\${BUNDLEID}" - RmDir /r "$LOCALAPPDATA\${BUNDLEID}" - ${EndIf} - - !ifmacrodef NSIS_HOOK_POSTUNINSTALL - !insertmacro NSIS_HOOK_POSTUNINSTALL - !endif - - ; Auto close if passive mode - ${If} $PassiveMode = 1 - SetAutoClose true - ${EndIf} -SectionEnd - -Function RestorePreviousInstallLocation - ReadRegStr $4 SHCTX "${MANUPRODUCTKEY}" "" - StrCmp $4 "" +2 0 - StrCpy $INSTDIR $4 -FunctionEnd - -Function Skip - Abort -FunctionEnd - -Function SkipIfPassive - ${IfThen} $PassiveMode = 1 ${|} Abort ${|} -FunctionEnd - -Function CreateOrUpdateStartMenuShortcut - ; We used to use product name as MAINBINARYNAME - ; migrate old shortcuts to target the new MAINBINARYNAME - StrCpy $R0 0 - - !insertmacro IsShortcutTarget "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCTNAME}.exe" - Pop $0 - ${If} $0 = 1 - !insertmacro SetShortcutTarget "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - StrCpy $R0 1 - ${EndIf} - - !insertmacro IsShortcutTarget "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCTNAME}.exe" - Pop $0 - ${If} $0 = 1 - !insertmacro SetShortcutTarget "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - StrCpy $R0 1 - ${EndIf} - - ${If} $R0 = 1 - Return - ${EndIf} - - ; Skip creating shortcut if in update mode or no shortcut mode - ${If} $UpdateMode = 1 - ${OrIf} $NoShortcutMode = 1 - Return - ${EndIf} - - !if "${STARTMENUFOLDER}" != "" - CreateDirectory "$SMPROGRAMS\$AppStartMenuFolder" - CreateShortcut "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - !insertmacro SetLnkAppUserModelId "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" - !else - CreateShortcut "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - !insertmacro SetLnkAppUserModelId "$SMPROGRAMS\${PRODUCTNAME}.lnk" - !endif -FunctionEnd - -Function CreateOrUpdateDesktopShortcut - ; We used to use product name as MAINBINARYNAME - ; migrate old shortcuts to target the new MAINBINARYNAME - !insertmacro IsShortcutTarget "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCTNAME}.exe" - Pop $0 - ${If} $0 = 1 - !insertmacro SetShortcutTarget "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - Return - ${EndIf} - - ; Skip creating shortcut if in update mode or no shortcut mode - ${If} $UpdateMode = 1 - ${OrIf} $NoShortcutMode = 1 - Return - ${EndIf} - - CreateShortcut "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - !insertmacro SetLnkAppUserModelId "$DESKTOP\${PRODUCTNAME}.lnk" +Unicode true +ManifestDPIAware true +; Add in `dpiAwareness` `PerMonitorV2` to manifest for Windows 10 1607+ (note this should not affect lower versions since they should be able to ignore this and pick up `dpiAware` `true` set by `ManifestDPIAware true`) +; Currently undocumented on NSIS's website but is in the Docs folder of source tree, see +; https://github.com/kichik/nsis/blob/5fc0b87b819a9eec006df4967d08e522ddd651c9/Docs/src/attributes.but#L286-L300 +; https://github.com/tauri-apps/tauri/pull/10106 +ManifestDPIAwareness PerMonitorV2 + +!if "{{compression}}" == "none" + SetCompress off +!else + ; Set the compression algorithm. We default to LZMA. + SetCompressor /SOLID "{{compression}}" +!endif + +!include MUI2.nsh +!include FileFunc.nsh +!include x64.nsh +!include WordFunc.nsh +!include "utils.nsh" +!include "FileAssociation.nsh" +!include "Win\COM.nsh" +!include "Win\Propkey.nsh" +!include "StrFunc.nsh" +${StrCase} +${StrLoc} + +{{#if installer_hooks}} +!include "{{installer_hooks}}" +{{/if}} + +!define MANUFACTURER "{{manufacturer}}" +!define PRODUCTNAME "{{product_name}}" +!define VERSION "{{version}}" +!define VERSIONWITHBUILD "{{version_with_build}}" +!define SHORTDESCRIPTION "{{short_description}}" +!define HOMEPAGE "{{homepage}}" +!define INSTALLMODE "{{install_mode}}" +!define LICENSE "{{license}}" +!define INSTALLERICON "{{installer_icon}}" +!define SIDEBARIMAGE "{{sidebar_image}}" +!define HEADERIMAGE "{{header_image}}" +!define MAINBINARYNAME "{{main_binary_name}}" +!define MAINBINARYSRCPATH "{{main_binary_path}}" +!define BUNDLEID "{{bundle_id}}" +!define COPYRIGHT "{{copyright}}" +!define OUTFILE "{{out_file}}" +!define ARCH "{{arch}}" +!define PLUGINSPATH "{{additional_plugins_path}}" +!define ALLOWDOWNGRADES "{{allow_downgrades}}" +!define DISPLAYLANGUAGESELECTOR "{{display_language_selector}}" +!define INSTALLWEBVIEW2MODE "{{install_webview2_mode}}" +!define WEBVIEW2INSTALLERARGS "{{webview2_installer_args}}" +!define WEBVIEW2BOOTSTRAPPERPATH "{{webview2_bootstrapper_path}}" +!define WEBVIEW2INSTALLERPATH "{{webview2_installer_path}}" +!define UNINSTKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCTNAME}" +!define APPPATHKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\${MAINBINARYNAME}.exe" +!define MANUPRODUCTKEY "Software\${MANUFACTURER}\${PRODUCTNAME}" +!define UNINSTALLERSIGNCOMMAND "{{uninstaller_sign_cmd}}" +!define ESTIMATEDSIZE "{{estimated_size}}" +!define STARTMENUFOLDER "{{start_menu_folder}}" + +Var PassiveMode +Var UpdateMode +Var NoShortcutMode + +Name "${PRODUCTNAME}" +BrandingText "${COPYRIGHT}" +OutFile "${OUTFILE}" + +; We don't actually use this value as default install path, +; it's just for nsis to append the product name folder in the directory selector +; https://nsis.sourceforge.io/Reference/InstallDir +!define PLACEHOLDER_INSTALL_DIR "placeholder\${MANUFACTURER}\${PRODUCTNAME}" +InstallDir "${PLACEHOLDER_INSTALL_DIR}" + +VIProductVersion "${VERSIONWITHBUILD}" +VIAddVersionKey "ProductName" "${PRODUCTNAME}" +VIAddVersionKey "FileDescription" "${SHORTDESCRIPTION}" +VIAddVersionKey "LegalCopyright" "${COPYRIGHT}" +VIAddVersionKey "FileVersion" "${VERSION}" +VIAddVersionKey "ProductVersion" "${VERSION}" + +; Plugins path, currently exists for linux only +!if "${PLUGINSPATH}" != "" + !addplugindir "${PLUGINSPATH}" +!endif + +; Uninstaller signing command +!if "${UNINSTALLERSIGNCOMMAND}" != "" + !uninstfinalize '${UNINSTALLERSIGNCOMMAND}' +!endif + +; Handle install mode, `perUser`, `perMachine` or `both` +!if "${INSTALLMODE}" == "perMachine" + RequestExecutionLevel highest +!endif + +!if "${INSTALLMODE}" == "currentUser" + RequestExecutionLevel user +!endif + +!if "${INSTALLMODE}" == "both" + !define MULTIUSER_MUI + !define MULTIUSER_INSTALLMODE_INSTDIR "${MANUFACTURER}\${PRODUCTNAME}" + !define MULTIUSER_INSTALLMODE_COMMANDLINE + !if "${ARCH}" == "x64" + !define MULTIUSER_USE_PROGRAMFILES64 + !else if "${ARCH}" == "arm64" + !define MULTIUSER_USE_PROGRAMFILES64 + !endif + !define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "${UNINSTKEY}" + !define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME "CurrentUser" + !define MULTIUSER_INSTALLMODEPAGE_SHOWUSERNAME + !define MULTIUSER_INSTALLMODE_FUNCTION RestorePreviousInstallLocation + !define MULTIUSER_EXECUTIONLEVEL Highest + !include MultiUser.nsh +!endif + +; Installer & Unistaller icon +!if "${INSTALLERICON}" != "" + !define MUI_ICON "${INSTALLERICON}" + !define MUI_UNICON "${INSTALLERICON}" +!endif + +; Installer sidebar image +!if "${SIDEBARIMAGE}" != "" + !define MUI_WELCOMEFINISHPAGE_BITMAP "${SIDEBARIMAGE}" +!endif + +; Installer header image +!if "${HEADERIMAGE}" != "" + !define MUI_HEADERIMAGE + !define MUI_HEADERIMAGE_BITMAP "${HEADERIMAGE}" +!endif + +; Define registry key to store installer language +!define MUI_LANGDLL_REGISTRY_ROOT "HKCU" +!define MUI_LANGDLL_REGISTRY_KEY "${MANUPRODUCTKEY}" +!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language" + +; =============================================================================================== +; ====================================== INSTALLER PAGES ======================================== +; =============================================================================================== +!define MUI_BGCOLOR 222228 +!define MUI_TEXTCOLOR fdfdfd +!define MUI_FINISHPAGE_TEXT_COLOR fdfdfd + +; 1. Welcome Page +!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive +!insertmacro MUI_PAGE_WELCOME + +; 2. License Page (if defined) +!if "${LICENSE}" != "" + !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive + !insertmacro MUI_PAGE_LICENSE "${LICENSE}" +!endif + +; 3. Install mode (if it is set to `both`) +!if "${INSTALLMODE}" == "both" + !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive + !insertmacro MULTIUSER_PAGE_INSTALLMODE +!endif + +; 4. Custom page to ask user if he wants to reinstall/uninstall +; only if a previous installation was detected +Var ReinstallPageCheck +Page custom PageReinstall PageLeaveReinstall +Function PageReinstall + ; Uninstall previous WiX installation if exists. + ; + ; A WiX installer stores the installation info in registry + ; using a UUID and so we have to loop through all keys under + ; `HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall` + ; and check if `DisplayName` and `Publisher` keys match ${PRODUCTNAME} and ${MANUFACTURER} + ; + ; This has a potential issue that there maybe another installation that matches + ; our ${PRODUCTNAME} and ${MANUFACTURER} but wasn't installed by our WiX installer, + ; however, this should be fine since the user will have to confirm the uninstallation + ; and they can chose to abort it if doesn't make sense. + StrCpy $0 0 + wix_loop: + EnumRegKey $1 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" $0 + StrCmp $1 "" wix_done ; Exit loop if there is no more keys to loop on + IntOp $0 $0 + 1 + ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "DisplayName" + ReadRegStr $R1 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "Publisher" + StrCmp "$R0$R1" "${PRODUCTNAME}${MANUFACTURER}" 0 wix_loop + ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "UninstallString" + ${StrCase} $R1 $R0 "L" + ${StrLoc} $R0 $R1 "msiexec" ">" + StrCmp $R0 0 0 wix_done + StrCpy $R7 "wix" + StrCpy $R6 "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" + Goto compare_version + wix_done: + + ; Check if there is an existing installation, if not, abort the reinstall page + ReadRegStr $R0 SHCTX "${UNINSTKEY}" "" + ReadRegStr $R1 SHCTX "${UNINSTKEY}" "UninstallString" + ${IfThen} "$R0$R1" == "" ${|} Abort ${|} + + ; Compare this installar version with the existing installation + ; and modify the messages presented to the user accordingly + compare_version: + StrCpy $R4 "$(older)" + ${If} $R7 == "wix" + ReadRegStr $R0 HKLM "$R6" "DisplayVersion" + ${Else} + ReadRegStr $R0 SHCTX "${UNINSTKEY}" "DisplayVersion" + ${EndIf} + ${IfThen} $R0 == "" ${|} StrCpy $R4 "$(unknown)" ${|} + + nsis_tauri_utils::SemverCompare "${VERSION}" $R0 + Pop $R0 + ; Reinstalling the same version + ${If} $R0 = 0 + StrCpy $R1 "$(alreadyInstalledLong)" + StrCpy $R2 "$(addOrReinstall)" + StrCpy $R3 "$(uninstallApp)" + !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(chooseMaintenanceOption)" + StrCpy $R5 "2" + ; Upgrading + ${ElseIf} $R0 = 1 + StrCpy $R1 "$(olderOrUnknownVersionInstalled)" + StrCpy $R2 "$(uninstallBeforeInstalling)" + StrCpy $R3 "$(dontUninstall)" + !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(choowHowToInstall)" + StrCpy $R5 "1" + ; Downgrading + ${ElseIf} $R0 = -1 + StrCpy $R1 "$(newerVersionInstalled)" + StrCpy $R2 "$(uninstallBeforeInstalling)" + !if "${ALLOWDOWNGRADES}" == "true" + StrCpy $R3 "$(dontUninstall)" + !else + StrCpy $R3 "$(dontUninstallDowngrade)" + !endif + !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(choowHowToInstall)" + StrCpy $R5 "1" + ${Else} + Abort + ${EndIf} + + ; Skip showing the page if passive + ; + ; Note that we don't call this earlier at the begining + ; of this function because we need to populate some variables + ; related to current installed version if detected and whether + ; we are downgrading or not. + Call SkipIfPassive + + nsDialogs::Create 1018 + Pop $R4 + ${IfThen} $(^RTL) = 1 ${|} nsDialogs::SetRTL $(^RTL) ${|} + + ${NSD_CreateLabel} 0 0 100% 24u $R1 + Pop $R1 + + ${NSD_CreateRadioButton} 30u 50u -30u 8u $R2 + Pop $R2 + ${NSD_OnClick} $R2 PageReinstallUpdateSelection + + ${NSD_CreateRadioButton} 30u 70u -30u 8u $R3 + Pop $R3 + ; Disable this radio button if downgrading and downgrades are disabled + !if "${ALLOWDOWNGRADES}" == "false" + ${IfThen} $R0 = -1 ${|} EnableWindow $R3 0 ${|} + !endif + ${NSD_OnClick} $R3 PageReinstallUpdateSelection + + ; Check the first radio button if this the first time + ; we enter this page or if the second button wasn't + ; selected the last time we were on this page + ${If} $ReinstallPageCheck <> 2 + SendMessage $R2 ${BM_SETCHECK} ${BST_CHECKED} 0 + ${Else} + SendMessage $R3 ${BM_SETCHECK} ${BST_CHECKED} 0 + ${EndIf} + + ${NSD_SetFocus} $R2 + nsDialogs::Show +FunctionEnd +Function PageReinstallUpdateSelection + ${NSD_GetState} $R2 $R1 + ${If} $R1 == ${BST_CHECKED} + StrCpy $ReinstallPageCheck 1 + ${Else} + StrCpy $ReinstallPageCheck 2 + ${EndIf} +FunctionEnd +Function PageLeaveReinstall + ${NSD_GetState} $R2 $R1 + + ; $R5 holds whether we are reinstalling the same version or not + ; $R5 == "1" -> different versions + ; $R5 == "2" -> same version + ; + ; $R1 holds the radio buttons state. its meaning is dependent on the context + StrCmp $R5 "1" 0 +2 ; Existing install is not the same version? + StrCmp $R1 "1" reinst_uninstall reinst_done ; $R1 == "1", then user chose to uninstall existing version, otherwise skip uninstalling + StrCmp $R1 "1" reinst_done ; Same version? skip uninstalling + + reinst_uninstall: + HideWindow + ClearErrors + + ${If} $R7 == "wix" + ReadRegStr $R1 HKLM "$R6" "UninstallString" + ExecWait '$R1' $0 + ${Else} + ReadRegStr $4 SHCTX "${MANUPRODUCTKEY}" "" + ReadRegStr $R1 SHCTX "${UNINSTKEY}" "UninstallString" + ${If} $UpdateMode = 1 + ExecWait '$R1 /UPDATE /P _?=$4' $0 + ${Else} + ExecWait '$R1 /P _?=$4' $0 + ${EndIf} + ${EndIf} + + BringToFront + + ${IfThen} ${Errors} ${|} StrCpy $0 2 ${|} ; ExecWait failed, set fake exit code + + ${If} $0 <> 0 + ${OrIf} ${FileExists} "$INSTDIR\${MAINBINARYNAME}.exe" + ${If} $0 = 1 ; User aborted uninstaller? + StrCmp $R5 "2" 0 +2 ; Is the existing install the same version? + Quit ; ...yes, already installed, we are done + Abort + ${EndIf} + MessageBox MB_ICONEXCLAMATION "$(unableToUninstall)" + Abort + ${Else} + StrCpy $0 $R1 1 + ${IfThen} $0 == '"' ${|} StrCpy $R1 $R1 -1 1 ${|} ; Strip quotes from UninstallString + Delete $R1 + RMDir $INSTDIR + ${EndIf} + reinst_done: +FunctionEnd + +; 5. Choose install directory page +!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive +!insertmacro MUI_PAGE_DIRECTORY + +; 6. Start menu shortcut page +Var AppStartMenuFolder +!if "${STARTMENUFOLDER}" != "" + !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive + !define MUI_STARTMENUPAGE_DEFAULTFOLDER "${STARTMENUFOLDER}" +!else + !define MUI_PAGE_CUSTOMFUNCTION_PRE Skip +!endif +!insertmacro MUI_PAGE_STARTMENU Application $AppStartMenuFolder + +; 7. Installation page +!insertmacro MUI_PAGE_INSTFILES + +; 8. Finish page +; +; Don't auto jump to finish page after installation page, +; because the installation page has useful info that can be used debug any issues with the installer. +!define MUI_FINISHPAGE_NOAUTOCLOSE +; Show sponsor link +!define MUI_FINISHPAGE_LINK_COLOR 59a7f6 +!define MUI_FINISHPAGE_LINK "Join us on Discord! 🤍" +!define MUI_FINISHPAGE_LINK_LOCATION "https://discord.gg/ABfASx5ZAJ" + +Function RunMainBinary + Exec '"$INSTDIR\${MAINBINARYNAME}.exe"' +FunctionEnd + +!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive +!define MUI_PAGE_CUSTOMFUNCTION_LEAVE RunMainBinary +!insertmacro MUI_PAGE_FINISH + +; Uninstaller Pages +; 1. Confirm uninstall page +Var DeleteAppDataCheckbox +Var DeleteAppDataCheckboxState +!define /ifndef WS_EX_LAYOUTRTL 0x00400000 +!define MUI_PAGE_CUSTOMFUNCTION_SHOW un.ConfirmShow +Function un.ConfirmShow ; Add add a `Delete app data` check box + ; $1 inner dialog HWND + ; $2 window DPI + ; $3 style + ; $4 x + ; $5 y + ; $6 width + ; $7 height + FindWindow $1 "#32770" "" $HWNDPARENT ; Find inner dialog + System::Call "user32::GetDpiForWindow(p r1) i .r2" + ${If} $(^RTL) = 1 + StrCpy $3 "${__NSD_CheckBox_EXSTYLE} | ${WS_EX_LAYOUTRTL}" + IntOp $4 50 * $2 + ${Else} + StrCpy $3 "${__NSD_CheckBox_EXSTYLE}" + IntOp $4 0 * $2 + ${EndIf} + IntOp $5 100 * $2 + IntOp $6 400 * $2 + IntOp $7 25 * $2 + IntOp $4 $4 / 96 + IntOp $5 $5 / 96 + IntOp $6 $6 / 96 + IntOp $7 $7 / 96 + System::Call 'user32::CreateWindowEx(i r3, w "${__NSD_CheckBox_CLASS}", w "$(deleteAppData)", i ${__NSD_CheckBox_STYLE}, i r4, i r5, i r6, i r7, p r1, i0, i0, i0) i .s' + Pop $DeleteAppDataCheckbox + SendMessage $HWNDPARENT ${WM_GETFONT} 0 0 $1 + SendMessage $DeleteAppDataCheckbox ${WM_SETFONT} $1 1 +FunctionEnd +!define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.ConfirmLeave +Function un.ConfirmLeave + SendMessage $DeleteAppDataCheckbox ${BM_GETCHECK} 0 0 $DeleteAppDataCheckboxState +FunctionEnd +!insertmacro MUI_UNPAGE_CONFIRM + +; 2. Uninstalling Page +!insertmacro MUI_UNPAGE_INSTFILES + +;Languages +{{#each languages}} +!insertmacro MUI_LANGUAGE "{{this}}" +{{/each}} +!insertmacro MUI_RESERVEFILE_LANGDLL +{{#each language_files}} + !include "{{this}}" +{{/each}} + +Function .onInit + ${GetOptions} $CMDLINE "/P" $PassiveMode + ${IfNot} ${Errors} + StrCpy $PassiveMode 1 + ${EndIf} + + ${GetOptions} $CMDLINE "/NS" $NoShortcutMode + ${IfNot} ${Errors} + StrCpy $NoShortcutMode 1 + ${EndIf} + + ${GetOptions} $CMDLINE "/UPDATE" $UpdateMode + ${IfNot} ${Errors} + StrCpy $UpdateMode 1 + ${EndIf} + + !if "${DISPLAYLANGUAGESELECTOR}" == "true" + !insertmacro MUI_LANGDLL_DISPLAY + !endif + + !insertmacro SetContext + + ${If} $INSTDIR == "${PLACEHOLDER_INSTALL_DIR}" + ; Set default install location + !if "${INSTALLMODE}" == "perMachine" + ${If} ${RunningX64} + !if "${ARCH}" == "x64" + StrCpy $INSTDIR "$PROGRAMFILES64\${MANUFACTURER}\${PRODUCTNAME}" + !else if "${ARCH}" == "arm64" + StrCpy $INSTDIR "$PROGRAMFILES64\${MANUFACTURER}\${PRODUCTNAME}" + !else + StrCpy $INSTDIR "$PROGRAMFILES\${MANUFACTURER}\${PRODUCTNAME}" + !endif + ${Else} + StrCpy $INSTDIR "$PROGRAMFILES\${MANUFACTURER}\${PRODUCTNAME}" + ${EndIf} + !else if "${INSTALLMODE}" == "currentUser" + StrCpy $INSTDIR "$LOCALAPPDATA\${MANUFACTURER}\${PRODUCTNAME}" + !endif + + Call RestorePreviousInstallLocation + ${EndIf} + + + !if "${INSTALLMODE}" == "both" + !insertmacro MULTIUSER_INIT + !endif +FunctionEnd + + +Section EarlyChecks + ; Abort silent installer if downgrades is disabled + !if "${ALLOWDOWNGRADES}" == "false" + ${If} ${Silent} + ; If downgrading + ${If} $R0 = -1 + System::Call 'kernel32::AttachConsole(i -1)i.r0' + ${If} $0 <> 0 + System::Call 'kernel32::GetStdHandle(i -11)i.r0' + System::call 'kernel32::SetConsoleTextAttribute(i r0, i 0x0004)' ; set red color + FileWrite $0 "$(silentDowngrades)" + ${EndIf} + Abort + ${EndIf} + ${EndIf} + !endif + +SectionEnd + +Section WebView2 + ; Check if Webview2 is already installed and skip this section + ${If} ${RunningX64} + ReadRegStr $4 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" + ${Else} + ReadRegStr $4 HKLM "SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" + ${EndIf} + ReadRegStr $5 HKCU "SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" + + StrCmp $4 "" 0 webview2_done + StrCmp $5 "" 0 webview2_done + + ; Webview2 installation + ; + ; Skip if updating + ${If} $UpdateMode <> 1 + !if "${INSTALLWEBVIEW2MODE}" == "downloadBootstrapper" + Delete "$TEMP\MicrosoftEdgeWebview2Setup.exe" + DetailPrint "$(webview2Downloading)" + NSISdl::download "https://go.microsoft.com/fwlink/p/?LinkId=2124703" "$TEMP\MicrosoftEdgeWebview2Setup.exe" + Pop $0 + ${If} $0 = 0 + DetailPrint "$(webview2DownloadSuccess)" + ${Else} + DetailPrint "$(webview2DownloadError)" + Abort "$(webview2AbortError)" + ${EndIf} + StrCpy $6 "$TEMP\MicrosoftEdgeWebview2Setup.exe" + Goto install_webview2 + !endif + + !if "${INSTALLWEBVIEW2MODE}" == "embedBootstrapper" + Delete "$TEMP\MicrosoftEdgeWebview2Setup.exe" + File "/oname=$TEMP\MicrosoftEdgeWebview2Setup.exe" "${WEBVIEW2BOOTSTRAPPERPATH}" + DetailPrint "$(installingWebview2)" + StrCpy $6 "$TEMP\MicrosoftEdgeWebview2Setup.exe" + Goto install_webview2 + !endif + + !if "${INSTALLWEBVIEW2MODE}" == "offlineInstaller" + Delete "$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe" + File "/oname=$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe" "${WEBVIEW2INSTALLERPATH}" + DetailPrint "$(installingWebview2)" + StrCpy $6 "$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe" + Goto install_webview2 + !endif + + Goto webview2_done + + install_webview2: + DetailPrint "$(installingWebview2)" + ; $6 holds the path to the webview2 installer + ExecWait "$6 ${WEBVIEW2INSTALLERARGS} /install" $1 + ${If} $1 = 0 + DetailPrint "$(webview2InstallSuccess)" + ${Else} + DetailPrint "$(webview2InstallError)" + Abort "$(webview2AbortError)" + ${EndIf} + webview2_done: + ${EndIf} +SectionEnd + +Section Install + SetOutPath $INSTDIR + + !ifmacrodef NSIS_HOOK_PREINSTALL + !insertmacro NSIS_HOOK_PREINSTALL + !endif + + !insertmacro CheckIfAppIsRunning + + ; Copy main executable + File "${MAINBINARYSRCPATH}" + + ; Copy resources + {{#each resources_dirs}} + CreateDirectory "$INSTDIR\\{{this}}" + {{/each}} + {{#each resources}} + File /a "/oname={{this.[1]}}" "{{@key}}" + {{/each}} + + ; Copy external binaries + {{#each binaries}} + File /a "/oname={{this}}" "{{@key}}" + {{/each}} + + ; Create file associations + {{#each file_associations as |association| ~}} + {{#each association.ext as |ext| ~}} + !insertmacro APP_ASSOCIATE "{{ext}}" "{{or association.name ext}}" "{{association-description association.description ext}}" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\",0" "Open with ${PRODUCTNAME}" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\" $\"%1$\"" + {{/each}} + {{/each}} + + ; Register deep links + {{#each deep_link_protocols as |protocol| ~}} + WriteRegStr SHCTX "Software\Classes\\{{protocol}}" "URL Protocol" "" + WriteRegStr SHCTX "Software\Classes\\{{protocol}}" "" "URL:${BUNDLEID} protocol" + WriteRegStr SHCTX "Software\Classes\\{{protocol}}\DefaultIcon" "" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\",0" + WriteRegStr SHCTX "Software\Classes\\{{protocol}}\shell\open\command" "" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\" $\"%1$\"" + {{/each}} + + ; Refresh file associations icons + !insertmacro UPDATEFILEASSOC + + ; Create uninstaller + WriteUninstaller "$INSTDIR\uninstall.exe" + + ; Save $INSTDIR in registry for future installations + WriteRegStr SHCTX "${MANUPRODUCTKEY}" "" $INSTDIR + + !if "${INSTALLMODE}" == "both" + ; Save install mode to be selected by default for the next installation such as updating + ; or when uninstalling + WriteRegStr SHCTX "${UNINSTKEY}" $MultiUser.InstallMode 1 + !endif + + ; Registry information for add/remove programs + WriteRegStr SHCTX "${UNINSTKEY}" "DisplayName" "${PRODUCTNAME}" + WriteRegStr SHCTX "${UNINSTKEY}" "DisplayIcon" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\"" + WriteRegStr SHCTX "${UNINSTKEY}" "DisplayVersion" "${VERSION}" + WriteRegStr SHCTX "${UNINSTKEY}" "Publisher" "${MANUFACTURER}" + WriteRegStr SHCTX "${UNINSTKEY}" "InstallLocation" "$\"$INSTDIR$\"" + WriteRegStr SHCTX "${UNINSTKEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" + WriteRegDWORD SHCTX "${UNINSTKEY}" "NoModify" "1" + WriteRegDWORD SHCTX "${UNINSTKEY}" "NoRepair" "1" + + ${GetSize} "$INSTDIR" "/M=uninstall.exe /S=0K /G=0" $0 $1 $2 + IntOp $0 $0 + ${ESTIMATEDSIZE} + IntFmt $0 "0x%08X" $0 + WriteRegDWORD SHCTX "${UNINSTKEY}" "EstimatedSize" "$0" + + !if "${HOMEPAGE}" != "" + WriteRegStr SHCTX "${UNINSTKEY}" "URLInfoAbout" "${HOMEPAGE}" + WriteRegStr SHCTX "${UNINSTKEY}" "URLUpdateInfo" "${HOMEPAGE}" + WriteRegStr SHCTX "${UNINSTKEY}" "HelpLink" "${HOMEPAGE}" + !endif + + ; Register Main Binary path to Apps Paths + WriteRegStr SHCTX "${APPPATHKEY}" "" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\"" + WriteRegStr SHCTX "${APPPATHKEY}" "Path" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\"" + + ; Create start menu shortcut + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + Call CreateOrUpdateStartMenuShortcut + !insertmacro MUI_STARTMENU_WRITE_END + + ; Create desktop shortcut and run Executable for silent and passive installers + ; because finish page will be skipped + ${If} $PassiveMode = 1 + ${OrIf} ${Silent} + Call CreateOrUpdateDesktopShortcut + Call RunMainBinary + ${EndIf} + + !ifmacrodef NSIS_HOOK_POSTINSTALL + !insertmacro NSIS_HOOK_POSTINSTALL + !endif + + ; Auto close this page for passive mode + ${If} $PassiveMode = 1 + SetAutoClose true + ${EndIf} +SectionEnd + +Function .onInstSuccess + ; Check for `/R` flag only in silent and passive installers because + ; GUI installer has a toggle for the user to (re)start the app + ${If} $PassiveMode = 1 + ${OrIf} ${Silent} + ${GetOptions} $CMDLINE "/R" $R0 + ${IfNot} ${Errors} + ${GetOptions} $CMDLINE "/ARGS" $R0 + nsis_tauri_utils::RunAsUser "$INSTDIR\${MAINBINARYNAME}.exe" "$R0" + ${EndIf} + ${EndIf} +FunctionEnd + +Function un.onInit + !insertmacro SetContext + + !if "${INSTALLMODE}" == "both" + !insertmacro MULTIUSER_UNINIT + !endif + + !insertmacro MUI_UNGETLANGUAGE + + ${GetOptions} $CMDLINE "/P" $PassiveMode + ${IfNot} ${Errors} + StrCpy $PassiveMode 1 + ${EndIf} + + ${GetOptions} $CMDLINE "/UPDATE" $UpdateMode + ${IfNot} ${Errors} + StrCpy $UpdateMode 1 + ${EndIf} +FunctionEnd + +Section Uninstall + + !ifmacrodef NSIS_HOOK_PREUNINSTALL + !insertmacro NSIS_HOOK_PREUNINSTALL + !endif + + !insertmacro CheckIfAppIsRunning + + ; Delete the app directory and its content from disk + ; Copy main executable + Delete "$INSTDIR\${MAINBINARYNAME}.exe" + + ; Delete resources + {{#each resources}} + Delete "$INSTDIR\\{{this.[1]}}" + {{/each}} + + ; Delete external binaries + {{#each binaries}} + Delete "$INSTDIR\\{{this}}" + {{/each}} + + ; Delete app associations + {{#each file_associations as |association| ~}} + {{#each association.ext as |ext| ~}} + !insertmacro APP_UNASSOCIATE "{{ext}}" "{{or association.name ext}}" + {{/each}} + {{/each}} + + ; Delete deep links + {{#each deep_link_protocols as |protocol| ~}} + ReadRegStr $R7 SHCTX "Software\Classes\\{{protocol}}\shell\open\command" "" + ${If} $R7 == "$\"$INSTDIR\${MAINBINARYNAME}.exe$\" $\"%1$\"" + DeleteRegKey SHCTX "Software\Classes\\{{protocol}}" + ${EndIf} + {{/each}} + + ; Refresh file associations icons + !insertmacro UPDATEFILEASSOC + + ; Delete uninstaller + Delete "$INSTDIR\uninstall.exe" + + {{#each resources_ancestors}} + RMDir /REBOOTOK "$INSTDIR\\{{this}}" + {{/each}} + RMDir "$INSTDIR" + + ; Remove shortcuts if not updating + ${If} $UpdateMode <> 1 + !insertmacro DeleteAppUserModelId + + ; Remove start menu shortcut + !insertmacro MUI_STARTMENU_GETFOLDER Application $AppStartMenuFolder + !insertmacro IsShortcutTarget "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + Pop $0 + ${If} $0 = 1 + !insertmacro UnpinShortcut "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" + Delete "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" + RMDir "$SMPROGRAMS\$AppStartMenuFolder" + ${EndIf} + !insertmacro IsShortcutTarget "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + Pop $0 + ${If} $0 = 1 + !insertmacro UnpinShortcut "$SMPROGRAMS\${PRODUCTNAME}.lnk" + Delete "$SMPROGRAMS\${PRODUCTNAME}.lnk" + ${EndIf} + + ; Remove desktop shortcuts + !insertmacro IsShortcutTarget "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + Pop $0 + ${If} $0 = 1 + !insertmacro UnpinShortcut "$DESKTOP\${PRODUCTNAME}.lnk" + Delete "$DESKTOP\${PRODUCTNAME}.lnk" + ${EndIf} + ${EndIf} + + ; Remove registry information for add/remove programs + !if "${INSTALLMODE}" == "both" + DeleteRegKey SHCTX "${UNINSTKEY}" + DeleteRegKey SHCTX "${APPPATHKEY}" + !else if "${INSTALLMODE}" == "perMachine" + DeleteRegKey HKLM "${UNINSTKEY}" + DeleteRegKey HKLM "${APPPATHKEY}" + !else + DeleteRegKey HKCU "${UNINSTKEY}" + DeleteRegKey HKCU "${APPPATHKEY}" + !endif + + DeleteRegValue HKCU "${MANUPRODUCTKEY}" "Installer Language" + + ; Delete app data if the checkbox is selected + ; and if not updating + ${If} $DeleteAppDataCheckboxState = 1 + ${AndIf} $UpdateMode <> 1 + SetShellVarContext current + RmDir /r "$APPDATA\${BUNDLEID}" + RmDir /r "$LOCALAPPDATA\${BUNDLEID}" + ${EndIf} + + !ifmacrodef NSIS_HOOK_POSTUNINSTALL + !insertmacro NSIS_HOOK_POSTUNINSTALL + !endif + + ; Auto close if passive mode + ${If} $PassiveMode = 1 + SetAutoClose true + ${EndIf} +SectionEnd + +Function RestorePreviousInstallLocation + ReadRegStr $4 SHCTX "${MANUPRODUCTKEY}" "" + StrCmp $4 "" +2 0 + StrCpy $INSTDIR $4 +FunctionEnd + +Function Skip + Abort +FunctionEnd + +Function SkipIfPassive + ${IfThen} $PassiveMode = 1 ${|} Abort ${|} +FunctionEnd + +Function CreateOrUpdateStartMenuShortcut + ; We used to use product name as MAINBINARYNAME + ; migrate old shortcuts to target the new MAINBINARYNAME + StrCpy $R0 0 + + !insertmacro IsShortcutTarget "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCTNAME}.exe" + Pop $0 + ${If} $0 = 1 + !insertmacro SetShortcutTarget "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + StrCpy $R0 1 + ${EndIf} + + !insertmacro IsShortcutTarget "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCTNAME}.exe" + Pop $0 + ${If} $0 = 1 + !insertmacro SetShortcutTarget "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + StrCpy $R0 1 + ${EndIf} + + ${If} $R0 = 1 + Return + ${EndIf} + + ; Skip creating shortcut if in update mode or no shortcut mode + ${If} $UpdateMode = 1 + ${OrIf} $NoShortcutMode = 1 + Return + ${EndIf} + + !if "${STARTMENUFOLDER}" != "" + CreateDirectory "$SMPROGRAMS\$AppStartMenuFolder" + CreateShortcut "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + !insertmacro SetLnkAppUserModelId "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" + !else + CreateShortcut "$SMPROGRAMS\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + !insertmacro SetLnkAppUserModelId "$SMPROGRAMS\${PRODUCTNAME}.lnk" + !endif +FunctionEnd + +Function CreateOrUpdateDesktopShortcut + ; We used to use product name as MAINBINARYNAME + ; migrate old shortcuts to target the new MAINBINARYNAME + !insertmacro IsShortcutTarget "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCTNAME}.exe" + Pop $0 + ${If} $0 = 1 + !insertmacro SetShortcutTarget "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + Return + ${EndIf} + + ; Skip creating shortcut if in update mode or no shortcut mode + ${If} $UpdateMode = 1 + ${OrIf} $NoShortcutMode = 1 + Return + ${EndIf} + + CreateShortcut "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + !insertmacro SetLnkAppUserModelId "$DESKTOP\${PRODUCTNAME}.lnk" FunctionEnd \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 07ea163f..cfcd1b05 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,31 +1,31 @@ -{ - "compilerOptions": { - "lib": [ - "ESNext", - "DOM" - ], - "target": "ES2020", - "module": "commonjs", - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "noImplicitAny": true, - "noImplicitReturns": true, - "noUncheckedIndexedAccess": true, - "noEmit": true, - "jsx": "react-jsx", - "types": [ - "react", - "readable-types", - "node", - "jest" - ], - "skipLibCheck": true, - }, - "exclude": [ - "node_modules", - "dist" - ] +{ + "compilerOptions": { + "lib": [ + "ESNext", + "DOM" + ], + "target": "ES2020", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noUncheckedIndexedAccess": true, + "noEmit": true, + "jsx": "react-jsx", + "types": [ + "react", + "readable-types", + "node", + "jest" + ], + "skipLibCheck": true, + }, + "exclude": [ + "node_modules", + "dist" + ] } \ No newline at end of file