├── .gitignore ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE.spdx ├── LICENSE_APACHE-2.0 ├── LICENSE_MIT ├── README.md ├── banner.png ├── dist-js ├── index.d.ts ├── index.min.js ├── index.min.js.map ├── index.mjs └── index.mjs.map ├── guest-js └── index.ts ├── package.json ├── rollup.config.mjs ├── src ├── cmd.rs └── lib.rs └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## \[0.1.1] 4 | 5 | - Address a couple of issues with restoring positions: 6 | 7 | - Fix restoring window positions correctly when the top-left corner of the window was outside of the monitor. 8 | 9 | - Fix restore maximization state only maximized on main monitor. 10 | 11 | - [70d9908](https://github.com/tauri-apps/plugins-workspace/commit/70d99086de3a58189d65c49954a3495972880725) fix(window-state): restore window position if the one of the window corners intersects with monitor ([#898](https://github.com/tauri-apps/plugins-workspace/pull/898)) on 2024-01-25 12 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tauri-plugin-window-state" 3 | version = "0.1.1" 4 | description = "Save window positions and sizes and restore them when the app is reopened." 5 | authors = { workspace = true } 6 | license = { workspace = true } 7 | edition = { workspace = true } 8 | rust-version = { workspace = true } 9 | 10 | [dependencies] 11 | serde = { workspace = true } 12 | serde_json = { workspace = true } 13 | tauri = { workspace = true } 14 | log = { workspace = true } 15 | thiserror = { workspace = true } 16 | bincode = "1.3" 17 | bitflags = "2" 18 | -------------------------------------------------------------------------------- /LICENSE.spdx: -------------------------------------------------------------------------------- 1 | SPDXVersion: SPDX-2.1 2 | DataLicense: CC0-1.0 3 | PackageName: tauri 4 | DataFormat: SPDXRef-1 5 | PackageSupplier: Organization: The Tauri Programme in the Commons Conservancy 6 | PackageHomePage: https://tauri.app 7 | PackageLicenseDeclared: Apache-2.0 8 | PackageLicenseDeclared: MIT 9 | PackageCopyrightText: 2019-2022, The Tauri Programme in the Commons Conservancy 10 | PackageSummary: Tauri is a rust project that enables developers to make secure 11 | and small desktop applications using a web frontend. 12 | 13 | PackageComment: The package includes the following libraries; see 14 | Relationship information. 15 | 16 | Created: 2019-05-20T09:00:00Z 17 | PackageDownloadLocation: git://github.com/tauri-apps/tauri 18 | PackageDownloadLocation: git+https://github.com/tauri-apps/tauri.git 19 | PackageDownloadLocation: git+ssh://github.com/tauri-apps/tauri.git 20 | Creator: Person: Daniel Thompson-Yvetot -------------------------------------------------------------------------------- /LICENSE_APACHE-2.0: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS -------------------------------------------------------------------------------- /LICENSE_MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 - Present Tauri Apps Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![plugin-window-state](https://github.com/tauri-apps/plugins-workspace/raw/v1/plugins/window-state/banner.png) 2 | 3 | Save window positions and sizes and restore them when the app is reopened. 4 | 5 | ## Install 6 | 7 | _This plugin requires a Rust version of at least **1.67**_ 8 | 9 | There are three general methods of installation that we can recommend. 10 | 11 | 1. Use crates.io and npm (easiest, and requires you to trust that our publishing pipeline worked) 12 | 2. Pull sources directly from Github using git tags / revision hashes (most secure) 13 | 3. Git submodule install this repo in your tauri project and then use file protocol to ingest the source (most secure, but inconvenient to use) 14 | 15 | Install the Core plugin by adding the following to your `Cargo.toml` file: 16 | 17 | `src-tauri/Cargo.toml` 18 | 19 | ```toml 20 | [dependencies] 21 | tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" } 22 | ``` 23 | 24 | You can install the JavaScript Guest bindings using your preferred JavaScript package manager: 25 | 26 | > Note: Since most JavaScript package managers are unable to install packages from git monorepos we provide read-only mirrors of each plugin. This makes installation option 2 more ergonomic to use. 27 | 28 | ```sh 29 | pnpm add https://github.com/tauri-apps/tauri-plugin-window-state#v1 30 | # or 31 | npm add https://github.com/tauri-apps/tauri-plugin-window-state#v1 32 | # or 33 | yarn add https://github.com/tauri-apps/tauri-plugin-window-state#v1 34 | ``` 35 | 36 | ## Usage 37 | 38 | First you need to register the core plugin with Tauri: 39 | 40 | `src-tauri/src/main.rs` 41 | 42 | ```rust 43 | fn main() { 44 | tauri::Builder::default() 45 | .plugin(tauri_plugin_window_state::Builder::default().build()) 46 | .run(tauri::generate_context!()) 47 | .expect("error while running tauri application"); 48 | } 49 | ``` 50 | 51 | Afterwards all windows will remember their state when the app is being closed and will restore to their previous state on the next launch. 52 | 53 | Optionally you can also tell the plugin to save the state of all open window to disk by using the `save_window_state()` method exposed by the `AppHandleExt` trait: 54 | 55 | ```rust 56 | use tauri_plugin_window_state::{AppHandleExt, StateFlags}; 57 | 58 | // `tauri::AppHandle` now has the following additional method 59 | app.save_window_state(StateFlags::all()); // will save the state of all open windows to disk 60 | ``` 61 | 62 | or through Javascript 63 | 64 | ```javascript 65 | import { saveWindowState, StateFlags } from "tauri-plugin-window-state-api"; 66 | 67 | saveWindowState(StateFlags.ALL); 68 | ``` 69 | 70 | To manually restore a windows state from disk you can call the `restore_state()` method exposed by the `WindowExt` trait: 71 | 72 | ```rust 73 | use tauri_plugin_window_state::{WindowExt, StateFlags}; 74 | 75 | // all `Window` types now have the following additional method 76 | window.restore_state(StateFlags::all()); // will restore the windows state from disk 77 | ``` 78 | 79 | or through Javascript 80 | 81 | ```javascript 82 | import { restoreStateCurrent, StateFlags } from "tauri-plugin-window-state-api"; 83 | 84 | restoreStateCurrent(StateFlags.ALL); 85 | ``` 86 | 87 | ## Contributing 88 | 89 | PRs accepted. Please make sure to read the Contributing Guide before making a pull request. 90 | 91 | ## Partners 92 | 93 | 94 | 95 | 96 | 101 | 102 | 103 |
97 | 98 | CrabNebula 99 | 100 |
104 | 105 | For the complete list of sponsors please visit our [website](https://tauri.app#sponsors) and [Open Collective](https://opencollective.com/tauri). 106 | 107 | ## License 108 | 109 | Code: (c) 2015 - Present - The Tauri Programme within The Commons Conservancy. 110 | 111 | MIT or MIT/Apache 2.0 where applicable. 112 | -------------------------------------------------------------------------------- /banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tauri-apps/tauri-plugin-window-state/12ac7a31bf71ab5c3e87add90d44b47cbfe95652/banner.png -------------------------------------------------------------------------------- /dist-js/index.d.ts: -------------------------------------------------------------------------------- 1 | import { WindowLabel } from "@tauri-apps/api/window"; 2 | export declare enum StateFlags { 3 | SIZE = 1, 4 | POSITION = 2, 5 | MAXIMIZED = 4, 6 | VISIBLE = 8, 7 | DECORATIONS = 16, 8 | FULLSCREEN = 32, 9 | ALL = 63 10 | } 11 | /** 12 | * Save the state of all open windows to disk. 13 | */ 14 | declare function saveWindowState(flags: StateFlags): Promise; 15 | /** 16 | * Restore the state for the specified window from disk. 17 | */ 18 | declare function restoreState(label: WindowLabel, flags: StateFlags): Promise; 19 | /** 20 | * Restore the state for the current window from disk. 21 | */ 22 | declare function restoreStateCurrent(flags: StateFlags): Promise; 23 | export { restoreState, restoreStateCurrent, saveWindowState }; 24 | -------------------------------------------------------------------------------- /dist-js/index.min.js: -------------------------------------------------------------------------------- 1 | // Copyright 2019-2023 Tauri Programme within The Commons Conservancy 2 | // SPDX-License-Identifier: Apache-2.0 3 | // SPDX-License-Identifier: MIT 4 | /** @ignore */ 5 | function uid() { 6 | return window.crypto.getRandomValues(new Uint32Array(1))[0]; 7 | } 8 | /** 9 | * Transforms a callback function to a string identifier that can be passed to the backend. 10 | * The backend uses the identifier to `eval()` the callback. 11 | * 12 | * @return A unique identifier associated with the callback function. 13 | * 14 | * @since 1.0.0 15 | */ 16 | function transformCallback(callback, once = false) { 17 | const identifier = uid(); 18 | const prop = `_${identifier}`; 19 | Object.defineProperty(window, prop, { 20 | value: (result) => { 21 | if (once) { 22 | Reflect.deleteProperty(window, prop); 23 | } 24 | return callback === null || callback === void 0 ? void 0 : callback(result); 25 | }, 26 | writable: false, 27 | configurable: true 28 | }); 29 | return identifier; 30 | } 31 | /** 32 | * Sends a message to the backend. 33 | * @example 34 | * ```typescript 35 | * import { invoke } from '@tauri-apps/api/tauri'; 36 | * await invoke('login', { user: 'tauri', password: 'poiwe3h4r5ip3yrhtew9ty' }); 37 | * ``` 38 | * 39 | * @param cmd The command name. 40 | * @param args The optional arguments to pass to the command. 41 | * @return A promise resolving or rejecting to the backend response. 42 | * 43 | * @since 1.0.0 44 | */ 45 | async function invoke(cmd, args = {}) { 46 | return new Promise((resolve, reject) => { 47 | const callback = transformCallback((e) => { 48 | resolve(e); 49 | Reflect.deleteProperty(window, `_${error}`); 50 | }, true); 51 | const error = transformCallback((e) => { 52 | reject(e); 53 | Reflect.deleteProperty(window, `_${callback}`); 54 | }, true); 55 | window.__TAURI_IPC__({ 56 | cmd, 57 | callback, 58 | error, 59 | ...args 60 | }); 61 | }); 62 | } 63 | 64 | // Copyright 2019-2023 Tauri Programme within The Commons Conservancy 65 | // SPDX-License-Identifier: Apache-2.0 66 | // SPDX-License-Identifier: MIT 67 | /** @ignore */ 68 | async function invokeTauriCommand(command) { 69 | return invoke('tauri', command); 70 | } 71 | 72 | // Copyright 2019-2023 Tauri Programme within The Commons Conservancy 73 | // SPDX-License-Identifier: Apache-2.0 74 | // SPDX-License-Identifier: MIT 75 | /** 76 | * Unregister the event listener associated with the given name and id. 77 | * 78 | * @ignore 79 | * @param event The event name 80 | * @param eventId Event identifier 81 | * @returns 82 | */ 83 | async function _unlisten(event, eventId) { 84 | return invokeTauriCommand({ 85 | __tauriModule: 'Event', 86 | message: { 87 | cmd: 'unlisten', 88 | event, 89 | eventId 90 | } 91 | }); 92 | } 93 | /** 94 | * Emits an event to the backend. 95 | * 96 | * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. 97 | * @param [windowLabel] The label of the window to which the event is sent, if null/undefined the event will be sent to all windows 98 | * @param [payload] Event payload 99 | * @returns 100 | */ 101 | async function emit(event, windowLabel, payload) { 102 | await invokeTauriCommand({ 103 | __tauriModule: 'Event', 104 | message: { 105 | cmd: 'emit', 106 | event, 107 | windowLabel, 108 | payload 109 | } 110 | }); 111 | } 112 | /** 113 | * Listen to an event from the backend. 114 | * 115 | * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. 116 | * @param handler Event handler callback. 117 | * @return A promise resolving to a function to unlisten to the event. 118 | */ 119 | async function listen(event, windowLabel, handler) { 120 | return invokeTauriCommand({ 121 | __tauriModule: 'Event', 122 | message: { 123 | cmd: 'listen', 124 | event, 125 | windowLabel, 126 | handler: transformCallback(handler) 127 | } 128 | }).then((eventId) => { 129 | return async () => _unlisten(event, eventId); 130 | }); 131 | } 132 | /** 133 | * Listen to an one-off event from the backend. 134 | * 135 | * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. 136 | * @param handler Event handler callback. 137 | * @returns A promise resolving to a function to unlisten to the event. 138 | */ 139 | async function once(event, windowLabel, handler) { 140 | return listen(event, windowLabel, (eventData) => { 141 | handler(eventData); 142 | _unlisten(event, eventData.id).catch(() => { }); 143 | }); 144 | } 145 | 146 | // Copyright 2019-2023 Tauri Programme within The Commons Conservancy 147 | // SPDX-License-Identifier: Apache-2.0 148 | // SPDX-License-Identifier: MIT 149 | /** 150 | * The event system allows you to emit events to the backend and listen to events from it. 151 | * 152 | * This package is also accessible with `window.__TAURI__.event` when [`build.withGlobalTauri`](https://tauri.app/v1/api/config/#buildconfig.withglobaltauri) in `tauri.conf.json` is set to `true`. 153 | * @module 154 | */ 155 | /** 156 | * @since 1.1.0 157 | */ 158 | var TauriEvent; 159 | (function (TauriEvent) { 160 | TauriEvent["WINDOW_RESIZED"] = "tauri://resize"; 161 | TauriEvent["WINDOW_MOVED"] = "tauri://move"; 162 | TauriEvent["WINDOW_CLOSE_REQUESTED"] = "tauri://close-requested"; 163 | TauriEvent["WINDOW_CREATED"] = "tauri://window-created"; 164 | TauriEvent["WINDOW_DESTROYED"] = "tauri://destroyed"; 165 | TauriEvent["WINDOW_FOCUS"] = "tauri://focus"; 166 | TauriEvent["WINDOW_BLUR"] = "tauri://blur"; 167 | TauriEvent["WINDOW_SCALE_FACTOR_CHANGED"] = "tauri://scale-change"; 168 | TauriEvent["WINDOW_THEME_CHANGED"] = "tauri://theme-changed"; 169 | TauriEvent["WINDOW_FILE_DROP"] = "tauri://file-drop"; 170 | TauriEvent["WINDOW_FILE_DROP_HOVER"] = "tauri://file-drop-hover"; 171 | TauriEvent["WINDOW_FILE_DROP_CANCELLED"] = "tauri://file-drop-cancelled"; 172 | TauriEvent["MENU"] = "tauri://menu"; 173 | TauriEvent["CHECK_UPDATE"] = "tauri://update"; 174 | TauriEvent["UPDATE_AVAILABLE"] = "tauri://update-available"; 175 | TauriEvent["INSTALL_UPDATE"] = "tauri://update-install"; 176 | TauriEvent["STATUS_UPDATE"] = "tauri://update-status"; 177 | TauriEvent["DOWNLOAD_PROGRESS"] = "tauri://update-download-progress"; 178 | })(TauriEvent || (TauriEvent = {})); 179 | 180 | // Copyright 2019-2023 Tauri Programme within The Commons Conservancy 181 | // SPDX-License-Identifier: Apache-2.0 182 | // SPDX-License-Identifier: MIT 183 | /** 184 | * Provides APIs to create windows, communicate with other windows and manipulate the current window. 185 | * 186 | * This package is also accessible with `window.__TAURI__.window` when [`build.withGlobalTauri`](https://tauri.app/v1/api/config/#buildconfig.withglobaltauri) in `tauri.conf.json` is set to `true`. 187 | * 188 | * The APIs must be added to [`tauri.allowlist.window`](https://tauri.app/v1/api/config/#allowlistconfig.window) in `tauri.conf.json`: 189 | * ```json 190 | * { 191 | * "tauri": { 192 | * "allowlist": { 193 | * "window": { 194 | * "all": true, // enable all window APIs 195 | * "create": true, // enable window creation 196 | * "center": true, 197 | * "requestUserAttention": true, 198 | * "setResizable": true, 199 | * "setMaximizable": true, 200 | * "setMinimizable": true, 201 | * "setClosable": true, 202 | * "setTitle": true, 203 | * "maximize": true, 204 | * "unmaximize": true, 205 | * "minimize": true, 206 | * "unminimize": true, 207 | * "show": true, 208 | * "hide": true, 209 | * "close": true, 210 | * "setDecorations": true, 211 | * "setAlwaysOnTop": true, 212 | * "setContentProtected": true, 213 | * "setSize": true, 214 | * "setMinSize": true, 215 | * "setMaxSize": true, 216 | * "setPosition": true, 217 | * "setFullscreen": true, 218 | * "setFocus": true, 219 | * "setIcon": true, 220 | * "setSkipTaskbar": true, 221 | * "setCursorGrab": true, 222 | * "setCursorVisible": true, 223 | * "setCursorIcon": true, 224 | * "setCursorPosition": true, 225 | * "setIgnoreCursorEvents": true, 226 | * "startDragging": true, 227 | * "print": true 228 | * } 229 | * } 230 | * } 231 | * } 232 | * ``` 233 | * It is recommended to allowlist only the APIs you use for optimal bundle size and security. 234 | * 235 | * ## Window events 236 | * 237 | * Events can be listened to using `appWindow.listen`: 238 | * ```typescript 239 | * import { appWindow } from "@tauri-apps/api/window"; 240 | * appWindow.listen("my-window-event", ({ event, payload }) => { }); 241 | * ``` 242 | * 243 | * @module 244 | */ 245 | /** 246 | * A size represented in logical pixels. 247 | * 248 | * @since 1.0.0 249 | */ 250 | class LogicalSize { 251 | constructor(width, height) { 252 | this.type = 'Logical'; 253 | this.width = width; 254 | this.height = height; 255 | } 256 | } 257 | /** 258 | * A size represented in physical pixels. 259 | * 260 | * @since 1.0.0 261 | */ 262 | class PhysicalSize { 263 | constructor(width, height) { 264 | this.type = 'Physical'; 265 | this.width = width; 266 | this.height = height; 267 | } 268 | /** 269 | * Converts the physical size to a logical one. 270 | * @example 271 | * ```typescript 272 | * import { appWindow } from '@tauri-apps/api/window'; 273 | * const factor = await appWindow.scaleFactor(); 274 | * const size = await appWindow.innerSize(); 275 | * const logical = size.toLogical(factor); 276 | * ``` 277 | * */ 278 | toLogical(scaleFactor) { 279 | return new LogicalSize(this.width / scaleFactor, this.height / scaleFactor); 280 | } 281 | } 282 | /** 283 | * A position represented in logical pixels. 284 | * 285 | * @since 1.0.0 286 | */ 287 | class LogicalPosition { 288 | constructor(x, y) { 289 | this.type = 'Logical'; 290 | this.x = x; 291 | this.y = y; 292 | } 293 | } 294 | /** 295 | * A position represented in physical pixels. 296 | * 297 | * @since 1.0.0 298 | */ 299 | class PhysicalPosition { 300 | constructor(x, y) { 301 | this.type = 'Physical'; 302 | this.x = x; 303 | this.y = y; 304 | } 305 | /** 306 | * Converts the physical position to a logical one. 307 | * @example 308 | * ```typescript 309 | * import { appWindow } from '@tauri-apps/api/window'; 310 | * const factor = await appWindow.scaleFactor(); 311 | * const position = await appWindow.innerPosition(); 312 | * const logical = position.toLogical(factor); 313 | * ``` 314 | * */ 315 | toLogical(scaleFactor) { 316 | return new LogicalPosition(this.x / scaleFactor, this.y / scaleFactor); 317 | } 318 | } 319 | /** 320 | * Attention type to request on a window. 321 | * 322 | * @since 1.0.0 323 | */ 324 | var UserAttentionType; 325 | (function (UserAttentionType) { 326 | /** 327 | * #### Platform-specific 328 | * - **macOS:** Bounces the dock icon until the application is in focus. 329 | * - **Windows:** Flashes both the window and the taskbar button until the application is in focus. 330 | */ 331 | UserAttentionType[UserAttentionType["Critical"] = 1] = "Critical"; 332 | /** 333 | * #### Platform-specific 334 | * - **macOS:** Bounces the dock icon once. 335 | * - **Windows:** Flashes the taskbar button until the application is in focus. 336 | */ 337 | UserAttentionType[UserAttentionType["Informational"] = 2] = "Informational"; 338 | })(UserAttentionType || (UserAttentionType = {})); 339 | /** 340 | * Get an instance of `WebviewWindow` for the current webview window. 341 | * 342 | * @since 1.0.0 343 | */ 344 | function getCurrent() { 345 | return new WebviewWindow(window.__TAURI_METADATA__.__currentWindow.label, { 346 | // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor 347 | skip: true 348 | }); 349 | } 350 | /** 351 | * Gets a list of instances of `WebviewWindow` for all available webview windows. 352 | * 353 | * @since 1.0.0 354 | */ 355 | function getAll() { 356 | return window.__TAURI_METADATA__.__windows.map((w) => new WebviewWindow(w.label, { 357 | // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor 358 | skip: true 359 | })); 360 | } 361 | /** @ignore */ 362 | // events that are emitted right here instead of by the created webview 363 | const localTauriEvents = ['tauri://created', 'tauri://error']; 364 | /** 365 | * A webview window handle allows emitting and listening to events from the backend that are tied to the window. 366 | * 367 | * @ignore 368 | * @since 1.0.0 369 | */ 370 | class WebviewWindowHandle { 371 | constructor(label) { 372 | this.label = label; 373 | // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment 374 | this.listeners = Object.create(null); 375 | } 376 | /** 377 | * Listen to an event emitted by the backend or webview. 378 | * The event must either be a global event or an event targetting this window. 379 | * 380 | * See {@link WebviewWindow.emit | `emit`} for more information. 381 | * 382 | * @example 383 | * ```typescript 384 | * import { appWindow } from '@tauri-apps/api/window'; 385 | * const unlisten = await appWindow.listen('state-changed', (event) => { 386 | * console.log(`Got error: ${payload}`); 387 | * }); 388 | * 389 | * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted 390 | * unlisten(); 391 | * ``` 392 | * 393 | * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. 394 | * 395 | * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. 396 | * @param handler Event handler. 397 | * @returns A promise resolving to a function to unlisten to the event. 398 | */ 399 | async listen(event, handler) { 400 | if (this._handleTauriEvent(event, handler)) { 401 | return Promise.resolve(() => { 402 | // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, security/detect-object-injection 403 | const listeners = this.listeners[event]; 404 | listeners.splice(listeners.indexOf(handler), 1); 405 | }); 406 | } 407 | return listen(event, this.label, handler); 408 | } 409 | /** 410 | * Listen to an one-off event. 411 | * See {@link WebviewWindow.listen | `listen`} for more information. 412 | * 413 | * @example 414 | * ```typescript 415 | * import { appWindow } from '@tauri-apps/api/window'; 416 | * const unlisten = await appWindow.once('initialized', (event) => { 417 | * console.log(`Window initialized!`); 418 | * }); 419 | * 420 | * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted 421 | * unlisten(); 422 | * ``` 423 | * 424 | * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. 425 | * 426 | * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. 427 | * @param handler Event handler. 428 | * @returns A promise resolving to a function to unlisten to the event. 429 | */ 430 | async once(event, handler) { 431 | if (this._handleTauriEvent(event, handler)) { 432 | return Promise.resolve(() => { 433 | // eslint-disable-next-line security/detect-object-injection 434 | const listeners = this.listeners[event]; 435 | listeners.splice(listeners.indexOf(handler), 1); 436 | }); 437 | } 438 | return once(event, this.label, handler); 439 | } 440 | /** 441 | * Emits an event to the backend and all Tauri windows. 442 | * The event will have this window's {@link WebviewWindow.label | label} as {@link Event.windowLabel | source window label}. 443 | * 444 | * @example 445 | * ```typescript 446 | * import { appWindow } from '@tauri-apps/api/window'; 447 | * await appWindow.emit('window-loaded', { loggedIn: true, token: 'authToken' }); 448 | * ``` 449 | * 450 | * This function can also be used to communicate between windows: 451 | * ```typescript 452 | * import { appWindow } from '@tauri-apps/api/window'; 453 | * await appWindow.listen('sync-data', (event) => { }); 454 | * 455 | * // on another window... 456 | * import { WebviewWindow } from '@tauri-apps/api/window'; 457 | * const otherWindow = WebviewWindow.getByLabel('other') 458 | * await otherWindow.emit('sync-data'); 459 | * ``` 460 | * 461 | * Global listeners are also triggered: 462 | * ```typescript 463 | * import { appWindow } from '@tauri-apps/api/window'; 464 | * import { listen } from '@tauri-apps/api/event'; 465 | * await listen('ping', (event) => { }); 466 | * 467 | * await appWindow.emit('ping'); 468 | * ``` 469 | * 470 | * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. 471 | * @param payload Event payload. 472 | */ 473 | async emit(event, payload) { 474 | if (localTauriEvents.includes(event)) { 475 | // eslint-disable-next-line 476 | for (const handler of this.listeners[event] || []) { 477 | handler({ event, id: -1, windowLabel: this.label, payload }); 478 | } 479 | return Promise.resolve(); 480 | } 481 | return emit(event, this.label, payload); 482 | } 483 | /** @ignore */ 484 | _handleTauriEvent(event, handler) { 485 | if (localTauriEvents.includes(event)) { 486 | if (!(event in this.listeners)) { 487 | // eslint-disable-next-line 488 | this.listeners[event] = [handler]; 489 | } 490 | else { 491 | // eslint-disable-next-line 492 | this.listeners[event].push(handler); 493 | } 494 | return true; 495 | } 496 | return false; 497 | } 498 | } 499 | /** 500 | * Manage the current window object. 501 | * 502 | * @ignore 503 | * @since 1.0.0 504 | */ 505 | class WindowManager extends WebviewWindowHandle { 506 | // Getters 507 | /** 508 | * The scale factor that can be used to map physical pixels to logical pixels. 509 | * @example 510 | * ```typescript 511 | * import { appWindow } from '@tauri-apps/api/window'; 512 | * const factor = await appWindow.scaleFactor(); 513 | * ``` 514 | * 515 | * @returns The window's monitor scale factor. 516 | * */ 517 | async scaleFactor() { 518 | return invokeTauriCommand({ 519 | __tauriModule: 'Window', 520 | message: { 521 | cmd: 'manage', 522 | data: { 523 | label: this.label, 524 | cmd: { 525 | type: 'scaleFactor' 526 | } 527 | } 528 | } 529 | }); 530 | } 531 | /** 532 | * The position of the top-left hand corner of the window's client area relative to the top-left hand corner of the desktop. 533 | * @example 534 | * ```typescript 535 | * import { appWindow } from '@tauri-apps/api/window'; 536 | * const position = await appWindow.innerPosition(); 537 | * ``` 538 | * 539 | * @returns The window's inner position. 540 | * */ 541 | async innerPosition() { 542 | return invokeTauriCommand({ 543 | __tauriModule: 'Window', 544 | message: { 545 | cmd: 'manage', 546 | data: { 547 | label: this.label, 548 | cmd: { 549 | type: 'innerPosition' 550 | } 551 | } 552 | } 553 | }).then(({ x, y }) => new PhysicalPosition(x, y)); 554 | } 555 | /** 556 | * The position of the top-left hand corner of the window relative to the top-left hand corner of the desktop. 557 | * @example 558 | * ```typescript 559 | * import { appWindow } from '@tauri-apps/api/window'; 560 | * const position = await appWindow.outerPosition(); 561 | * ``` 562 | * 563 | * @returns The window's outer position. 564 | * */ 565 | async outerPosition() { 566 | return invokeTauriCommand({ 567 | __tauriModule: 'Window', 568 | message: { 569 | cmd: 'manage', 570 | data: { 571 | label: this.label, 572 | cmd: { 573 | type: 'outerPosition' 574 | } 575 | } 576 | } 577 | }).then(({ x, y }) => new PhysicalPosition(x, y)); 578 | } 579 | /** 580 | * The physical size of the window's client area. 581 | * The client area is the content of the window, excluding the title bar and borders. 582 | * @example 583 | * ```typescript 584 | * import { appWindow } from '@tauri-apps/api/window'; 585 | * const size = await appWindow.innerSize(); 586 | * ``` 587 | * 588 | * @returns The window's inner size. 589 | */ 590 | async innerSize() { 591 | return invokeTauriCommand({ 592 | __tauriModule: 'Window', 593 | message: { 594 | cmd: 'manage', 595 | data: { 596 | label: this.label, 597 | cmd: { 598 | type: 'innerSize' 599 | } 600 | } 601 | } 602 | }).then(({ width, height }) => new PhysicalSize(width, height)); 603 | } 604 | /** 605 | * The physical size of the entire window. 606 | * These dimensions include the title bar and borders. If you don't want that (and you usually don't), use inner_size instead. 607 | * @example 608 | * ```typescript 609 | * import { appWindow } from '@tauri-apps/api/window'; 610 | * const size = await appWindow.outerSize(); 611 | * ``` 612 | * 613 | * @returns The window's outer size. 614 | */ 615 | async outerSize() { 616 | return invokeTauriCommand({ 617 | __tauriModule: 'Window', 618 | message: { 619 | cmd: 'manage', 620 | data: { 621 | label: this.label, 622 | cmd: { 623 | type: 'outerSize' 624 | } 625 | } 626 | } 627 | }).then(({ width, height }) => new PhysicalSize(width, height)); 628 | } 629 | /** 630 | * Gets the window's current fullscreen state. 631 | * @example 632 | * ```typescript 633 | * import { appWindow } from '@tauri-apps/api/window'; 634 | * const fullscreen = await appWindow.isFullscreen(); 635 | * ``` 636 | * 637 | * @returns Whether the window is in fullscreen mode or not. 638 | * */ 639 | async isFullscreen() { 640 | return invokeTauriCommand({ 641 | __tauriModule: 'Window', 642 | message: { 643 | cmd: 'manage', 644 | data: { 645 | label: this.label, 646 | cmd: { 647 | type: 'isFullscreen' 648 | } 649 | } 650 | } 651 | }); 652 | } 653 | /** 654 | * Gets the window's current minimized state. 655 | * @example 656 | * ```typescript 657 | * import { appWindow } from '@tauri-apps/api/window'; 658 | * const minimized = await appWindow.isMinimized(); 659 | * ``` 660 | * 661 | * @since 1.3.0 662 | * */ 663 | async isMinimized() { 664 | return invokeTauriCommand({ 665 | __tauriModule: 'Window', 666 | message: { 667 | cmd: 'manage', 668 | data: { 669 | label: this.label, 670 | cmd: { 671 | type: 'isMinimized' 672 | } 673 | } 674 | } 675 | }); 676 | } 677 | /** 678 | * Gets the window's current maximized state. 679 | * @example 680 | * ```typescript 681 | * import { appWindow } from '@tauri-apps/api/window'; 682 | * const maximized = await appWindow.isMaximized(); 683 | * ``` 684 | * 685 | * @returns Whether the window is maximized or not. 686 | * */ 687 | async isMaximized() { 688 | return invokeTauriCommand({ 689 | __tauriModule: 'Window', 690 | message: { 691 | cmd: 'manage', 692 | data: { 693 | label: this.label, 694 | cmd: { 695 | type: 'isMaximized' 696 | } 697 | } 698 | } 699 | }); 700 | } 701 | /** 702 | * Gets the window's current focus state. 703 | * @example 704 | * ```typescript 705 | * import { appWindow } from '@tauri-apps/api/window'; 706 | * const focused = await appWindow.isFocused(); 707 | * ``` 708 | * 709 | * @returns Whether the window is focused or not. 710 | * 711 | * @since 1.4 712 | * */ 713 | async isFocused() { 714 | return invokeTauriCommand({ 715 | __tauriModule: 'Window', 716 | message: { 717 | cmd: 'manage', 718 | data: { 719 | label: this.label, 720 | cmd: { 721 | type: 'isFocused' 722 | } 723 | } 724 | } 725 | }); 726 | } 727 | /** 728 | * Gets the window's current decorated state. 729 | * @example 730 | * ```typescript 731 | * import { appWindow } from '@tauri-apps/api/window'; 732 | * const decorated = await appWindow.isDecorated(); 733 | * ``` 734 | * 735 | * @returns Whether the window is decorated or not. 736 | * */ 737 | async isDecorated() { 738 | return invokeTauriCommand({ 739 | __tauriModule: 'Window', 740 | message: { 741 | cmd: 'manage', 742 | data: { 743 | label: this.label, 744 | cmd: { 745 | type: 'isDecorated' 746 | } 747 | } 748 | } 749 | }); 750 | } 751 | /** 752 | * Gets the window's current resizable state. 753 | * @example 754 | * ```typescript 755 | * import { appWindow } from '@tauri-apps/api/window'; 756 | * const resizable = await appWindow.isResizable(); 757 | * ``` 758 | * 759 | * @returns Whether the window is resizable or not. 760 | * */ 761 | async isResizable() { 762 | return invokeTauriCommand({ 763 | __tauriModule: 'Window', 764 | message: { 765 | cmd: 'manage', 766 | data: { 767 | label: this.label, 768 | cmd: { 769 | type: 'isResizable' 770 | } 771 | } 772 | } 773 | }); 774 | } 775 | /** 776 | * Gets the window’s native maximize button state. 777 | * 778 | * #### Platform-specific 779 | * 780 | * - **Linux / iOS / Android:** Unsupported. 781 | * 782 | * @example 783 | * ```typescript 784 | * import { appWindow } from '@tauri-apps/api/window'; 785 | * const maximizable = await appWindow.isMaximizable(); 786 | * ``` 787 | * 788 | * @returns Whether the window's native maximize button is enabled or not. 789 | * */ 790 | async isMaximizable() { 791 | return invokeTauriCommand({ 792 | __tauriModule: 'Window', 793 | message: { 794 | cmd: 'manage', 795 | data: { 796 | label: this.label, 797 | cmd: { 798 | type: 'isMaximizable' 799 | } 800 | } 801 | } 802 | }); 803 | } 804 | /** 805 | * Gets the window’s native minimize button state. 806 | * 807 | * #### Platform-specific 808 | * 809 | * - **Linux / iOS / Android:** Unsupported. 810 | * 811 | * @example 812 | * ```typescript 813 | * import { appWindow } from '@tauri-apps/api/window'; 814 | * const minimizable = await appWindow.isMinimizable(); 815 | * ``` 816 | * 817 | * @returns Whether the window's native minimize button is enabled or not. 818 | * */ 819 | async isMinimizable() { 820 | return invokeTauriCommand({ 821 | __tauriModule: 'Window', 822 | message: { 823 | cmd: 'manage', 824 | data: { 825 | label: this.label, 826 | cmd: { 827 | type: 'isMinimizable' 828 | } 829 | } 830 | } 831 | }); 832 | } 833 | /** 834 | * Gets the window’s native close button state. 835 | * 836 | * #### Platform-specific 837 | * 838 | * - **Linux / iOS / Android:** Unsupported. 839 | * 840 | * @example 841 | * ```typescript 842 | * import { appWindow } from '@tauri-apps/api/window'; 843 | * const closable = await appWindow.isClosable(); 844 | * ``` 845 | * 846 | * @returns Whether the window's native close button is enabled or not. 847 | * */ 848 | async isClosable() { 849 | return invokeTauriCommand({ 850 | __tauriModule: 'Window', 851 | message: { 852 | cmd: 'manage', 853 | data: { 854 | label: this.label, 855 | cmd: { 856 | type: 'isClosable' 857 | } 858 | } 859 | } 860 | }); 861 | } 862 | /** 863 | * Gets the window's current visible state. 864 | * @example 865 | * ```typescript 866 | * import { appWindow } from '@tauri-apps/api/window'; 867 | * const visible = await appWindow.isVisible(); 868 | * ``` 869 | * 870 | * @returns Whether the window is visible or not. 871 | * */ 872 | async isVisible() { 873 | return invokeTauriCommand({ 874 | __tauriModule: 'Window', 875 | message: { 876 | cmd: 'manage', 877 | data: { 878 | label: this.label, 879 | cmd: { 880 | type: 'isVisible' 881 | } 882 | } 883 | } 884 | }); 885 | } 886 | /** 887 | * Gets the window's current title. 888 | * @example 889 | * ```typescript 890 | * import { appWindow } from '@tauri-apps/api/window'; 891 | * const title = await appWindow.title(); 892 | * ``` 893 | * 894 | * @since 1.3.0 895 | * */ 896 | async title() { 897 | return invokeTauriCommand({ 898 | __tauriModule: 'Window', 899 | message: { 900 | cmd: 'manage', 901 | data: { 902 | label: this.label, 903 | cmd: { 904 | type: 'title' 905 | } 906 | } 907 | } 908 | }); 909 | } 910 | /** 911 | * Gets the window's current theme. 912 | * 913 | * #### Platform-specific 914 | * 915 | * - **macOS:** Theme was introduced on macOS 10.14. Returns `light` on macOS 10.13 and below. 916 | * 917 | * @example 918 | * ```typescript 919 | * import { appWindow } from '@tauri-apps/api/window'; 920 | * const theme = await appWindow.theme(); 921 | * ``` 922 | * 923 | * @returns The window theme. 924 | * */ 925 | async theme() { 926 | return invokeTauriCommand({ 927 | __tauriModule: 'Window', 928 | message: { 929 | cmd: 'manage', 930 | data: { 931 | label: this.label, 932 | cmd: { 933 | type: 'theme' 934 | } 935 | } 936 | } 937 | }); 938 | } 939 | // Setters 940 | /** 941 | * Centers the window. 942 | * @example 943 | * ```typescript 944 | * import { appWindow } from '@tauri-apps/api/window'; 945 | * await appWindow.center(); 946 | * ``` 947 | * 948 | * @returns A promise indicating the success or failure of the operation. 949 | */ 950 | async center() { 951 | return invokeTauriCommand({ 952 | __tauriModule: 'Window', 953 | message: { 954 | cmd: 'manage', 955 | data: { 956 | label: this.label, 957 | cmd: { 958 | type: 'center' 959 | } 960 | } 961 | } 962 | }); 963 | } 964 | /** 965 | * Requests user attention to the window, this has no effect if the application 966 | * is already focused. How requesting for user attention manifests is platform dependent, 967 | * see `UserAttentionType` for details. 968 | * 969 | * Providing `null` will unset the request for user attention. Unsetting the request for 970 | * user attention might not be done automatically by the WM when the window receives input. 971 | * 972 | * #### Platform-specific 973 | * 974 | * - **macOS:** `null` has no effect. 975 | * - **Linux:** Urgency levels have the same effect. 976 | * @example 977 | * ```typescript 978 | * import { appWindow } from '@tauri-apps/api/window'; 979 | * await appWindow.requestUserAttention(); 980 | * ``` 981 | * 982 | * @param requestType 983 | * @returns A promise indicating the success or failure of the operation. 984 | */ 985 | async requestUserAttention(requestType) { 986 | let requestType_ = null; 987 | if (requestType) { 988 | if (requestType === UserAttentionType.Critical) { 989 | requestType_ = { type: 'Critical' }; 990 | } 991 | else { 992 | requestType_ = { type: 'Informational' }; 993 | } 994 | } 995 | return invokeTauriCommand({ 996 | __tauriModule: 'Window', 997 | message: { 998 | cmd: 'manage', 999 | data: { 1000 | label: this.label, 1001 | cmd: { 1002 | type: 'requestUserAttention', 1003 | payload: requestType_ 1004 | } 1005 | } 1006 | } 1007 | }); 1008 | } 1009 | /** 1010 | * Updates the window resizable flag. 1011 | * @example 1012 | * ```typescript 1013 | * import { appWindow } from '@tauri-apps/api/window'; 1014 | * await appWindow.setResizable(false); 1015 | * ``` 1016 | * 1017 | * @param resizable 1018 | * @returns A promise indicating the success or failure of the operation. 1019 | */ 1020 | async setResizable(resizable) { 1021 | return invokeTauriCommand({ 1022 | __tauriModule: 'Window', 1023 | message: { 1024 | cmd: 'manage', 1025 | data: { 1026 | label: this.label, 1027 | cmd: { 1028 | type: 'setResizable', 1029 | payload: resizable 1030 | } 1031 | } 1032 | } 1033 | }); 1034 | } 1035 | /** 1036 | * Sets whether the window's native maximize button is enabled or not. 1037 | * If resizable is set to false, this setting is ignored. 1038 | * 1039 | * #### Platform-specific 1040 | * 1041 | * - **macOS:** Disables the "zoom" button in the window titlebar, which is also used to enter fullscreen mode. 1042 | * - **Linux / iOS / Android:** Unsupported. 1043 | * 1044 | * @example 1045 | * ```typescript 1046 | * import { appWindow } from '@tauri-apps/api/window'; 1047 | * await appWindow.setMaximizable(false); 1048 | * ``` 1049 | * 1050 | * @param maximizable 1051 | * @returns A promise indicating the success or failure of the operation. 1052 | */ 1053 | async setMaximizable(maximizable) { 1054 | return invokeTauriCommand({ 1055 | __tauriModule: 'Window', 1056 | message: { 1057 | cmd: 'manage', 1058 | data: { 1059 | label: this.label, 1060 | cmd: { 1061 | type: 'setMaximizable', 1062 | payload: maximizable 1063 | } 1064 | } 1065 | } 1066 | }); 1067 | } 1068 | /** 1069 | * Sets whether the window's native minimize button is enabled or not. 1070 | * 1071 | * #### Platform-specific 1072 | * 1073 | * - **Linux / iOS / Android:** Unsupported. 1074 | * 1075 | * @example 1076 | * ```typescript 1077 | * import { appWindow } from '@tauri-apps/api/window'; 1078 | * await appWindow.setMinimizable(false); 1079 | * ``` 1080 | * 1081 | * @param minimizable 1082 | * @returns A promise indicating the success or failure of the operation. 1083 | */ 1084 | async setMinimizable(minimizable) { 1085 | return invokeTauriCommand({ 1086 | __tauriModule: 'Window', 1087 | message: { 1088 | cmd: 'manage', 1089 | data: { 1090 | label: this.label, 1091 | cmd: { 1092 | type: 'setMinimizable', 1093 | payload: minimizable 1094 | } 1095 | } 1096 | } 1097 | }); 1098 | } 1099 | /** 1100 | * Sets whether the window's native close button is enabled or not. 1101 | * 1102 | * #### Platform-specific 1103 | * 1104 | * - **Linux:** GTK+ will do its best to convince the window manager not to show a close button. Depending on the system, this function may not have any effect when called on a window that is already visible 1105 | * - **iOS / Android:** Unsupported. 1106 | * 1107 | * @example 1108 | * ```typescript 1109 | * import { appWindow } from '@tauri-apps/api/window'; 1110 | * await appWindow.setClosable(false); 1111 | * ``` 1112 | * 1113 | * @param closable 1114 | * @returns A promise indicating the success or failure of the operation. 1115 | */ 1116 | async setClosable(closable) { 1117 | return invokeTauriCommand({ 1118 | __tauriModule: 'Window', 1119 | message: { 1120 | cmd: 'manage', 1121 | data: { 1122 | label: this.label, 1123 | cmd: { 1124 | type: 'setClosable', 1125 | payload: closable 1126 | } 1127 | } 1128 | } 1129 | }); 1130 | } 1131 | /** 1132 | * Sets the window title. 1133 | * @example 1134 | * ```typescript 1135 | * import { appWindow } from '@tauri-apps/api/window'; 1136 | * await appWindow.setTitle('Tauri'); 1137 | * ``` 1138 | * 1139 | * @param title The new title 1140 | * @returns A promise indicating the success or failure of the operation. 1141 | */ 1142 | async setTitle(title) { 1143 | return invokeTauriCommand({ 1144 | __tauriModule: 'Window', 1145 | message: { 1146 | cmd: 'manage', 1147 | data: { 1148 | label: this.label, 1149 | cmd: { 1150 | type: 'setTitle', 1151 | payload: title 1152 | } 1153 | } 1154 | } 1155 | }); 1156 | } 1157 | /** 1158 | * Maximizes the window. 1159 | * @example 1160 | * ```typescript 1161 | * import { appWindow } from '@tauri-apps/api/window'; 1162 | * await appWindow.maximize(); 1163 | * ``` 1164 | * 1165 | * @returns A promise indicating the success or failure of the operation. 1166 | */ 1167 | async maximize() { 1168 | return invokeTauriCommand({ 1169 | __tauriModule: 'Window', 1170 | message: { 1171 | cmd: 'manage', 1172 | data: { 1173 | label: this.label, 1174 | cmd: { 1175 | type: 'maximize' 1176 | } 1177 | } 1178 | } 1179 | }); 1180 | } 1181 | /** 1182 | * Unmaximizes the window. 1183 | * @example 1184 | * ```typescript 1185 | * import { appWindow } from '@tauri-apps/api/window'; 1186 | * await appWindow.unmaximize(); 1187 | * ``` 1188 | * 1189 | * @returns A promise indicating the success or failure of the operation. 1190 | */ 1191 | async unmaximize() { 1192 | return invokeTauriCommand({ 1193 | __tauriModule: 'Window', 1194 | message: { 1195 | cmd: 'manage', 1196 | data: { 1197 | label: this.label, 1198 | cmd: { 1199 | type: 'unmaximize' 1200 | } 1201 | } 1202 | } 1203 | }); 1204 | } 1205 | /** 1206 | * Toggles the window maximized state. 1207 | * @example 1208 | * ```typescript 1209 | * import { appWindow } from '@tauri-apps/api/window'; 1210 | * await appWindow.toggleMaximize(); 1211 | * ``` 1212 | * 1213 | * @returns A promise indicating the success or failure of the operation. 1214 | */ 1215 | async toggleMaximize() { 1216 | return invokeTauriCommand({ 1217 | __tauriModule: 'Window', 1218 | message: { 1219 | cmd: 'manage', 1220 | data: { 1221 | label: this.label, 1222 | cmd: { 1223 | type: 'toggleMaximize' 1224 | } 1225 | } 1226 | } 1227 | }); 1228 | } 1229 | /** 1230 | * Minimizes the window. 1231 | * @example 1232 | * ```typescript 1233 | * import { appWindow } from '@tauri-apps/api/window'; 1234 | * await appWindow.minimize(); 1235 | * ``` 1236 | * 1237 | * @returns A promise indicating the success or failure of the operation. 1238 | */ 1239 | async minimize() { 1240 | return invokeTauriCommand({ 1241 | __tauriModule: 'Window', 1242 | message: { 1243 | cmd: 'manage', 1244 | data: { 1245 | label: this.label, 1246 | cmd: { 1247 | type: 'minimize' 1248 | } 1249 | } 1250 | } 1251 | }); 1252 | } 1253 | /** 1254 | * Unminimizes the window. 1255 | * @example 1256 | * ```typescript 1257 | * import { appWindow } from '@tauri-apps/api/window'; 1258 | * await appWindow.unminimize(); 1259 | * ``` 1260 | * 1261 | * @returns A promise indicating the success or failure of the operation. 1262 | */ 1263 | async unminimize() { 1264 | return invokeTauriCommand({ 1265 | __tauriModule: 'Window', 1266 | message: { 1267 | cmd: 'manage', 1268 | data: { 1269 | label: this.label, 1270 | cmd: { 1271 | type: 'unminimize' 1272 | } 1273 | } 1274 | } 1275 | }); 1276 | } 1277 | /** 1278 | * Sets the window visibility to true. 1279 | * @example 1280 | * ```typescript 1281 | * import { appWindow } from '@tauri-apps/api/window'; 1282 | * await appWindow.show(); 1283 | * ``` 1284 | * 1285 | * @returns A promise indicating the success or failure of the operation. 1286 | */ 1287 | async show() { 1288 | return invokeTauriCommand({ 1289 | __tauriModule: 'Window', 1290 | message: { 1291 | cmd: 'manage', 1292 | data: { 1293 | label: this.label, 1294 | cmd: { 1295 | type: 'show' 1296 | } 1297 | } 1298 | } 1299 | }); 1300 | } 1301 | /** 1302 | * Sets the window visibility to false. 1303 | * @example 1304 | * ```typescript 1305 | * import { appWindow } from '@tauri-apps/api/window'; 1306 | * await appWindow.hide(); 1307 | * ``` 1308 | * 1309 | * @returns A promise indicating the success or failure of the operation. 1310 | */ 1311 | async hide() { 1312 | return invokeTauriCommand({ 1313 | __tauriModule: 'Window', 1314 | message: { 1315 | cmd: 'manage', 1316 | data: { 1317 | label: this.label, 1318 | cmd: { 1319 | type: 'hide' 1320 | } 1321 | } 1322 | } 1323 | }); 1324 | } 1325 | /** 1326 | * Closes the window. 1327 | * @example 1328 | * ```typescript 1329 | * import { appWindow } from '@tauri-apps/api/window'; 1330 | * await appWindow.close(); 1331 | * ``` 1332 | * 1333 | * @returns A promise indicating the success or failure of the operation. 1334 | */ 1335 | async close() { 1336 | return invokeTauriCommand({ 1337 | __tauriModule: 'Window', 1338 | message: { 1339 | cmd: 'manage', 1340 | data: { 1341 | label: this.label, 1342 | cmd: { 1343 | type: 'close' 1344 | } 1345 | } 1346 | } 1347 | }); 1348 | } 1349 | /** 1350 | * Whether the window should have borders and bars. 1351 | * @example 1352 | * ```typescript 1353 | * import { appWindow } from '@tauri-apps/api/window'; 1354 | * await appWindow.setDecorations(false); 1355 | * ``` 1356 | * 1357 | * @param decorations Whether the window should have borders and bars. 1358 | * @returns A promise indicating the success or failure of the operation. 1359 | */ 1360 | async setDecorations(decorations) { 1361 | return invokeTauriCommand({ 1362 | __tauriModule: 'Window', 1363 | message: { 1364 | cmd: 'manage', 1365 | data: { 1366 | label: this.label, 1367 | cmd: { 1368 | type: 'setDecorations', 1369 | payload: decorations 1370 | } 1371 | } 1372 | } 1373 | }); 1374 | } 1375 | /** 1376 | * Whether the window should always be on top of other windows. 1377 | * @example 1378 | * ```typescript 1379 | * import { appWindow } from '@tauri-apps/api/window'; 1380 | * await appWindow.setAlwaysOnTop(true); 1381 | * ``` 1382 | * 1383 | * @param alwaysOnTop Whether the window should always be on top of other windows or not. 1384 | * @returns A promise indicating the success or failure of the operation. 1385 | */ 1386 | async setAlwaysOnTop(alwaysOnTop) { 1387 | return invokeTauriCommand({ 1388 | __tauriModule: 'Window', 1389 | message: { 1390 | cmd: 'manage', 1391 | data: { 1392 | label: this.label, 1393 | cmd: { 1394 | type: 'setAlwaysOnTop', 1395 | payload: alwaysOnTop 1396 | } 1397 | } 1398 | } 1399 | }); 1400 | } 1401 | /** 1402 | * Prevents the window contents from being captured by other apps. 1403 | * @example 1404 | * ```typescript 1405 | * import { appWindow } from '@tauri-apps/api/window'; 1406 | * await appWindow.setContentProtected(true); 1407 | * ``` 1408 | * 1409 | * @returns A promise indicating the success or failure of the operation. 1410 | * 1411 | * @since 1.2.0 1412 | */ 1413 | async setContentProtected(protected_) { 1414 | return invokeTauriCommand({ 1415 | __tauriModule: 'Window', 1416 | message: { 1417 | cmd: 'manage', 1418 | data: { 1419 | label: this.label, 1420 | cmd: { 1421 | type: 'setContentProtected', 1422 | payload: protected_ 1423 | } 1424 | } 1425 | } 1426 | }); 1427 | } 1428 | /** 1429 | * Resizes the window with a new inner size. 1430 | * @example 1431 | * ```typescript 1432 | * import { appWindow, LogicalSize } from '@tauri-apps/api/window'; 1433 | * await appWindow.setSize(new LogicalSize(600, 500)); 1434 | * ``` 1435 | * 1436 | * @param size The logical or physical inner size. 1437 | * @returns A promise indicating the success or failure of the operation. 1438 | */ 1439 | async setSize(size) { 1440 | if (!size || (size.type !== 'Logical' && size.type !== 'Physical')) { 1441 | throw new Error('the `size` argument must be either a LogicalSize or a PhysicalSize instance'); 1442 | } 1443 | return invokeTauriCommand({ 1444 | __tauriModule: 'Window', 1445 | message: { 1446 | cmd: 'manage', 1447 | data: { 1448 | label: this.label, 1449 | cmd: { 1450 | type: 'setSize', 1451 | payload: { 1452 | type: size.type, 1453 | data: { 1454 | width: size.width, 1455 | height: size.height 1456 | } 1457 | } 1458 | } 1459 | } 1460 | } 1461 | }); 1462 | } 1463 | /** 1464 | * Sets the window minimum inner size. If the `size` argument is not provided, the constraint is unset. 1465 | * @example 1466 | * ```typescript 1467 | * import { appWindow, PhysicalSize } from '@tauri-apps/api/window'; 1468 | * await appWindow.setMinSize(new PhysicalSize(600, 500)); 1469 | * ``` 1470 | * 1471 | * @param size The logical or physical inner size, or `null` to unset the constraint. 1472 | * @returns A promise indicating the success or failure of the operation. 1473 | */ 1474 | async setMinSize(size) { 1475 | if (size && size.type !== 'Logical' && size.type !== 'Physical') { 1476 | throw new Error('the `size` argument must be either a LogicalSize or a PhysicalSize instance'); 1477 | } 1478 | return invokeTauriCommand({ 1479 | __tauriModule: 'Window', 1480 | message: { 1481 | cmd: 'manage', 1482 | data: { 1483 | label: this.label, 1484 | cmd: { 1485 | type: 'setMinSize', 1486 | payload: size 1487 | ? { 1488 | type: size.type, 1489 | data: { 1490 | width: size.width, 1491 | height: size.height 1492 | } 1493 | } 1494 | : null 1495 | } 1496 | } 1497 | } 1498 | }); 1499 | } 1500 | /** 1501 | * Sets the window maximum inner size. If the `size` argument is undefined, the constraint is unset. 1502 | * @example 1503 | * ```typescript 1504 | * import { appWindow, LogicalSize } from '@tauri-apps/api/window'; 1505 | * await appWindow.setMaxSize(new LogicalSize(600, 500)); 1506 | * ``` 1507 | * 1508 | * @param size The logical or physical inner size, or `null` to unset the constraint. 1509 | * @returns A promise indicating the success or failure of the operation. 1510 | */ 1511 | async setMaxSize(size) { 1512 | if (size && size.type !== 'Logical' && size.type !== 'Physical') { 1513 | throw new Error('the `size` argument must be either a LogicalSize or a PhysicalSize instance'); 1514 | } 1515 | return invokeTauriCommand({ 1516 | __tauriModule: 'Window', 1517 | message: { 1518 | cmd: 'manage', 1519 | data: { 1520 | label: this.label, 1521 | cmd: { 1522 | type: 'setMaxSize', 1523 | payload: size 1524 | ? { 1525 | type: size.type, 1526 | data: { 1527 | width: size.width, 1528 | height: size.height 1529 | } 1530 | } 1531 | : null 1532 | } 1533 | } 1534 | } 1535 | }); 1536 | } 1537 | /** 1538 | * Sets the window outer position. 1539 | * @example 1540 | * ```typescript 1541 | * import { appWindow, LogicalPosition } from '@tauri-apps/api/window'; 1542 | * await appWindow.setPosition(new LogicalPosition(600, 500)); 1543 | * ``` 1544 | * 1545 | * @param position The new position, in logical or physical pixels. 1546 | * @returns A promise indicating the success or failure of the operation. 1547 | */ 1548 | async setPosition(position) { 1549 | if (!position || 1550 | (position.type !== 'Logical' && position.type !== 'Physical')) { 1551 | throw new Error('the `position` argument must be either a LogicalPosition or a PhysicalPosition instance'); 1552 | } 1553 | return invokeTauriCommand({ 1554 | __tauriModule: 'Window', 1555 | message: { 1556 | cmd: 'manage', 1557 | data: { 1558 | label: this.label, 1559 | cmd: { 1560 | type: 'setPosition', 1561 | payload: { 1562 | type: position.type, 1563 | data: { 1564 | x: position.x, 1565 | y: position.y 1566 | } 1567 | } 1568 | } 1569 | } 1570 | } 1571 | }); 1572 | } 1573 | /** 1574 | * Sets the window fullscreen state. 1575 | * @example 1576 | * ```typescript 1577 | * import { appWindow } from '@tauri-apps/api/window'; 1578 | * await appWindow.setFullscreen(true); 1579 | * ``` 1580 | * 1581 | * @param fullscreen Whether the window should go to fullscreen or not. 1582 | * @returns A promise indicating the success or failure of the operation. 1583 | */ 1584 | async setFullscreen(fullscreen) { 1585 | return invokeTauriCommand({ 1586 | __tauriModule: 'Window', 1587 | message: { 1588 | cmd: 'manage', 1589 | data: { 1590 | label: this.label, 1591 | cmd: { 1592 | type: 'setFullscreen', 1593 | payload: fullscreen 1594 | } 1595 | } 1596 | } 1597 | }); 1598 | } 1599 | /** 1600 | * Bring the window to front and focus. 1601 | * @example 1602 | * ```typescript 1603 | * import { appWindow } from '@tauri-apps/api/window'; 1604 | * await appWindow.setFocus(); 1605 | * ``` 1606 | * 1607 | * @returns A promise indicating the success or failure of the operation. 1608 | */ 1609 | async setFocus() { 1610 | return invokeTauriCommand({ 1611 | __tauriModule: 'Window', 1612 | message: { 1613 | cmd: 'manage', 1614 | data: { 1615 | label: this.label, 1616 | cmd: { 1617 | type: 'setFocus' 1618 | } 1619 | } 1620 | } 1621 | }); 1622 | } 1623 | /** 1624 | * Sets the window icon. 1625 | * @example 1626 | * ```typescript 1627 | * import { appWindow } from '@tauri-apps/api/window'; 1628 | * await appWindow.setIcon('/tauri/awesome.png'); 1629 | * ``` 1630 | * 1631 | * Note that you need the `icon-ico` or `icon-png` Cargo features to use this API. 1632 | * To enable it, change your Cargo.toml file: 1633 | * ```toml 1634 | * [dependencies] 1635 | * tauri = { version = "...", features = ["...", "icon-png"] } 1636 | * ``` 1637 | * 1638 | * @param icon Icon bytes or path to the icon file. 1639 | * @returns A promise indicating the success or failure of the operation. 1640 | */ 1641 | async setIcon(icon) { 1642 | return invokeTauriCommand({ 1643 | __tauriModule: 'Window', 1644 | message: { 1645 | cmd: 'manage', 1646 | data: { 1647 | label: this.label, 1648 | cmd: { 1649 | type: 'setIcon', 1650 | payload: { 1651 | // correctly serialize Uint8Arrays 1652 | icon: typeof icon === 'string' ? icon : Array.from(icon) 1653 | } 1654 | } 1655 | } 1656 | } 1657 | }); 1658 | } 1659 | /** 1660 | * Whether the window icon should be hidden from the taskbar or not. 1661 | * 1662 | * #### Platform-specific 1663 | * 1664 | * - **macOS:** Unsupported. 1665 | * @example 1666 | * ```typescript 1667 | * import { appWindow } from '@tauri-apps/api/window'; 1668 | * await appWindow.setSkipTaskbar(true); 1669 | * ``` 1670 | * 1671 | * @param skip true to hide window icon, false to show it. 1672 | * @returns A promise indicating the success or failure of the operation. 1673 | */ 1674 | async setSkipTaskbar(skip) { 1675 | return invokeTauriCommand({ 1676 | __tauriModule: 'Window', 1677 | message: { 1678 | cmd: 'manage', 1679 | data: { 1680 | label: this.label, 1681 | cmd: { 1682 | type: 'setSkipTaskbar', 1683 | payload: skip 1684 | } 1685 | } 1686 | } 1687 | }); 1688 | } 1689 | /** 1690 | * Grabs the cursor, preventing it from leaving the window. 1691 | * 1692 | * There's no guarantee that the cursor will be hidden. You should 1693 | * hide it by yourself if you want so. 1694 | * 1695 | * #### Platform-specific 1696 | * 1697 | * - **Linux:** Unsupported. 1698 | * - **macOS:** This locks the cursor in a fixed location, which looks visually awkward. 1699 | * @example 1700 | * ```typescript 1701 | * import { appWindow } from '@tauri-apps/api/window'; 1702 | * await appWindow.setCursorGrab(true); 1703 | * ``` 1704 | * 1705 | * @param grab `true` to grab the cursor icon, `false` to release it. 1706 | * @returns A promise indicating the success or failure of the operation. 1707 | */ 1708 | async setCursorGrab(grab) { 1709 | return invokeTauriCommand({ 1710 | __tauriModule: 'Window', 1711 | message: { 1712 | cmd: 'manage', 1713 | data: { 1714 | label: this.label, 1715 | cmd: { 1716 | type: 'setCursorGrab', 1717 | payload: grab 1718 | } 1719 | } 1720 | } 1721 | }); 1722 | } 1723 | /** 1724 | * Modifies the cursor's visibility. 1725 | * 1726 | * #### Platform-specific 1727 | * 1728 | * - **Windows:** The cursor is only hidden within the confines of the window. 1729 | * - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor is 1730 | * outside of the window. 1731 | * @example 1732 | * ```typescript 1733 | * import { appWindow } from '@tauri-apps/api/window'; 1734 | * await appWindow.setCursorVisible(false); 1735 | * ``` 1736 | * 1737 | * @param visible If `false`, this will hide the cursor. If `true`, this will show the cursor. 1738 | * @returns A promise indicating the success or failure of the operation. 1739 | */ 1740 | async setCursorVisible(visible) { 1741 | return invokeTauriCommand({ 1742 | __tauriModule: 'Window', 1743 | message: { 1744 | cmd: 'manage', 1745 | data: { 1746 | label: this.label, 1747 | cmd: { 1748 | type: 'setCursorVisible', 1749 | payload: visible 1750 | } 1751 | } 1752 | } 1753 | }); 1754 | } 1755 | /** 1756 | * Modifies the cursor icon of the window. 1757 | * @example 1758 | * ```typescript 1759 | * import { appWindow } from '@tauri-apps/api/window'; 1760 | * await appWindow.setCursorIcon('help'); 1761 | * ``` 1762 | * 1763 | * @param icon The new cursor icon. 1764 | * @returns A promise indicating the success or failure of the operation. 1765 | */ 1766 | async setCursorIcon(icon) { 1767 | return invokeTauriCommand({ 1768 | __tauriModule: 'Window', 1769 | message: { 1770 | cmd: 'manage', 1771 | data: { 1772 | label: this.label, 1773 | cmd: { 1774 | type: 'setCursorIcon', 1775 | payload: icon 1776 | } 1777 | } 1778 | } 1779 | }); 1780 | } 1781 | /** 1782 | * Changes the position of the cursor in window coordinates. 1783 | * @example 1784 | * ```typescript 1785 | * import { appWindow, LogicalPosition } from '@tauri-apps/api/window'; 1786 | * await appWindow.setCursorPosition(new LogicalPosition(600, 300)); 1787 | * ``` 1788 | * 1789 | * @param position The new cursor position. 1790 | * @returns A promise indicating the success or failure of the operation. 1791 | */ 1792 | async setCursorPosition(position) { 1793 | if (!position || 1794 | (position.type !== 'Logical' && position.type !== 'Physical')) { 1795 | throw new Error('the `position` argument must be either a LogicalPosition or a PhysicalPosition instance'); 1796 | } 1797 | return invokeTauriCommand({ 1798 | __tauriModule: 'Window', 1799 | message: { 1800 | cmd: 'manage', 1801 | data: { 1802 | label: this.label, 1803 | cmd: { 1804 | type: 'setCursorPosition', 1805 | payload: { 1806 | type: position.type, 1807 | data: { 1808 | x: position.x, 1809 | y: position.y 1810 | } 1811 | } 1812 | } 1813 | } 1814 | } 1815 | }); 1816 | } 1817 | /** 1818 | * Changes the cursor events behavior. 1819 | * 1820 | * @example 1821 | * ```typescript 1822 | * import { appWindow } from '@tauri-apps/api/window'; 1823 | * await appWindow.setIgnoreCursorEvents(true); 1824 | * ``` 1825 | * 1826 | * @param ignore `true` to ignore the cursor events; `false` to process them as usual. 1827 | * @returns A promise indicating the success or failure of the operation. 1828 | */ 1829 | async setIgnoreCursorEvents(ignore) { 1830 | return invokeTauriCommand({ 1831 | __tauriModule: 'Window', 1832 | message: { 1833 | cmd: 'manage', 1834 | data: { 1835 | label: this.label, 1836 | cmd: { 1837 | type: 'setIgnoreCursorEvents', 1838 | payload: ignore 1839 | } 1840 | } 1841 | } 1842 | }); 1843 | } 1844 | /** 1845 | * Starts dragging the window. 1846 | * @example 1847 | * ```typescript 1848 | * import { appWindow } from '@tauri-apps/api/window'; 1849 | * await appWindow.startDragging(); 1850 | * ``` 1851 | * 1852 | * @return A promise indicating the success or failure of the operation. 1853 | */ 1854 | async startDragging() { 1855 | return invokeTauriCommand({ 1856 | __tauriModule: 'Window', 1857 | message: { 1858 | cmd: 'manage', 1859 | data: { 1860 | label: this.label, 1861 | cmd: { 1862 | type: 'startDragging' 1863 | } 1864 | } 1865 | } 1866 | }); 1867 | } 1868 | // Listeners 1869 | /** 1870 | * Listen to window resize. 1871 | * 1872 | * @example 1873 | * ```typescript 1874 | * import { appWindow } from "@tauri-apps/api/window"; 1875 | * const unlisten = await appWindow.onResized(({ payload: size }) => { 1876 | * console.log('Window resized', size); 1877 | * }); 1878 | * 1879 | * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted 1880 | * unlisten(); 1881 | * ``` 1882 | * 1883 | * @returns A promise resolving to a function to unlisten to the event. 1884 | * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. 1885 | * 1886 | * @since 1.0.2 1887 | */ 1888 | async onResized(handler) { 1889 | return this.listen(TauriEvent.WINDOW_RESIZED, (e) => { 1890 | e.payload = mapPhysicalSize(e.payload); 1891 | handler(e); 1892 | }); 1893 | } 1894 | /** 1895 | * Listen to window move. 1896 | * 1897 | * @example 1898 | * ```typescript 1899 | * import { appWindow } from "@tauri-apps/api/window"; 1900 | * const unlisten = await appWindow.onMoved(({ payload: position }) => { 1901 | * console.log('Window moved', position); 1902 | * }); 1903 | * 1904 | * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted 1905 | * unlisten(); 1906 | * ``` 1907 | * 1908 | * @returns A promise resolving to a function to unlisten to the event. 1909 | * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. 1910 | * 1911 | * @since 1.0.2 1912 | */ 1913 | async onMoved(handler) { 1914 | return this.listen(TauriEvent.WINDOW_MOVED, (e) => { 1915 | e.payload = mapPhysicalPosition(e.payload); 1916 | handler(e); 1917 | }); 1918 | } 1919 | /** 1920 | * Listen to window close requested. Emitted when the user requests to closes the window. 1921 | * 1922 | * @example 1923 | * ```typescript 1924 | * import { appWindow } from "@tauri-apps/api/window"; 1925 | * import { confirm } from '@tauri-apps/api/dialog'; 1926 | * const unlisten = await appWindow.onCloseRequested(async (event) => { 1927 | * const confirmed = await confirm('Are you sure?'); 1928 | * if (!confirmed) { 1929 | * // user did not confirm closing the window; let's prevent it 1930 | * event.preventDefault(); 1931 | * } 1932 | * }); 1933 | * 1934 | * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted 1935 | * unlisten(); 1936 | * ``` 1937 | * 1938 | * @returns A promise resolving to a function to unlisten to the event. 1939 | * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. 1940 | * 1941 | * @since 1.0.2 1942 | */ 1943 | /* eslint-disable @typescript-eslint/promise-function-async */ 1944 | async onCloseRequested(handler) { 1945 | return this.listen(TauriEvent.WINDOW_CLOSE_REQUESTED, (event) => { 1946 | const evt = new CloseRequestedEvent(event); 1947 | void Promise.resolve(handler(evt)).then(() => { 1948 | if (!evt.isPreventDefault()) { 1949 | return this.close(); 1950 | } 1951 | }); 1952 | }); 1953 | } 1954 | /* eslint-enable */ 1955 | /** 1956 | * Listen to window focus change. 1957 | * 1958 | * @example 1959 | * ```typescript 1960 | * import { appWindow } from "@tauri-apps/api/window"; 1961 | * const unlisten = await appWindow.onFocusChanged(({ payload: focused }) => { 1962 | * console.log('Focus changed, window is focused? ' + focused); 1963 | * }); 1964 | * 1965 | * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted 1966 | * unlisten(); 1967 | * ``` 1968 | * 1969 | * @returns A promise resolving to a function to unlisten to the event. 1970 | * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. 1971 | * 1972 | * @since 1.0.2 1973 | */ 1974 | async onFocusChanged(handler) { 1975 | const unlistenFocus = await this.listen(TauriEvent.WINDOW_FOCUS, (event) => { 1976 | handler({ ...event, payload: true }); 1977 | }); 1978 | const unlistenBlur = await this.listen(TauriEvent.WINDOW_BLUR, (event) => { 1979 | handler({ ...event, payload: false }); 1980 | }); 1981 | return () => { 1982 | unlistenFocus(); 1983 | unlistenBlur(); 1984 | }; 1985 | } 1986 | /** 1987 | * Listen to window scale change. Emitted when the window's scale factor has changed. 1988 | * The following user actions can cause DPI changes: 1989 | * - Changing the display's resolution. 1990 | * - Changing the display's scale factor (e.g. in Control Panel on Windows). 1991 | * - Moving the window to a display with a different scale factor. 1992 | * 1993 | * @example 1994 | * ```typescript 1995 | * import { appWindow } from "@tauri-apps/api/window"; 1996 | * const unlisten = await appWindow.onScaleChanged(({ payload }) => { 1997 | * console.log('Scale changed', payload.scaleFactor, payload.size); 1998 | * }); 1999 | * 2000 | * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted 2001 | * unlisten(); 2002 | * ``` 2003 | * 2004 | * @returns A promise resolving to a function to unlisten to the event. 2005 | * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. 2006 | * 2007 | * @since 1.0.2 2008 | */ 2009 | async onScaleChanged(handler) { 2010 | return this.listen(TauriEvent.WINDOW_SCALE_FACTOR_CHANGED, handler); 2011 | } 2012 | /** 2013 | * Listen to the window menu item click. The payload is the item id. 2014 | * 2015 | * @example 2016 | * ```typescript 2017 | * import { appWindow } from "@tauri-apps/api/window"; 2018 | * const unlisten = await appWindow.onMenuClicked(({ payload: menuId }) => { 2019 | * console.log('Menu clicked: ' + menuId); 2020 | * }); 2021 | * 2022 | * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted 2023 | * unlisten(); 2024 | * ``` 2025 | * 2026 | * @returns A promise resolving to a function to unlisten to the event. 2027 | * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. 2028 | * 2029 | * @since 1.0.2 2030 | */ 2031 | async onMenuClicked(handler) { 2032 | return this.listen(TauriEvent.MENU, handler); 2033 | } 2034 | /** 2035 | * Listen to a file drop event. 2036 | * The listener is triggered when the user hovers the selected files on the window, 2037 | * drops the files or cancels the operation. 2038 | * 2039 | * @example 2040 | * ```typescript 2041 | * import { appWindow } from "@tauri-apps/api/window"; 2042 | * const unlisten = await appWindow.onFileDropEvent((event) => { 2043 | * if (event.payload.type === 'hover') { 2044 | * console.log('User hovering', event.payload.paths); 2045 | * } else if (event.payload.type === 'drop') { 2046 | * console.log('User dropped', event.payload.paths); 2047 | * } else { 2048 | * console.log('File drop cancelled'); 2049 | * } 2050 | * }); 2051 | * 2052 | * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted 2053 | * unlisten(); 2054 | * ``` 2055 | * 2056 | * @returns A promise resolving to a function to unlisten to the event. 2057 | * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. 2058 | * 2059 | * @since 1.0.2 2060 | */ 2061 | async onFileDropEvent(handler) { 2062 | const unlistenFileDrop = await this.listen(TauriEvent.WINDOW_FILE_DROP, (event) => { 2063 | handler({ ...event, payload: { type: 'drop', paths: event.payload } }); 2064 | }); 2065 | const unlistenFileHover = await this.listen(TauriEvent.WINDOW_FILE_DROP_HOVER, (event) => { 2066 | handler({ ...event, payload: { type: 'hover', paths: event.payload } }); 2067 | }); 2068 | const unlistenCancel = await this.listen(TauriEvent.WINDOW_FILE_DROP_CANCELLED, (event) => { 2069 | handler({ ...event, payload: { type: 'cancel' } }); 2070 | }); 2071 | return () => { 2072 | unlistenFileDrop(); 2073 | unlistenFileHover(); 2074 | unlistenCancel(); 2075 | }; 2076 | } 2077 | /** 2078 | * Listen to the system theme change. 2079 | * 2080 | * @example 2081 | * ```typescript 2082 | * import { appWindow } from "@tauri-apps/api/window"; 2083 | * const unlisten = await appWindow.onThemeChanged(({ payload: theme }) => { 2084 | * console.log('New theme: ' + theme); 2085 | * }); 2086 | * 2087 | * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted 2088 | * unlisten(); 2089 | * ``` 2090 | * 2091 | * @returns A promise resolving to a function to unlisten to the event. 2092 | * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. 2093 | * 2094 | * @since 1.0.2 2095 | */ 2096 | async onThemeChanged(handler) { 2097 | return this.listen(TauriEvent.WINDOW_THEME_CHANGED, handler); 2098 | } 2099 | } 2100 | /** 2101 | * @since 1.0.2 2102 | */ 2103 | class CloseRequestedEvent { 2104 | constructor(event) { 2105 | this._preventDefault = false; 2106 | this.event = event.event; 2107 | this.windowLabel = event.windowLabel; 2108 | this.id = event.id; 2109 | } 2110 | preventDefault() { 2111 | this._preventDefault = true; 2112 | } 2113 | isPreventDefault() { 2114 | return this._preventDefault; 2115 | } 2116 | } 2117 | /** 2118 | * Create new webview windows and get a handle to existing ones. 2119 | * 2120 | * Windows are identified by a *label* a unique identifier that can be used to reference it later. 2121 | * It may only contain alphanumeric characters `a-zA-Z` plus the following special characters `-`, `/`, `:` and `_`. 2122 | * 2123 | * @example 2124 | * ```typescript 2125 | * // loading embedded asset: 2126 | * const webview = new WebviewWindow('theUniqueLabel', { 2127 | * url: 'path/to/page.html' 2128 | * }); 2129 | * // alternatively, load a remote URL: 2130 | * const webview = new WebviewWindow('theUniqueLabel', { 2131 | * url: 'https://github.com/tauri-apps/tauri' 2132 | * }); 2133 | * 2134 | * webview.once('tauri://created', function () { 2135 | * // webview window successfully created 2136 | * }); 2137 | * webview.once('tauri://error', function (e) { 2138 | * // an error happened creating the webview window 2139 | * }); 2140 | * 2141 | * // emit an event to the backend 2142 | * await webview.emit("some event", "data"); 2143 | * // listen to an event from the backend 2144 | * const unlisten = await webview.listen("event name", e => {}); 2145 | * unlisten(); 2146 | * ``` 2147 | * 2148 | * @since 1.0.2 2149 | */ 2150 | class WebviewWindow extends WindowManager { 2151 | /** 2152 | * Creates a new WebviewWindow. 2153 | * @example 2154 | * ```typescript 2155 | * import { WebviewWindow } from '@tauri-apps/api/window'; 2156 | * const webview = new WebviewWindow('my-label', { 2157 | * url: 'https://github.com/tauri-apps/tauri' 2158 | * }); 2159 | * webview.once('tauri://created', function () { 2160 | * // webview window successfully created 2161 | * }); 2162 | * webview.once('tauri://error', function (e) { 2163 | * // an error happened creating the webview window 2164 | * }); 2165 | * ``` 2166 | * 2167 | * * @param label The unique webview window label. Must be alphanumeric: `a-zA-Z-/:_`. 2168 | * @returns The WebviewWindow instance to communicate with the webview. 2169 | */ 2170 | constructor(label, options = {}) { 2171 | super(label); 2172 | // @ts-expect-error `skip` is not a public API so it is not defined in WindowOptions 2173 | if (!(options === null || options === void 0 ? void 0 : options.skip)) { 2174 | invokeTauriCommand({ 2175 | __tauriModule: 'Window', 2176 | message: { 2177 | cmd: 'createWebview', 2178 | data: { 2179 | options: { 2180 | label, 2181 | ...options 2182 | } 2183 | } 2184 | } 2185 | }) 2186 | .then(async () => this.emit('tauri://created')) 2187 | .catch(async (e) => this.emit('tauri://error', e)); 2188 | } 2189 | } 2190 | /** 2191 | * Gets the WebviewWindow for the webview associated with the given label. 2192 | * @example 2193 | * ```typescript 2194 | * import { WebviewWindow } from '@tauri-apps/api/window'; 2195 | * const mainWindow = WebviewWindow.getByLabel('main'); 2196 | * ``` 2197 | * 2198 | * @param label The webview window label. 2199 | * @returns The WebviewWindow instance to communicate with the webview or null if the webview doesn't exist. 2200 | */ 2201 | static getByLabel(label) { 2202 | if (getAll().some((w) => w.label === label)) { 2203 | // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor 2204 | return new WebviewWindow(label, { skip: true }); 2205 | } 2206 | return null; 2207 | } 2208 | /** 2209 | * Gets the focused window. 2210 | * @example 2211 | * ```typescript 2212 | * import { WebviewWindow } from '@tauri-apps/api/window'; 2213 | * const focusedWindow = WebviewWindow.getFocusedWindow(); 2214 | * ``` 2215 | * 2216 | * @returns The WebviewWindow instance to communicate with the webview or `undefined` if there is not any focused window. 2217 | * 2218 | * @since 1.4 2219 | */ 2220 | static async getFocusedWindow() { 2221 | for (const w of getAll()) { 2222 | if (await w.isFocused()) { 2223 | return w; 2224 | } 2225 | } 2226 | return null; 2227 | } 2228 | } 2229 | if ('__TAURI_METADATA__' in window) { 2230 | new WebviewWindow(window.__TAURI_METADATA__.__currentWindow.label, { 2231 | // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor 2232 | skip: true 2233 | }); 2234 | } 2235 | else { 2236 | console.warn(`Could not find "window.__TAURI_METADATA__". The "appWindow" value will reference the "main" window label.\nNote that this is not an issue if running this frontend on a browser instead of a Tauri window.`); 2237 | new WebviewWindow('main', { 2238 | // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor 2239 | skip: true 2240 | }); 2241 | } 2242 | function mapPhysicalPosition(m) { 2243 | return new PhysicalPosition(m.x, m.y); 2244 | } 2245 | function mapPhysicalSize(m) { 2246 | return new PhysicalSize(m.width, m.height); 2247 | } 2248 | 2249 | var StateFlags; 2250 | (function (StateFlags) { 2251 | StateFlags[StateFlags["SIZE"] = 1] = "SIZE"; 2252 | StateFlags[StateFlags["POSITION"] = 2] = "POSITION"; 2253 | StateFlags[StateFlags["MAXIMIZED"] = 4] = "MAXIMIZED"; 2254 | StateFlags[StateFlags["VISIBLE"] = 8] = "VISIBLE"; 2255 | StateFlags[StateFlags["DECORATIONS"] = 16] = "DECORATIONS"; 2256 | StateFlags[StateFlags["FULLSCREEN"] = 32] = "FULLSCREEN"; 2257 | StateFlags[StateFlags["ALL"] = 63] = "ALL"; 2258 | })(StateFlags || (StateFlags = {})); 2259 | /** 2260 | * Save the state of all open windows to disk. 2261 | */ 2262 | async function saveWindowState(flags) { 2263 | return invoke("plugin:window-state|save_window_state", { flags }); 2264 | } 2265 | /** 2266 | * Restore the state for the specified window from disk. 2267 | */ 2268 | async function restoreState(label, flags) { 2269 | return invoke("plugin:window-state|restore_state", { label, flags }); 2270 | } 2271 | /** 2272 | * Restore the state for the current window from disk. 2273 | */ 2274 | async function restoreStateCurrent(flags) { 2275 | return restoreState(getCurrent().label, flags); 2276 | } 2277 | 2278 | export { StateFlags, restoreState, restoreStateCurrent, saveWindowState }; 2279 | //# sourceMappingURL=index.min.js.map 2280 | -------------------------------------------------------------------------------- /dist-js/index.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.min.js","sources":["../../../node_modules/.pnpm/@tauri-apps+api@1.6.0/node_modules/@tauri-apps/api/tauri.js","../../../node_modules/.pnpm/@tauri-apps+api@1.6.0/node_modules/@tauri-apps/api/helpers/tauri.js","../../../node_modules/.pnpm/@tauri-apps+api@1.6.0/node_modules/@tauri-apps/api/helpers/event.js","../../../node_modules/.pnpm/@tauri-apps+api@1.6.0/node_modules/@tauri-apps/api/event.js","../../../node_modules/.pnpm/@tauri-apps+api@1.6.0/node_modules/@tauri-apps/api/window.js","../guest-js/index.ts"],"sourcesContent":["// Copyright 2019-2023 Tauri Programme within The Commons Conservancy\n// SPDX-License-Identifier: Apache-2.0\n// SPDX-License-Identifier: MIT\n/** @ignore */\nfunction uid() {\n return window.crypto.getRandomValues(new Uint32Array(1))[0];\n}\n/**\n * Transforms a callback function to a string identifier that can be passed to the backend.\n * The backend uses the identifier to `eval()` the callback.\n *\n * @return A unique identifier associated with the callback function.\n *\n * @since 1.0.0\n */\nfunction transformCallback(callback, once = false) {\n const identifier = uid();\n const prop = `_${identifier}`;\n Object.defineProperty(window, prop, {\n value: (result) => {\n if (once) {\n Reflect.deleteProperty(window, prop);\n }\n return callback === null || callback === void 0 ? void 0 : callback(result);\n },\n writable: false,\n configurable: true\n });\n return identifier;\n}\n/**\n * Sends a message to the backend.\n * @example\n * ```typescript\n * import { invoke } from '@tauri-apps/api/tauri';\n * await invoke('login', { user: 'tauri', password: 'poiwe3h4r5ip3yrhtew9ty' });\n * ```\n *\n * @param cmd The command name.\n * @param args The optional arguments to pass to the command.\n * @return A promise resolving or rejecting to the backend response.\n *\n * @since 1.0.0\n */\nasync function invoke(cmd, args = {}) {\n return new Promise((resolve, reject) => {\n const callback = transformCallback((e) => {\n resolve(e);\n Reflect.deleteProperty(window, `_${error}`);\n }, true);\n const error = transformCallback((e) => {\n reject(e);\n Reflect.deleteProperty(window, `_${callback}`);\n }, true);\n window.__TAURI_IPC__({\n cmd,\n callback,\n error,\n ...args\n });\n });\n}\n/**\n * Convert a device file path to an URL that can be loaded by the webview.\n * Note that `asset:` and `https://asset.localhost` must be added to [`tauri.security.csp`](https://tauri.app/v1/api/config/#securityconfig.csp) in `tauri.conf.json`.\n * Example CSP value: `\"csp\": \"default-src 'self'; img-src 'self' asset: https://asset.localhost\"` to use the asset protocol on image sources.\n *\n * Additionally, `asset` must be added to [`tauri.allowlist.protocol`](https://tauri.app/v1/api/config/#allowlistconfig.protocol)\n * in `tauri.conf.json` and its access scope must be defined on the `assetScope` array on the same `protocol` object.\n * For example:\n * ```json\n * {\n * \"tauri\": {\n * \"allowlist\": {\n * \"protocol\": {\n * \"asset\": true,\n * \"assetScope\": [\"$APPDATA/assets/*\"]\n * }\n * }\n * }\n * }\n * ```\n *\n * @param filePath The file path.\n * @param protocol The protocol to use. Defaults to `asset`. You only need to set this when using a custom protocol.\n * @example\n * ```typescript\n * import { appDataDir, join } from '@tauri-apps/api/path';\n * import { convertFileSrc } from '@tauri-apps/api/tauri';\n * const appDataDirPath = await appDataDir();\n * const filePath = await join(appDataDirPath, 'assets/video.mp4');\n * const assetUrl = convertFileSrc(filePath);\n *\n * const video = document.getElementById('my-video');\n * const source = document.createElement('source');\n * source.type = 'video/mp4';\n * source.src = assetUrl;\n * video.appendChild(source);\n * video.load();\n * ```\n *\n * @return the URL that can be used as source on the webview.\n *\n * @since 1.0.0\n */\nfunction convertFileSrc(filePath, protocol = 'asset') {\n return window.__TAURI__.convertFileSrc(filePath, protocol);\n}\n\nexport { convertFileSrc, invoke, transformCallback };\n","import { invoke } from '../tauri.js';\n\n// Copyright 2019-2023 Tauri Programme within The Commons Conservancy\n// SPDX-License-Identifier: Apache-2.0\n// SPDX-License-Identifier: MIT\n/** @ignore */\nasync function invokeTauriCommand(command) {\n return invoke('tauri', command);\n}\n\nexport { invokeTauriCommand };\n","import { invokeTauriCommand } from './tauri.js';\nimport { transformCallback } from '../tauri.js';\n\n// Copyright 2019-2023 Tauri Programme within The Commons Conservancy\n// SPDX-License-Identifier: Apache-2.0\n// SPDX-License-Identifier: MIT\n/**\n * Unregister the event listener associated with the given name and id.\n *\n * @ignore\n * @param event The event name\n * @param eventId Event identifier\n * @returns\n */\nasync function _unlisten(event, eventId) {\n return invokeTauriCommand({\n __tauriModule: 'Event',\n message: {\n cmd: 'unlisten',\n event,\n eventId\n }\n });\n}\n/**\n * Emits an event to the backend.\n *\n * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.\n * @param [windowLabel] The label of the window to which the event is sent, if null/undefined the event will be sent to all windows\n * @param [payload] Event payload\n * @returns\n */\nasync function emit(event, windowLabel, payload) {\n await invokeTauriCommand({\n __tauriModule: 'Event',\n message: {\n cmd: 'emit',\n event,\n windowLabel,\n payload\n }\n });\n}\n/**\n * Listen to an event from the backend.\n *\n * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.\n * @param handler Event handler callback.\n * @return A promise resolving to a function to unlisten to the event.\n */\nasync function listen(event, windowLabel, handler) {\n return invokeTauriCommand({\n __tauriModule: 'Event',\n message: {\n cmd: 'listen',\n event,\n windowLabel,\n handler: transformCallback(handler)\n }\n }).then((eventId) => {\n return async () => _unlisten(event, eventId);\n });\n}\n/**\n * Listen to an one-off event from the backend.\n *\n * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.\n * @param handler Event handler callback.\n * @returns A promise resolving to a function to unlisten to the event.\n */\nasync function once(event, windowLabel, handler) {\n return listen(event, windowLabel, (eventData) => {\n handler(eventData);\n _unlisten(event, eventData.id).catch(() => { });\n });\n}\n\nexport { emit, listen, once };\n","import { listen as listen$1, once as once$1, emit as emit$1 } from './helpers/event.js';\n\n// Copyright 2019-2023 Tauri Programme within The Commons Conservancy\n// SPDX-License-Identifier: Apache-2.0\n// SPDX-License-Identifier: MIT\n/**\n * The event system allows you to emit events to the backend and listen to events from it.\n *\n * This package is also accessible with `window.__TAURI__.event` when [`build.withGlobalTauri`](https://tauri.app/v1/api/config/#buildconfig.withglobaltauri) in `tauri.conf.json` is set to `true`.\n * @module\n */\n/**\n * @since 1.1.0\n */\nvar TauriEvent;\n(function (TauriEvent) {\n TauriEvent[\"WINDOW_RESIZED\"] = \"tauri://resize\";\n TauriEvent[\"WINDOW_MOVED\"] = \"tauri://move\";\n TauriEvent[\"WINDOW_CLOSE_REQUESTED\"] = \"tauri://close-requested\";\n TauriEvent[\"WINDOW_CREATED\"] = \"tauri://window-created\";\n TauriEvent[\"WINDOW_DESTROYED\"] = \"tauri://destroyed\";\n TauriEvent[\"WINDOW_FOCUS\"] = \"tauri://focus\";\n TauriEvent[\"WINDOW_BLUR\"] = \"tauri://blur\";\n TauriEvent[\"WINDOW_SCALE_FACTOR_CHANGED\"] = \"tauri://scale-change\";\n TauriEvent[\"WINDOW_THEME_CHANGED\"] = \"tauri://theme-changed\";\n TauriEvent[\"WINDOW_FILE_DROP\"] = \"tauri://file-drop\";\n TauriEvent[\"WINDOW_FILE_DROP_HOVER\"] = \"tauri://file-drop-hover\";\n TauriEvent[\"WINDOW_FILE_DROP_CANCELLED\"] = \"tauri://file-drop-cancelled\";\n TauriEvent[\"MENU\"] = \"tauri://menu\";\n TauriEvent[\"CHECK_UPDATE\"] = \"tauri://update\";\n TauriEvent[\"UPDATE_AVAILABLE\"] = \"tauri://update-available\";\n TauriEvent[\"INSTALL_UPDATE\"] = \"tauri://update-install\";\n TauriEvent[\"STATUS_UPDATE\"] = \"tauri://update-status\";\n TauriEvent[\"DOWNLOAD_PROGRESS\"] = \"tauri://update-download-progress\";\n})(TauriEvent || (TauriEvent = {}));\n/**\n * Listen to an event. The event can be either global or window-specific.\n * See {@link Event.windowLabel} to check the event source.\n *\n * @example\n * ```typescript\n * import { listen } from '@tauri-apps/api/event';\n * const unlisten = await listen('error', (event) => {\n * console.log(`Got error in window ${event.windowLabel}, payload: ${event.payload}`);\n * });\n *\n * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\n * unlisten();\n * ```\n *\n * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.\n * @param handler Event handler callback.\n * @returns A promise resolving to a function to unlisten to the event.\n * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.\n *\n * @since 1.0.0\n */\nasync function listen(event, handler) {\n return listen$1(event, null, handler);\n}\n/**\n * Listen to an one-off event. See {@link listen} for more information.\n *\n * @example\n * ```typescript\n * import { once } from '@tauri-apps/api/event';\n * interface LoadedPayload {\n * loggedIn: boolean,\n * token: string\n * }\n * const unlisten = await once('loaded', (event) => {\n * console.log(`App is loaded, loggedIn: ${event.payload.loggedIn}, token: ${event.payload.token}`);\n * });\n *\n * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\n * unlisten();\n * ```\n *\n * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.\n * @returns A promise resolving to a function to unlisten to the event.\n * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.\n *\n * @since 1.0.0\n */\nasync function once(event, handler) {\n return once$1(event, null, handler);\n}\n/**\n * Emits an event to the backend and all Tauri windows.\n * @example\n * ```typescript\n * import { emit } from '@tauri-apps/api/event';\n * await emit('frontend-loaded', { loggedIn: true, token: 'authToken' });\n * ```\n *\n * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.\n *\n * @since 1.0.0\n */\nasync function emit(event, payload) {\n return emit$1(event, undefined, payload);\n}\n\nexport { TauriEvent, emit, listen, once };\n","import { invokeTauriCommand } from './helpers/tauri.js';\nimport { listen, once, emit } from './helpers/event.js';\nimport { TauriEvent } from './event.js';\n\n// Copyright 2019-2023 Tauri Programme within The Commons Conservancy\n// SPDX-License-Identifier: Apache-2.0\n// SPDX-License-Identifier: MIT\n/**\n * Provides APIs to create windows, communicate with other windows and manipulate the current window.\n *\n * This package is also accessible with `window.__TAURI__.window` when [`build.withGlobalTauri`](https://tauri.app/v1/api/config/#buildconfig.withglobaltauri) in `tauri.conf.json` is set to `true`.\n *\n * The APIs must be added to [`tauri.allowlist.window`](https://tauri.app/v1/api/config/#allowlistconfig.window) in `tauri.conf.json`:\n * ```json\n * {\n * \"tauri\": {\n * \"allowlist\": {\n * \"window\": {\n * \"all\": true, // enable all window APIs\n * \"create\": true, // enable window creation\n * \"center\": true,\n * \"requestUserAttention\": true,\n * \"setResizable\": true,\n * \"setMaximizable\": true,\n * \"setMinimizable\": true,\n * \"setClosable\": true,\n * \"setTitle\": true,\n * \"maximize\": true,\n * \"unmaximize\": true,\n * \"minimize\": true,\n * \"unminimize\": true,\n * \"show\": true,\n * \"hide\": true,\n * \"close\": true,\n * \"setDecorations\": true,\n * \"setAlwaysOnTop\": true,\n * \"setContentProtected\": true,\n * \"setSize\": true,\n * \"setMinSize\": true,\n * \"setMaxSize\": true,\n * \"setPosition\": true,\n * \"setFullscreen\": true,\n * \"setFocus\": true,\n * \"setIcon\": true,\n * \"setSkipTaskbar\": true,\n * \"setCursorGrab\": true,\n * \"setCursorVisible\": true,\n * \"setCursorIcon\": true,\n * \"setCursorPosition\": true,\n * \"setIgnoreCursorEvents\": true,\n * \"startDragging\": true,\n * \"print\": true\n * }\n * }\n * }\n * }\n * ```\n * It is recommended to allowlist only the APIs you use for optimal bundle size and security.\n *\n * ## Window events\n *\n * Events can be listened to using `appWindow.listen`:\n * ```typescript\n * import { appWindow } from \"@tauri-apps/api/window\";\n * appWindow.listen(\"my-window-event\", ({ event, payload }) => { });\n * ```\n *\n * @module\n */\n/**\n * A size represented in logical pixels.\n *\n * @since 1.0.0\n */\nclass LogicalSize {\n constructor(width, height) {\n this.type = 'Logical';\n this.width = width;\n this.height = height;\n }\n}\n/**\n * A size represented in physical pixels.\n *\n * @since 1.0.0\n */\nclass PhysicalSize {\n constructor(width, height) {\n this.type = 'Physical';\n this.width = width;\n this.height = height;\n }\n /**\n * Converts the physical size to a logical one.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const factor = await appWindow.scaleFactor();\n * const size = await appWindow.innerSize();\n * const logical = size.toLogical(factor);\n * ```\n * */\n toLogical(scaleFactor) {\n return new LogicalSize(this.width / scaleFactor, this.height / scaleFactor);\n }\n}\n/**\n * A position represented in logical pixels.\n *\n * @since 1.0.0\n */\nclass LogicalPosition {\n constructor(x, y) {\n this.type = 'Logical';\n this.x = x;\n this.y = y;\n }\n}\n/**\n * A position represented in physical pixels.\n *\n * @since 1.0.0\n */\nclass PhysicalPosition {\n constructor(x, y) {\n this.type = 'Physical';\n this.x = x;\n this.y = y;\n }\n /**\n * Converts the physical position to a logical one.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const factor = await appWindow.scaleFactor();\n * const position = await appWindow.innerPosition();\n * const logical = position.toLogical(factor);\n * ```\n * */\n toLogical(scaleFactor) {\n return new LogicalPosition(this.x / scaleFactor, this.y / scaleFactor);\n }\n}\n/**\n * Attention type to request on a window.\n *\n * @since 1.0.0\n */\nvar UserAttentionType;\n(function (UserAttentionType) {\n /**\n * #### Platform-specific\n * - **macOS:** Bounces the dock icon until the application is in focus.\n * - **Windows:** Flashes both the window and the taskbar button until the application is in focus.\n */\n UserAttentionType[UserAttentionType[\"Critical\"] = 1] = \"Critical\";\n /**\n * #### Platform-specific\n * - **macOS:** Bounces the dock icon once.\n * - **Windows:** Flashes the taskbar button until the application is in focus.\n */\n UserAttentionType[UserAttentionType[\"Informational\"] = 2] = \"Informational\";\n})(UserAttentionType || (UserAttentionType = {}));\n/**\n * Get an instance of `WebviewWindow` for the current webview window.\n *\n * @since 1.0.0\n */\nfunction getCurrent() {\n return new WebviewWindow(window.__TAURI_METADATA__.__currentWindow.label, {\n // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor\n skip: true\n });\n}\n/**\n * Gets a list of instances of `WebviewWindow` for all available webview windows.\n *\n * @since 1.0.0\n */\nfunction getAll() {\n return window.__TAURI_METADATA__.__windows.map((w) => new WebviewWindow(w.label, {\n // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor\n skip: true\n }));\n}\n/** @ignore */\n// events that are emitted right here instead of by the created webview\nconst localTauriEvents = ['tauri://created', 'tauri://error'];\n/**\n * A webview window handle allows emitting and listening to events from the backend that are tied to the window.\n *\n * @ignore\n * @since 1.0.0\n */\nclass WebviewWindowHandle {\n constructor(label) {\n this.label = label;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n this.listeners = Object.create(null);\n }\n /**\n * Listen to an event emitted by the backend or webview.\n * The event must either be a global event or an event targetting this window.\n *\n * See {@link WebviewWindow.emit | `emit`} for more information.\n *\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const unlisten = await appWindow.listen('state-changed', (event) => {\n * console.log(`Got error: ${payload}`);\n * });\n *\n * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\n * unlisten();\n * ```\n *\n * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.\n *\n * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.\n * @param handler Event handler.\n * @returns A promise resolving to a function to unlisten to the event.\n */\n async listen(event, handler) {\n if (this._handleTauriEvent(event, handler)) {\n return Promise.resolve(() => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, security/detect-object-injection\n const listeners = this.listeners[event];\n listeners.splice(listeners.indexOf(handler), 1);\n });\n }\n return listen(event, this.label, handler);\n }\n /**\n * Listen to an one-off event.\n * See {@link WebviewWindow.listen | `listen`} for more information.\n *\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const unlisten = await appWindow.once('initialized', (event) => {\n * console.log(`Window initialized!`);\n * });\n *\n * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\n * unlisten();\n * ```\n *\n * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.\n *\n * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.\n * @param handler Event handler.\n * @returns A promise resolving to a function to unlisten to the event.\n */\n async once(event, handler) {\n if (this._handleTauriEvent(event, handler)) {\n return Promise.resolve(() => {\n // eslint-disable-next-line security/detect-object-injection\n const listeners = this.listeners[event];\n listeners.splice(listeners.indexOf(handler), 1);\n });\n }\n return once(event, this.label, handler);\n }\n /**\n * Emits an event to the backend and all Tauri windows.\n * The event will have this window's {@link WebviewWindow.label | label} as {@link Event.windowLabel | source window label}.\n *\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.emit('window-loaded', { loggedIn: true, token: 'authToken' });\n * ```\n *\n * This function can also be used to communicate between windows:\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.listen('sync-data', (event) => { });\n *\n * // on another window...\n * import { WebviewWindow } from '@tauri-apps/api/window';\n * const otherWindow = WebviewWindow.getByLabel('other')\n * await otherWindow.emit('sync-data');\n * ```\n *\n * Global listeners are also triggered:\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * import { listen } from '@tauri-apps/api/event';\n * await listen('ping', (event) => { });\n *\n * await appWindow.emit('ping');\n * ```\n *\n * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.\n * @param payload Event payload.\n */\n async emit(event, payload) {\n if (localTauriEvents.includes(event)) {\n // eslint-disable-next-line\n for (const handler of this.listeners[event] || []) {\n handler({ event, id: -1, windowLabel: this.label, payload });\n }\n return Promise.resolve();\n }\n return emit(event, this.label, payload);\n }\n /** @ignore */\n _handleTauriEvent(event, handler) {\n if (localTauriEvents.includes(event)) {\n if (!(event in this.listeners)) {\n // eslint-disable-next-line\n this.listeners[event] = [handler];\n }\n else {\n // eslint-disable-next-line\n this.listeners[event].push(handler);\n }\n return true;\n }\n return false;\n }\n}\n/**\n * Manage the current window object.\n *\n * @ignore\n * @since 1.0.0\n */\nclass WindowManager extends WebviewWindowHandle {\n // Getters\n /**\n * The scale factor that can be used to map physical pixels to logical pixels.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const factor = await appWindow.scaleFactor();\n * ```\n *\n * @returns The window's monitor scale factor.\n * */\n async scaleFactor() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'scaleFactor'\n }\n }\n }\n });\n }\n /**\n * The position of the top-left hand corner of the window's client area relative to the top-left hand corner of the desktop.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const position = await appWindow.innerPosition();\n * ```\n *\n * @returns The window's inner position.\n * */\n async innerPosition() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'innerPosition'\n }\n }\n }\n }).then(({ x, y }) => new PhysicalPosition(x, y));\n }\n /**\n * The position of the top-left hand corner of the window relative to the top-left hand corner of the desktop.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const position = await appWindow.outerPosition();\n * ```\n *\n * @returns The window's outer position.\n * */\n async outerPosition() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'outerPosition'\n }\n }\n }\n }).then(({ x, y }) => new PhysicalPosition(x, y));\n }\n /**\n * The physical size of the window's client area.\n * The client area is the content of the window, excluding the title bar and borders.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const size = await appWindow.innerSize();\n * ```\n *\n * @returns The window's inner size.\n */\n async innerSize() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'innerSize'\n }\n }\n }\n }).then(({ width, height }) => new PhysicalSize(width, height));\n }\n /**\n * The physical size of the entire window.\n * These dimensions include the title bar and borders. If you don't want that (and you usually don't), use inner_size instead.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const size = await appWindow.outerSize();\n * ```\n *\n * @returns The window's outer size.\n */\n async outerSize() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'outerSize'\n }\n }\n }\n }).then(({ width, height }) => new PhysicalSize(width, height));\n }\n /**\n * Gets the window's current fullscreen state.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const fullscreen = await appWindow.isFullscreen();\n * ```\n *\n * @returns Whether the window is in fullscreen mode or not.\n * */\n async isFullscreen() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'isFullscreen'\n }\n }\n }\n });\n }\n /**\n * Gets the window's current minimized state.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const minimized = await appWindow.isMinimized();\n * ```\n *\n * @since 1.3.0\n * */\n async isMinimized() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'isMinimized'\n }\n }\n }\n });\n }\n /**\n * Gets the window's current maximized state.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const maximized = await appWindow.isMaximized();\n * ```\n *\n * @returns Whether the window is maximized or not.\n * */\n async isMaximized() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'isMaximized'\n }\n }\n }\n });\n }\n /**\n * Gets the window's current focus state.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const focused = await appWindow.isFocused();\n * ```\n *\n * @returns Whether the window is focused or not.\n *\n * @since 1.4\n * */\n async isFocused() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'isFocused'\n }\n }\n }\n });\n }\n /**\n * Gets the window's current decorated state.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const decorated = await appWindow.isDecorated();\n * ```\n *\n * @returns Whether the window is decorated or not.\n * */\n async isDecorated() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'isDecorated'\n }\n }\n }\n });\n }\n /**\n * Gets the window's current resizable state.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const resizable = await appWindow.isResizable();\n * ```\n *\n * @returns Whether the window is resizable or not.\n * */\n async isResizable() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'isResizable'\n }\n }\n }\n });\n }\n /**\n * Gets the window’s native maximize button state.\n *\n * #### Platform-specific\n *\n * - **Linux / iOS / Android:** Unsupported.\n *\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const maximizable = await appWindow.isMaximizable();\n * ```\n *\n * @returns Whether the window's native maximize button is enabled or not.\n * */\n async isMaximizable() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'isMaximizable'\n }\n }\n }\n });\n }\n /**\n * Gets the window’s native minimize button state.\n *\n * #### Platform-specific\n *\n * - **Linux / iOS / Android:** Unsupported.\n *\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const minimizable = await appWindow.isMinimizable();\n * ```\n *\n * @returns Whether the window's native minimize button is enabled or not.\n * */\n async isMinimizable() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'isMinimizable'\n }\n }\n }\n });\n }\n /**\n * Gets the window’s native close button state.\n *\n * #### Platform-specific\n *\n * - **Linux / iOS / Android:** Unsupported.\n *\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const closable = await appWindow.isClosable();\n * ```\n *\n * @returns Whether the window's native close button is enabled or not.\n * */\n async isClosable() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'isClosable'\n }\n }\n }\n });\n }\n /**\n * Gets the window's current visible state.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const visible = await appWindow.isVisible();\n * ```\n *\n * @returns Whether the window is visible or not.\n * */\n async isVisible() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'isVisible'\n }\n }\n }\n });\n }\n /**\n * Gets the window's current title.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const title = await appWindow.title();\n * ```\n *\n * @since 1.3.0\n * */\n async title() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'title'\n }\n }\n }\n });\n }\n /**\n * Gets the window's current theme.\n *\n * #### Platform-specific\n *\n * - **macOS:** Theme was introduced on macOS 10.14. Returns `light` on macOS 10.13 and below.\n *\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * const theme = await appWindow.theme();\n * ```\n *\n * @returns The window theme.\n * */\n async theme() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'theme'\n }\n }\n }\n });\n }\n // Setters\n /**\n * Centers the window.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.center();\n * ```\n *\n * @returns A promise indicating the success or failure of the operation.\n */\n async center() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'center'\n }\n }\n }\n });\n }\n /**\n * Requests user attention to the window, this has no effect if the application\n * is already focused. How requesting for user attention manifests is platform dependent,\n * see `UserAttentionType` for details.\n *\n * Providing `null` will unset the request for user attention. Unsetting the request for\n * user attention might not be done automatically by the WM when the window receives input.\n *\n * #### Platform-specific\n *\n * - **macOS:** `null` has no effect.\n * - **Linux:** Urgency levels have the same effect.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.requestUserAttention();\n * ```\n *\n * @param requestType\n * @returns A promise indicating the success or failure of the operation.\n */\n async requestUserAttention(requestType) {\n let requestType_ = null;\n if (requestType) {\n if (requestType === UserAttentionType.Critical) {\n requestType_ = { type: 'Critical' };\n }\n else {\n requestType_ = { type: 'Informational' };\n }\n }\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'requestUserAttention',\n payload: requestType_\n }\n }\n }\n });\n }\n /**\n * Updates the window resizable flag.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setResizable(false);\n * ```\n *\n * @param resizable\n * @returns A promise indicating the success or failure of the operation.\n */\n async setResizable(resizable) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setResizable',\n payload: resizable\n }\n }\n }\n });\n }\n /**\n * Sets whether the window's native maximize button is enabled or not.\n * If resizable is set to false, this setting is ignored.\n *\n * #### Platform-specific\n *\n * - **macOS:** Disables the \"zoom\" button in the window titlebar, which is also used to enter fullscreen mode.\n * - **Linux / iOS / Android:** Unsupported.\n *\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setMaximizable(false);\n * ```\n *\n * @param maximizable\n * @returns A promise indicating the success or failure of the operation.\n */\n async setMaximizable(maximizable) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setMaximizable',\n payload: maximizable\n }\n }\n }\n });\n }\n /**\n * Sets whether the window's native minimize button is enabled or not.\n *\n * #### Platform-specific\n *\n * - **Linux / iOS / Android:** Unsupported.\n *\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setMinimizable(false);\n * ```\n *\n * @param minimizable\n * @returns A promise indicating the success or failure of the operation.\n */\n async setMinimizable(minimizable) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setMinimizable',\n payload: minimizable\n }\n }\n }\n });\n }\n /**\n * Sets whether the window's native close button is enabled or not.\n *\n * #### Platform-specific\n *\n * - **Linux:** GTK+ will do its best to convince the window manager not to show a close button. Depending on the system, this function may not have any effect when called on a window that is already visible\n * - **iOS / Android:** Unsupported.\n *\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setClosable(false);\n * ```\n *\n * @param closable\n * @returns A promise indicating the success or failure of the operation.\n */\n async setClosable(closable) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setClosable',\n payload: closable\n }\n }\n }\n });\n }\n /**\n * Sets the window title.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setTitle('Tauri');\n * ```\n *\n * @param title The new title\n * @returns A promise indicating the success or failure of the operation.\n */\n async setTitle(title) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setTitle',\n payload: title\n }\n }\n }\n });\n }\n /**\n * Maximizes the window.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.maximize();\n * ```\n *\n * @returns A promise indicating the success or failure of the operation.\n */\n async maximize() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'maximize'\n }\n }\n }\n });\n }\n /**\n * Unmaximizes the window.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.unmaximize();\n * ```\n *\n * @returns A promise indicating the success or failure of the operation.\n */\n async unmaximize() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'unmaximize'\n }\n }\n }\n });\n }\n /**\n * Toggles the window maximized state.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.toggleMaximize();\n * ```\n *\n * @returns A promise indicating the success or failure of the operation.\n */\n async toggleMaximize() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'toggleMaximize'\n }\n }\n }\n });\n }\n /**\n * Minimizes the window.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.minimize();\n * ```\n *\n * @returns A promise indicating the success or failure of the operation.\n */\n async minimize() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'minimize'\n }\n }\n }\n });\n }\n /**\n * Unminimizes the window.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.unminimize();\n * ```\n *\n * @returns A promise indicating the success or failure of the operation.\n */\n async unminimize() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'unminimize'\n }\n }\n }\n });\n }\n /**\n * Sets the window visibility to true.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.show();\n * ```\n *\n * @returns A promise indicating the success or failure of the operation.\n */\n async show() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'show'\n }\n }\n }\n });\n }\n /**\n * Sets the window visibility to false.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.hide();\n * ```\n *\n * @returns A promise indicating the success or failure of the operation.\n */\n async hide() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'hide'\n }\n }\n }\n });\n }\n /**\n * Closes the window.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.close();\n * ```\n *\n * @returns A promise indicating the success or failure of the operation.\n */\n async close() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'close'\n }\n }\n }\n });\n }\n /**\n * Whether the window should have borders and bars.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setDecorations(false);\n * ```\n *\n * @param decorations Whether the window should have borders and bars.\n * @returns A promise indicating the success or failure of the operation.\n */\n async setDecorations(decorations) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setDecorations',\n payload: decorations\n }\n }\n }\n });\n }\n /**\n * Whether the window should always be on top of other windows.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setAlwaysOnTop(true);\n * ```\n *\n * @param alwaysOnTop Whether the window should always be on top of other windows or not.\n * @returns A promise indicating the success or failure of the operation.\n */\n async setAlwaysOnTop(alwaysOnTop) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setAlwaysOnTop',\n payload: alwaysOnTop\n }\n }\n }\n });\n }\n /**\n * Prevents the window contents from being captured by other apps.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setContentProtected(true);\n * ```\n *\n * @returns A promise indicating the success or failure of the operation.\n *\n * @since 1.2.0\n */\n async setContentProtected(protected_) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setContentProtected',\n payload: protected_\n }\n }\n }\n });\n }\n /**\n * Resizes the window with a new inner size.\n * @example\n * ```typescript\n * import { appWindow, LogicalSize } from '@tauri-apps/api/window';\n * await appWindow.setSize(new LogicalSize(600, 500));\n * ```\n *\n * @param size The logical or physical inner size.\n * @returns A promise indicating the success or failure of the operation.\n */\n async setSize(size) {\n if (!size || (size.type !== 'Logical' && size.type !== 'Physical')) {\n throw new Error('the `size` argument must be either a LogicalSize or a PhysicalSize instance');\n }\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setSize',\n payload: {\n type: size.type,\n data: {\n width: size.width,\n height: size.height\n }\n }\n }\n }\n }\n });\n }\n /**\n * Sets the window minimum inner size. If the `size` argument is not provided, the constraint is unset.\n * @example\n * ```typescript\n * import { appWindow, PhysicalSize } from '@tauri-apps/api/window';\n * await appWindow.setMinSize(new PhysicalSize(600, 500));\n * ```\n *\n * @param size The logical or physical inner size, or `null` to unset the constraint.\n * @returns A promise indicating the success or failure of the operation.\n */\n async setMinSize(size) {\n if (size && size.type !== 'Logical' && size.type !== 'Physical') {\n throw new Error('the `size` argument must be either a LogicalSize or a PhysicalSize instance');\n }\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setMinSize',\n payload: size\n ? {\n type: size.type,\n data: {\n width: size.width,\n height: size.height\n }\n }\n : null\n }\n }\n }\n });\n }\n /**\n * Sets the window maximum inner size. If the `size` argument is undefined, the constraint is unset.\n * @example\n * ```typescript\n * import { appWindow, LogicalSize } from '@tauri-apps/api/window';\n * await appWindow.setMaxSize(new LogicalSize(600, 500));\n * ```\n *\n * @param size The logical or physical inner size, or `null` to unset the constraint.\n * @returns A promise indicating the success or failure of the operation.\n */\n async setMaxSize(size) {\n if (size && size.type !== 'Logical' && size.type !== 'Physical') {\n throw new Error('the `size` argument must be either a LogicalSize or a PhysicalSize instance');\n }\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setMaxSize',\n payload: size\n ? {\n type: size.type,\n data: {\n width: size.width,\n height: size.height\n }\n }\n : null\n }\n }\n }\n });\n }\n /**\n * Sets the window outer position.\n * @example\n * ```typescript\n * import { appWindow, LogicalPosition } from '@tauri-apps/api/window';\n * await appWindow.setPosition(new LogicalPosition(600, 500));\n * ```\n *\n * @param position The new position, in logical or physical pixels.\n * @returns A promise indicating the success or failure of the operation.\n */\n async setPosition(position) {\n if (!position ||\n (position.type !== 'Logical' && position.type !== 'Physical')) {\n throw new Error('the `position` argument must be either a LogicalPosition or a PhysicalPosition instance');\n }\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setPosition',\n payload: {\n type: position.type,\n data: {\n x: position.x,\n y: position.y\n }\n }\n }\n }\n }\n });\n }\n /**\n * Sets the window fullscreen state.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setFullscreen(true);\n * ```\n *\n * @param fullscreen Whether the window should go to fullscreen or not.\n * @returns A promise indicating the success or failure of the operation.\n */\n async setFullscreen(fullscreen) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setFullscreen',\n payload: fullscreen\n }\n }\n }\n });\n }\n /**\n * Bring the window to front and focus.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setFocus();\n * ```\n *\n * @returns A promise indicating the success or failure of the operation.\n */\n async setFocus() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setFocus'\n }\n }\n }\n });\n }\n /**\n * Sets the window icon.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setIcon('/tauri/awesome.png');\n * ```\n *\n * Note that you need the `icon-ico` or `icon-png` Cargo features to use this API.\n * To enable it, change your Cargo.toml file:\n * ```toml\n * [dependencies]\n * tauri = { version = \"...\", features = [\"...\", \"icon-png\"] }\n * ```\n *\n * @param icon Icon bytes or path to the icon file.\n * @returns A promise indicating the success or failure of the operation.\n */\n async setIcon(icon) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setIcon',\n payload: {\n // correctly serialize Uint8Arrays\n icon: typeof icon === 'string' ? icon : Array.from(icon)\n }\n }\n }\n }\n });\n }\n /**\n * Whether the window icon should be hidden from the taskbar or not.\n *\n * #### Platform-specific\n *\n * - **macOS:** Unsupported.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setSkipTaskbar(true);\n * ```\n *\n * @param skip true to hide window icon, false to show it.\n * @returns A promise indicating the success or failure of the operation.\n */\n async setSkipTaskbar(skip) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setSkipTaskbar',\n payload: skip\n }\n }\n }\n });\n }\n /**\n * Grabs the cursor, preventing it from leaving the window.\n *\n * There's no guarantee that the cursor will be hidden. You should\n * hide it by yourself if you want so.\n *\n * #### Platform-specific\n *\n * - **Linux:** Unsupported.\n * - **macOS:** This locks the cursor in a fixed location, which looks visually awkward.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setCursorGrab(true);\n * ```\n *\n * @param grab `true` to grab the cursor icon, `false` to release it.\n * @returns A promise indicating the success or failure of the operation.\n */\n async setCursorGrab(grab) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setCursorGrab',\n payload: grab\n }\n }\n }\n });\n }\n /**\n * Modifies the cursor's visibility.\n *\n * #### Platform-specific\n *\n * - **Windows:** The cursor is only hidden within the confines of the window.\n * - **macOS:** The cursor is hidden as long as the window has input focus, even if the cursor is\n * outside of the window.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setCursorVisible(false);\n * ```\n *\n * @param visible If `false`, this will hide the cursor. If `true`, this will show the cursor.\n * @returns A promise indicating the success or failure of the operation.\n */\n async setCursorVisible(visible) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setCursorVisible',\n payload: visible\n }\n }\n }\n });\n }\n /**\n * Modifies the cursor icon of the window.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setCursorIcon('help');\n * ```\n *\n * @param icon The new cursor icon.\n * @returns A promise indicating the success or failure of the operation.\n */\n async setCursorIcon(icon) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setCursorIcon',\n payload: icon\n }\n }\n }\n });\n }\n /**\n * Changes the position of the cursor in window coordinates.\n * @example\n * ```typescript\n * import { appWindow, LogicalPosition } from '@tauri-apps/api/window';\n * await appWindow.setCursorPosition(new LogicalPosition(600, 300));\n * ```\n *\n * @param position The new cursor position.\n * @returns A promise indicating the success or failure of the operation.\n */\n async setCursorPosition(position) {\n if (!position ||\n (position.type !== 'Logical' && position.type !== 'Physical')) {\n throw new Error('the `position` argument must be either a LogicalPosition or a PhysicalPosition instance');\n }\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setCursorPosition',\n payload: {\n type: position.type,\n data: {\n x: position.x,\n y: position.y\n }\n }\n }\n }\n }\n });\n }\n /**\n * Changes the cursor events behavior.\n *\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.setIgnoreCursorEvents(true);\n * ```\n *\n * @param ignore `true` to ignore the cursor events; `false` to process them as usual.\n * @returns A promise indicating the success or failure of the operation.\n */\n async setIgnoreCursorEvents(ignore) {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'setIgnoreCursorEvents',\n payload: ignore\n }\n }\n }\n });\n }\n /**\n * Starts dragging the window.\n * @example\n * ```typescript\n * import { appWindow } from '@tauri-apps/api/window';\n * await appWindow.startDragging();\n * ```\n *\n * @return A promise indicating the success or failure of the operation.\n */\n async startDragging() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n label: this.label,\n cmd: {\n type: 'startDragging'\n }\n }\n }\n });\n }\n // Listeners\n /**\n * Listen to window resize.\n *\n * @example\n * ```typescript\n * import { appWindow } from \"@tauri-apps/api/window\";\n * const unlisten = await appWindow.onResized(({ payload: size }) => {\n * console.log('Window resized', size);\n * });\n *\n * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\n * unlisten();\n * ```\n *\n * @returns A promise resolving to a function to unlisten to the event.\n * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.\n *\n * @since 1.0.2\n */\n async onResized(handler) {\n return this.listen(TauriEvent.WINDOW_RESIZED, (e) => {\n e.payload = mapPhysicalSize(e.payload);\n handler(e);\n });\n }\n /**\n * Listen to window move.\n *\n * @example\n * ```typescript\n * import { appWindow } from \"@tauri-apps/api/window\";\n * const unlisten = await appWindow.onMoved(({ payload: position }) => {\n * console.log('Window moved', position);\n * });\n *\n * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\n * unlisten();\n * ```\n *\n * @returns A promise resolving to a function to unlisten to the event.\n * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.\n *\n * @since 1.0.2\n */\n async onMoved(handler) {\n return this.listen(TauriEvent.WINDOW_MOVED, (e) => {\n e.payload = mapPhysicalPosition(e.payload);\n handler(e);\n });\n }\n /**\n * Listen to window close requested. Emitted when the user requests to closes the window.\n *\n * @example\n * ```typescript\n * import { appWindow } from \"@tauri-apps/api/window\";\n * import { confirm } from '@tauri-apps/api/dialog';\n * const unlisten = await appWindow.onCloseRequested(async (event) => {\n * const confirmed = await confirm('Are you sure?');\n * if (!confirmed) {\n * // user did not confirm closing the window; let's prevent it\n * event.preventDefault();\n * }\n * });\n *\n * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\n * unlisten();\n * ```\n *\n * @returns A promise resolving to a function to unlisten to the event.\n * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.\n *\n * @since 1.0.2\n */\n /* eslint-disable @typescript-eslint/promise-function-async */\n async onCloseRequested(handler) {\n return this.listen(TauriEvent.WINDOW_CLOSE_REQUESTED, (event) => {\n const evt = new CloseRequestedEvent(event);\n void Promise.resolve(handler(evt)).then(() => {\n if (!evt.isPreventDefault()) {\n return this.close();\n }\n });\n });\n }\n /* eslint-enable */\n /**\n * Listen to window focus change.\n *\n * @example\n * ```typescript\n * import { appWindow } from \"@tauri-apps/api/window\";\n * const unlisten = await appWindow.onFocusChanged(({ payload: focused }) => {\n * console.log('Focus changed, window is focused? ' + focused);\n * });\n *\n * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\n * unlisten();\n * ```\n *\n * @returns A promise resolving to a function to unlisten to the event.\n * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.\n *\n * @since 1.0.2\n */\n async onFocusChanged(handler) {\n const unlistenFocus = await this.listen(TauriEvent.WINDOW_FOCUS, (event) => {\n handler({ ...event, payload: true });\n });\n const unlistenBlur = await this.listen(TauriEvent.WINDOW_BLUR, (event) => {\n handler({ ...event, payload: false });\n });\n return () => {\n unlistenFocus();\n unlistenBlur();\n };\n }\n /**\n * Listen to window scale change. Emitted when the window's scale factor has changed.\n * The following user actions can cause DPI changes:\n * - Changing the display's resolution.\n * - Changing the display's scale factor (e.g. in Control Panel on Windows).\n * - Moving the window to a display with a different scale factor.\n *\n * @example\n * ```typescript\n * import { appWindow } from \"@tauri-apps/api/window\";\n * const unlisten = await appWindow.onScaleChanged(({ payload }) => {\n * console.log('Scale changed', payload.scaleFactor, payload.size);\n * });\n *\n * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\n * unlisten();\n * ```\n *\n * @returns A promise resolving to a function to unlisten to the event.\n * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.\n *\n * @since 1.0.2\n */\n async onScaleChanged(handler) {\n return this.listen(TauriEvent.WINDOW_SCALE_FACTOR_CHANGED, handler);\n }\n /**\n * Listen to the window menu item click. The payload is the item id.\n *\n * @example\n * ```typescript\n * import { appWindow } from \"@tauri-apps/api/window\";\n * const unlisten = await appWindow.onMenuClicked(({ payload: menuId }) => {\n * console.log('Menu clicked: ' + menuId);\n * });\n *\n * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\n * unlisten();\n * ```\n *\n * @returns A promise resolving to a function to unlisten to the event.\n * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.\n *\n * @since 1.0.2\n */\n async onMenuClicked(handler) {\n return this.listen(TauriEvent.MENU, handler);\n }\n /**\n * Listen to a file drop event.\n * The listener is triggered when the user hovers the selected files on the window,\n * drops the files or cancels the operation.\n *\n * @example\n * ```typescript\n * import { appWindow } from \"@tauri-apps/api/window\";\n * const unlisten = await appWindow.onFileDropEvent((event) => {\n * if (event.payload.type === 'hover') {\n * console.log('User hovering', event.payload.paths);\n * } else if (event.payload.type === 'drop') {\n * console.log('User dropped', event.payload.paths);\n * } else {\n * console.log('File drop cancelled');\n * }\n * });\n *\n * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\n * unlisten();\n * ```\n *\n * @returns A promise resolving to a function to unlisten to the event.\n * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.\n *\n * @since 1.0.2\n */\n async onFileDropEvent(handler) {\n const unlistenFileDrop = await this.listen(TauriEvent.WINDOW_FILE_DROP, (event) => {\n handler({ ...event, payload: { type: 'drop', paths: event.payload } });\n });\n const unlistenFileHover = await this.listen(TauriEvent.WINDOW_FILE_DROP_HOVER, (event) => {\n handler({ ...event, payload: { type: 'hover', paths: event.payload } });\n });\n const unlistenCancel = await this.listen(TauriEvent.WINDOW_FILE_DROP_CANCELLED, (event) => {\n handler({ ...event, payload: { type: 'cancel' } });\n });\n return () => {\n unlistenFileDrop();\n unlistenFileHover();\n unlistenCancel();\n };\n }\n /**\n * Listen to the system theme change.\n *\n * @example\n * ```typescript\n * import { appWindow } from \"@tauri-apps/api/window\";\n * const unlisten = await appWindow.onThemeChanged(({ payload: theme }) => {\n * console.log('New theme: ' + theme);\n * });\n *\n * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\n * unlisten();\n * ```\n *\n * @returns A promise resolving to a function to unlisten to the event.\n * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.\n *\n * @since 1.0.2\n */\n async onThemeChanged(handler) {\n return this.listen(TauriEvent.WINDOW_THEME_CHANGED, handler);\n }\n}\n/**\n * @since 1.0.2\n */\nclass CloseRequestedEvent {\n constructor(event) {\n this._preventDefault = false;\n this.event = event.event;\n this.windowLabel = event.windowLabel;\n this.id = event.id;\n }\n preventDefault() {\n this._preventDefault = true;\n }\n isPreventDefault() {\n return this._preventDefault;\n }\n}\n/**\n * Create new webview windows and get a handle to existing ones.\n *\n * Windows are identified by a *label* a unique identifier that can be used to reference it later.\n * It may only contain alphanumeric characters `a-zA-Z` plus the following special characters `-`, `/`, `:` and `_`.\n *\n * @example\n * ```typescript\n * // loading embedded asset:\n * const webview = new WebviewWindow('theUniqueLabel', {\n * url: 'path/to/page.html'\n * });\n * // alternatively, load a remote URL:\n * const webview = new WebviewWindow('theUniqueLabel', {\n * url: 'https://github.com/tauri-apps/tauri'\n * });\n *\n * webview.once('tauri://created', function () {\n * // webview window successfully created\n * });\n * webview.once('tauri://error', function (e) {\n * // an error happened creating the webview window\n * });\n *\n * // emit an event to the backend\n * await webview.emit(\"some event\", \"data\");\n * // listen to an event from the backend\n * const unlisten = await webview.listen(\"event name\", e => {});\n * unlisten();\n * ```\n *\n * @since 1.0.2\n */\nclass WebviewWindow extends WindowManager {\n /**\n * Creates a new WebviewWindow.\n * @example\n * ```typescript\n * import { WebviewWindow } from '@tauri-apps/api/window';\n * const webview = new WebviewWindow('my-label', {\n * url: 'https://github.com/tauri-apps/tauri'\n * });\n * webview.once('tauri://created', function () {\n * // webview window successfully created\n * });\n * webview.once('tauri://error', function (e) {\n * // an error happened creating the webview window\n * });\n * ```\n *\n * * @param label The unique webview window label. Must be alphanumeric: `a-zA-Z-/:_`.\n * @returns The WebviewWindow instance to communicate with the webview.\n */\n constructor(label, options = {}) {\n super(label);\n // @ts-expect-error `skip` is not a public API so it is not defined in WindowOptions\n if (!(options === null || options === void 0 ? void 0 : options.skip)) {\n invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'createWebview',\n data: {\n options: {\n label,\n ...options\n }\n }\n }\n })\n .then(async () => this.emit('tauri://created'))\n .catch(async (e) => this.emit('tauri://error', e));\n }\n }\n /**\n * Gets the WebviewWindow for the webview associated with the given label.\n * @example\n * ```typescript\n * import { WebviewWindow } from '@tauri-apps/api/window';\n * const mainWindow = WebviewWindow.getByLabel('main');\n * ```\n *\n * @param label The webview window label.\n * @returns The WebviewWindow instance to communicate with the webview or null if the webview doesn't exist.\n */\n static getByLabel(label) {\n if (getAll().some((w) => w.label === label)) {\n // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor\n return new WebviewWindow(label, { skip: true });\n }\n return null;\n }\n /**\n * Gets the focused window.\n * @example\n * ```typescript\n * import { WebviewWindow } from '@tauri-apps/api/window';\n * const focusedWindow = WebviewWindow.getFocusedWindow();\n * ```\n *\n * @returns The WebviewWindow instance to communicate with the webview or `undefined` if there is not any focused window.\n *\n * @since 1.4\n */\n static async getFocusedWindow() {\n for (const w of getAll()) {\n if (await w.isFocused()) {\n return w;\n }\n }\n return null;\n }\n}\n/** The WebviewWindow for the current window. */\nlet appWindow;\nif ('__TAURI_METADATA__' in window) {\n appWindow = new WebviewWindow(window.__TAURI_METADATA__.__currentWindow.label, {\n // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor\n skip: true\n });\n}\nelse {\n console.warn(`Could not find \"window.__TAURI_METADATA__\". The \"appWindow\" value will reference the \"main\" window label.\\nNote that this is not an issue if running this frontend on a browser instead of a Tauri window.`);\n appWindow = new WebviewWindow('main', {\n // @ts-expect-error `skip` is not defined in the public API but it is handled by the constructor\n skip: true\n });\n}\nfunction mapMonitor(m) {\n return m === null\n ? null\n : {\n name: m.name,\n scaleFactor: m.scaleFactor,\n position: mapPhysicalPosition(m.position),\n size: mapPhysicalSize(m.size)\n };\n}\nfunction mapPhysicalPosition(m) {\n return new PhysicalPosition(m.x, m.y);\n}\nfunction mapPhysicalSize(m) {\n return new PhysicalSize(m.width, m.height);\n}\n/**\n * Returns the monitor on which the window currently resides.\n * Returns `null` if current monitor can't be detected.\n * @example\n * ```typescript\n * import { currentMonitor } from '@tauri-apps/api/window';\n * const monitor = currentMonitor();\n * ```\n *\n * @since 1.0.0\n */\nasync function currentMonitor() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n cmd: {\n type: 'currentMonitor'\n }\n }\n }\n }).then(mapMonitor);\n}\n/**\n * Returns the primary monitor of the system.\n * Returns `null` if it can't identify any monitor as a primary one.\n * @example\n * ```typescript\n * import { primaryMonitor } from '@tauri-apps/api/window';\n * const monitor = primaryMonitor();\n * ```\n *\n * @since 1.0.0\n */\nasync function primaryMonitor() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n cmd: {\n type: 'primaryMonitor'\n }\n }\n }\n }).then(mapMonitor);\n}\n/**\n * Returns the list of all the monitors available on the system.\n * @example\n * ```typescript\n * import { availableMonitors } from '@tauri-apps/api/window';\n * const monitors = availableMonitors();\n * ```\n *\n * @since 1.0.0\n */\nasync function availableMonitors() {\n return invokeTauriCommand({\n __tauriModule: 'Window',\n message: {\n cmd: 'manage',\n data: {\n cmd: {\n type: 'availableMonitors'\n }\n }\n }\n }).then((ms) => ms.map(mapMonitor));\n}\n\nexport { CloseRequestedEvent, LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, UserAttentionType, WebviewWindow, WebviewWindowHandle, WindowManager, appWindow, availableMonitors, currentMonitor, getAll, getCurrent, primaryMonitor };\n",null],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA,SAAS,GAAG,GAAG;AACf,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,iBAAiB,CAAC,QAAQ,EAAE,IAAI,GAAG,KAAK,EAAE;AACnD,IAAI,MAAM,UAAU,GAAG,GAAG,EAAE;AAC5B,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;AACjC,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE;AACxC,QAAQ,KAAK,EAAE,CAAC,MAAM,KAAK;AAC3B,YAAY,IAAI,IAAI,EAAE;AACtB,gBAAgB,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC;AACpD;AACA,YAAY,OAAO,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;AACvF,SAAS;AACT,QAAQ,QAAQ,EAAE,KAAK;AACvB,QAAQ,YAAY,EAAE;AACtB,KAAK,CAAC;AACN,IAAI,OAAO,UAAU;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM,CAAC,GAAG,EAAE,IAAI,GAAG,EAAE,EAAE;AACtC,IAAI,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAC5C,QAAQ,MAAM,QAAQ,GAAG,iBAAiB,CAAC,CAAC,CAAC,KAAK;AAClD,YAAY,OAAO,CAAC,CAAC,CAAC;AACtB,YAAY,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AACvD,SAAS,EAAE,IAAI,CAAC;AAChB,QAAQ,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,CAAC,KAAK;AAC/C,YAAY,MAAM,CAAC,CAAC,CAAC;AACrB,YAAY,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC1D,SAAS,EAAE,IAAI,CAAC;AAChB,QAAQ,MAAM,CAAC,aAAa,CAAC;AAC7B,YAAY,GAAG;AACf,YAAY,QAAQ;AACpB,YAAY,KAAK;AACjB,YAAY,GAAG;AACf,SAAS,CAAC;AACV,KAAK,CAAC;AACN;;AC3DA;AACA;AACA;AACA;AACA,eAAe,kBAAkB,CAAC,OAAO,EAAE;AAC3C,IAAI,OAAO,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;AACnC;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE;AACzC,IAAI,OAAO,kBAAkB,CAAC;AAC9B,QAAQ,aAAa,EAAE,OAAO;AAC9B,QAAQ,OAAO,EAAE;AACjB,YAAY,GAAG,EAAE,UAAU;AAC3B,YAAY,KAAK;AACjB,YAAY;AACZ;AACA,KAAK,CAAC;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE;AACjD,IAAI,MAAM,kBAAkB,CAAC;AAC7B,QAAQ,aAAa,EAAE,OAAO;AAC9B,QAAQ,OAAO,EAAE;AACjB,YAAY,GAAG,EAAE,MAAM;AACvB,YAAY,KAAK;AACjB,YAAY,WAAW;AACvB,YAAY;AACZ;AACA,KAAK,CAAC;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE;AACnD,IAAI,OAAO,kBAAkB,CAAC;AAC9B,QAAQ,aAAa,EAAE,OAAO;AAC9B,QAAQ,OAAO,EAAE;AACjB,YAAY,GAAG,EAAE,QAAQ;AACzB,YAAY,KAAK;AACjB,YAAY,WAAW;AACvB,YAAY,OAAO,EAAE,iBAAiB,CAAC,OAAO;AAC9C;AACA,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK;AACzB,QAAQ,OAAO,YAAY,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC;AACpD,KAAK,CAAC;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE;AACjD,IAAI,OAAO,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,SAAS,KAAK;AACrD,QAAQ,OAAO,CAAC,SAAS,CAAC;AAC1B,QAAQ,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;AACvD,KAAK,CAAC;AACN;;ACzEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,UAAU;AACd,CAAC,UAAU,UAAU,EAAE;AACvB,IAAI,UAAU,CAAC,gBAAgB,CAAC,GAAG,gBAAgB;AACnD,IAAI,UAAU,CAAC,cAAc,CAAC,GAAG,cAAc;AAC/C,IAAI,UAAU,CAAC,wBAAwB,CAAC,GAAG,yBAAyB;AACpE,IAAI,UAAU,CAAC,gBAAgB,CAAC,GAAG,wBAAwB;AAC3D,IAAI,UAAU,CAAC,kBAAkB,CAAC,GAAG,mBAAmB;AACxD,IAAI,UAAU,CAAC,cAAc,CAAC,GAAG,eAAe;AAChD,IAAI,UAAU,CAAC,aAAa,CAAC,GAAG,cAAc;AAC9C,IAAI,UAAU,CAAC,6BAA6B,CAAC,GAAG,sBAAsB;AACtE,IAAI,UAAU,CAAC,sBAAsB,CAAC,GAAG,uBAAuB;AAChE,IAAI,UAAU,CAAC,kBAAkB,CAAC,GAAG,mBAAmB;AACxD,IAAI,UAAU,CAAC,wBAAwB,CAAC,GAAG,yBAAyB;AACpE,IAAI,UAAU,CAAC,4BAA4B,CAAC,GAAG,6BAA6B;AAC5E,IAAI,UAAU,CAAC,MAAM,CAAC,GAAG,cAAc;AACvC,IAAI,UAAU,CAAC,cAAc,CAAC,GAAG,gBAAgB;AACjD,IAAI,UAAU,CAAC,kBAAkB,CAAC,GAAG,0BAA0B;AAC/D,IAAI,UAAU,CAAC,gBAAgB,CAAC,GAAG,wBAAwB;AAC3D,IAAI,UAAU,CAAC,eAAe,CAAC,GAAG,uBAAuB;AACzD,IAAI,UAAU,CAAC,mBAAmB,CAAC,GAAG,kCAAkC;AACxE,CAAC,EAAE,UAAU,KAAK,UAAU,GAAG,EAAE,CAAC,CAAC;;AC9BnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,WAAW,CAAC;AAClB,IAAI,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE;AAC/B,QAAQ,IAAI,CAAC,IAAI,GAAG,SAAS;AAC7B,QAAQ,IAAI,CAAC,KAAK,GAAG,KAAK;AAC1B,QAAQ,IAAI,CAAC,MAAM,GAAG,MAAM;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,YAAY,CAAC;AACnB,IAAI,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE;AAC/B,QAAQ,IAAI,CAAC,IAAI,GAAG,UAAU;AAC9B,QAAQ,IAAI,CAAC,KAAK,GAAG,KAAK;AAC1B,QAAQ,IAAI,CAAC,MAAM,GAAG,MAAM;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,SAAS,CAAC,WAAW,EAAE;AAC3B,QAAQ,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,GAAG,WAAW,EAAE,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,eAAe,CAAC;AACtB,IAAI,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE;AACtB,QAAQ,IAAI,CAAC,IAAI,GAAG,SAAS;AAC7B,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC;AAClB,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,gBAAgB,CAAC;AACvB,IAAI,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE;AACtB,QAAQ,IAAI,CAAC,IAAI,GAAG,UAAU;AAC9B,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC;AAClB,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,SAAS,CAAC,WAAW,EAAE;AAC3B,QAAQ,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,GAAG,WAAW,EAAE,IAAI,CAAC,CAAC,GAAG,WAAW,CAAC;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,iBAAiB;AACrB,CAAC,UAAU,iBAAiB,EAAE;AAC9B;AACA;AACA;AACA;AACA;AACA,IAAI,iBAAiB,CAAC,iBAAiB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU;AACrE;AACA;AACA;AACA;AACA;AACA,IAAI,iBAAiB,CAAC,iBAAiB,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,GAAG,eAAe;AAC/E,CAAC,EAAE,iBAAiB,KAAK,iBAAiB,GAAG,EAAE,CAAC,CAAC;AACjD;AACA;AACA;AACA;AACA;AACA,SAAS,UAAU,GAAG;AACtB,IAAI,OAAO,IAAI,aAAa,CAAC,MAAM,CAAC,kBAAkB,CAAC,eAAe,CAAC,KAAK,EAAE;AAC9E;AACA,QAAQ,IAAI,EAAE;AACd,KAAK,CAAC;AACN;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,MAAM,GAAG;AAClB,IAAI,OAAO,MAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,aAAa,CAAC,CAAC,CAAC,KAAK,EAAE;AACrF;AACA,QAAQ,IAAI,EAAE;AACd,KAAK,CAAC,CAAC;AACP;AACA;AACA;AACA,MAAM,gBAAgB,GAAG,CAAC,iBAAiB,EAAE,eAAe,CAAC;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,mBAAmB,CAAC;AAC1B,IAAI,WAAW,CAAC,KAAK,EAAE;AACvB,QAAQ,IAAI,CAAC,KAAK,GAAG,KAAK;AAC1B;AACA,QAAQ,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE;AACjC,QAAQ,IAAI,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;AACpD,YAAY,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM;AACzC;AACA,gBAAgB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;AACvD,gBAAgB,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAC/D,aAAa,CAAC;AACd;AACA,QAAQ,OAAO,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE;AAC/B,QAAQ,IAAI,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;AACpD,YAAY,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM;AACzC;AACA,gBAAgB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;AACvD,gBAAgB,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAC/D,aAAa,CAAC;AACd;AACA,QAAQ,OAAO,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE;AAC/B,QAAQ,IAAI,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AAC9C;AACA,YAAY,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE;AAC/D,gBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5E;AACA,YAAY,OAAO,OAAO,CAAC,OAAO,EAAE;AACpC;AACA,QAAQ,OAAO,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC;AAC/C;AACA;AACA,IAAI,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE;AACtC,QAAQ,IAAI,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AAC9C,YAAY,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE;AAC5C;AACA,gBAAgB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC;AACjD;AACA,iBAAiB;AACjB;AACA,gBAAgB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;AACnD;AACA,YAAY,OAAO,IAAI;AACvB;AACA,QAAQ,OAAO,KAAK;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,aAAa,SAAS,mBAAmB,CAAC;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,WAAW,GAAG;AACxB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,aAAa,GAAG;AAC1B,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,aAAa,GAAG;AAC1B,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,SAAS,GAAG;AACtB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,SAAS,GAAG;AACtB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,YAAY,GAAG;AACzB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,WAAW,GAAG;AACxB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,WAAW,GAAG;AACxB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,SAAS,GAAG;AACtB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,WAAW,GAAG;AACxB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,WAAW,GAAG;AACxB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,aAAa,GAAG;AAC1B,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,aAAa,GAAG;AAC1B,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,UAAU,GAAG;AACvB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,SAAS,GAAG;AACtB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,KAAK,GAAG;AAClB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,KAAK,GAAG;AAClB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,MAAM,GAAG;AACnB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,oBAAoB,CAAC,WAAW,EAAE;AAC5C,QAAQ,IAAI,YAAY,GAAG,IAAI;AAC/B,QAAQ,IAAI,WAAW,EAAE;AACzB,YAAY,IAAI,WAAW,KAAK,iBAAiB,CAAC,QAAQ,EAAE;AAC5D,gBAAgB,YAAY,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE;AACnD;AACA,iBAAiB;AACjB,gBAAgB,YAAY,GAAG,EAAE,IAAI,EAAE,eAAe,EAAE;AACxD;AACA;AACA,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,sBAAsB;AACpD,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,YAAY,CAAC,SAAS,EAAE;AAClC,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,cAAc;AAC5C,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,cAAc,CAAC,WAAW,EAAE;AACtC,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,gBAAgB;AAC9C,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,cAAc,CAAC,WAAW,EAAE;AACtC,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,gBAAgB;AAC9C,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,WAAW,CAAC,QAAQ,EAAE;AAChC,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,aAAa;AAC3C,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,QAAQ,CAAC,KAAK,EAAE;AAC1B,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,UAAU;AACxC,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,QAAQ,GAAG;AACrB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,UAAU,GAAG;AACvB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,cAAc,GAAG;AAC3B,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,QAAQ,GAAG;AACrB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,UAAU,GAAG;AACvB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,IAAI,GAAG;AACjB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,IAAI,GAAG;AACjB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,KAAK,GAAG;AAClB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,cAAc,CAAC,WAAW,EAAE;AACtC,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,gBAAgB;AAC9C,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,cAAc,CAAC,WAAW,EAAE;AACtC,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,gBAAgB;AAC9C,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,mBAAmB,CAAC,UAAU,EAAE;AAC1C,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,qBAAqB;AACnD,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,OAAO,CAAC,IAAI,EAAE;AACxB,QAAQ,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,EAAE;AAC5E,YAAY,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC;AAC1G;AACA,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,SAAS;AACvC,wBAAwB,OAAO,EAAE;AACjC,4BAA4B,IAAI,EAAE,IAAI,CAAC,IAAI;AAC3C,4BAA4B,IAAI,EAAE;AAClC,gCAAgC,KAAK,EAAE,IAAI,CAAC,KAAK;AACjD,gCAAgC,MAAM,EAAE,IAAI,CAAC;AAC7C;AACA;AACA;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,UAAU,CAAC,IAAI,EAAE;AAC3B,QAAQ,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE;AACzE,YAAY,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC;AAC1G;AACA,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,YAAY;AAC1C,wBAAwB,OAAO,EAAE;AACjC,8BAA8B;AAC9B,gCAAgC,IAAI,EAAE,IAAI,CAAC,IAAI;AAC/C,gCAAgC,IAAI,EAAE;AACtC,oCAAoC,KAAK,EAAE,IAAI,CAAC,KAAK;AACrD,oCAAoC,MAAM,EAAE,IAAI,CAAC;AACjD;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,UAAU,CAAC,IAAI,EAAE;AAC3B,QAAQ,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE;AACzE,YAAY,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC;AAC1G;AACA,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,YAAY;AAC1C,wBAAwB,OAAO,EAAE;AACjC,8BAA8B;AAC9B,gCAAgC,IAAI,EAAE,IAAI,CAAC,IAAI;AAC/C,gCAAgC,IAAI,EAAE;AACtC,oCAAoC,KAAK,EAAE,IAAI,CAAC,KAAK;AACrD,oCAAoC,MAAM,EAAE,IAAI,CAAC;AACjD;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,WAAW,CAAC,QAAQ,EAAE;AAChC,QAAQ,IAAI,CAAC,QAAQ;AACrB,aAAa,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU,CAAC,EAAE;AAC3E,YAAY,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC;AACtH;AACA,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,aAAa;AAC3C,wBAAwB,OAAO,EAAE;AACjC,4BAA4B,IAAI,EAAE,QAAQ,CAAC,IAAI;AAC/C,4BAA4B,IAAI,EAAE;AAClC,gCAAgC,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC7C,gCAAgC,CAAC,EAAE,QAAQ,CAAC;AAC5C;AACA;AACA;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,aAAa,CAAC,UAAU,EAAE;AACpC,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,eAAe;AAC7C,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,QAAQ,GAAG;AACrB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,OAAO,CAAC,IAAI,EAAE;AACxB,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,SAAS;AACvC,wBAAwB,OAAO,EAAE;AACjC;AACA,4BAA4B,IAAI,EAAE,OAAO,IAAI,KAAK,QAAQ,GAAG,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI;AACnF;AACA;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,cAAc,CAAC,IAAI,EAAE;AAC/B,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,gBAAgB;AAC9C,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,aAAa,CAAC,IAAI,EAAE;AAC9B,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,eAAe;AAC7C,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,gBAAgB,CAAC,OAAO,EAAE;AACpC,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,kBAAkB;AAChD,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,aAAa,CAAC,IAAI,EAAE;AAC9B,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,eAAe;AAC7C,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,iBAAiB,CAAC,QAAQ,EAAE;AACtC,QAAQ,IAAI,CAAC,QAAQ;AACrB,aAAa,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU,CAAC,EAAE;AAC3E,YAAY,MAAM,IAAI,KAAK,CAAC,yFAAyF,CAAC;AACtH;AACA,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,mBAAmB;AACjD,wBAAwB,OAAO,EAAE;AACjC,4BAA4B,IAAI,EAAE,QAAQ,CAAC,IAAI;AAC/C,4BAA4B,IAAI,EAAE;AAClC,gCAAgC,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC7C,gCAAgC,CAAC,EAAE,QAAQ,CAAC;AAC5C;AACA;AACA;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,qBAAqB,CAAC,MAAM,EAAE;AACxC,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE,uBAAuB;AACrD,wBAAwB,OAAO,EAAE;AACjC;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,aAAa,GAAG;AAC1B,QAAQ,OAAO,kBAAkB,CAAC;AAClC,YAAY,aAAa,EAAE,QAAQ;AACnC,YAAY,OAAO,EAAE;AACrB,gBAAgB,GAAG,EAAE,QAAQ;AAC7B,gBAAgB,IAAI,EAAE;AACtB,oBAAoB,KAAK,EAAE,IAAI,CAAC,KAAK;AACrC,oBAAoB,GAAG,EAAE;AACzB,wBAAwB,IAAI,EAAE;AAC9B;AACA;AACA;AACA,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,SAAS,CAAC,OAAO,EAAE;AAC7B,QAAQ,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC,KAAK;AAC7D,YAAY,CAAC,CAAC,OAAO,GAAG,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC;AAClD,YAAY,OAAO,CAAC,CAAC,CAAC;AACtB,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,OAAO,CAAC,OAAO,EAAE;AAC3B,QAAQ,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC,KAAK;AAC3D,YAAY,CAAC,CAAC,OAAO,GAAG,mBAAmB,CAAC,CAAC,CAAC,OAAO,CAAC;AACtD,YAAY,OAAO,CAAC,CAAC,CAAC;AACtB,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,gBAAgB,CAAC,OAAO,EAAE;AACpC,QAAQ,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,sBAAsB,EAAE,CAAC,KAAK,KAAK;AACzE,YAAY,MAAM,GAAG,GAAG,IAAI,mBAAmB,CAAC,KAAK,CAAC;AACtD,YAAY,KAAK,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM;AAC1D,gBAAgB,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,EAAE;AAC7C,oBAAoB,OAAO,IAAI,CAAC,KAAK,EAAE;AACvC;AACA,aAAa,CAAC;AACd,SAAS,CAAC;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,cAAc,CAAC,OAAO,EAAE;AAClC,QAAQ,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,KAAK,KAAK;AACpF,YAAY,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAChD,SAAS,CAAC;AACV,QAAQ,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,KAAK,KAAK;AAClF,YAAY,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AACjD,SAAS,CAAC;AACV,QAAQ,OAAO,MAAM;AACrB,YAAY,aAAa,EAAE;AAC3B,YAAY,YAAY,EAAE;AAC1B,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,cAAc,CAAC,OAAO,EAAE;AAClC,QAAQ,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,2BAA2B,EAAE,OAAO,CAAC;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,aAAa,CAAC,OAAO,EAAE;AACjC,QAAQ,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,eAAe,CAAC,OAAO,EAAE;AACnC,QAAQ,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,KAAK,KAAK;AAC3F,YAAY,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;AAClF,SAAS,CAAC;AACV,QAAQ,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,sBAAsB,EAAE,CAAC,KAAK,KAAK;AAClG,YAAY,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;AACnF,SAAS,CAAC;AACV,QAAQ,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,0BAA0B,EAAE,CAAC,KAAK,KAAK;AACnG,YAAY,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC;AAC9D,SAAS,CAAC;AACV,QAAQ,OAAO,MAAM;AACrB,YAAY,gBAAgB,EAAE;AAC9B,YAAY,iBAAiB,EAAE;AAC/B,YAAY,cAAc,EAAE;AAC5B,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,cAAc,CAAC,OAAO,EAAE;AAClC,QAAQ,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,oBAAoB,EAAE,OAAO,CAAC;AACpE;AACA;AACA;AACA;AACA;AACA,MAAM,mBAAmB,CAAC;AAC1B,IAAI,WAAW,CAAC,KAAK,EAAE;AACvB,QAAQ,IAAI,CAAC,eAAe,GAAG,KAAK;AACpC,QAAQ,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK;AAChC,QAAQ,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW;AAC5C,QAAQ,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE;AAC1B;AACA,IAAI,cAAc,GAAG;AACrB,QAAQ,IAAI,CAAC,eAAe,GAAG,IAAI;AACnC;AACA,IAAI,gBAAgB,GAAG;AACvB,QAAQ,OAAO,IAAI,CAAC,eAAe;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,aAAa,SAAS,aAAa,CAAC;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,EAAE,EAAE;AACrC,QAAQ,KAAK,CAAC,KAAK,CAAC;AACpB;AACA,QAAQ,IAAI,EAAE,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE;AAC/E,YAAY,kBAAkB,CAAC;AAC/B,gBAAgB,aAAa,EAAE,QAAQ;AACvC,gBAAgB,OAAO,EAAE;AACzB,oBAAoB,GAAG,EAAE,eAAe;AACxC,oBAAoB,IAAI,EAAE;AAC1B,wBAAwB,OAAO,EAAE;AACjC,4BAA4B,KAAK;AACjC,4BAA4B,GAAG;AAC/B;AACA;AACA;AACA,aAAa;AACb,iBAAiB,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC;AAC9D,iBAAiB,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,OAAO,UAAU,CAAC,KAAK,EAAE;AAC7B,QAAQ,IAAI,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE;AACrD;AACA,YAAY,OAAO,IAAI,aAAa,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC3D;AACA,QAAQ,OAAO,IAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,aAAa,gBAAgB,GAAG;AACpC,QAAQ,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,EAAE;AAClC,YAAY,IAAI,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE;AACrC,gBAAgB,OAAO,CAAC;AACxB;AACA;AACA,QAAQ,OAAO,IAAI;AACnB;AACA;AAGA,IAAI,oBAAoB,IAAI,MAAM,EAAE;AACpC,IAAgB,IAAI,aAAa,CAAC,MAAM,CAAC,kBAAkB,CAAC,eAAe,CAAC,KAAK,EAAE;AACnF;AACA,QAAQ,IAAI,EAAE;AACd,KAAK,CAAC;AACN;AACA,KAAK;AACL,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,0MAA0M,CAAC,CAAC;AAC9N,IAAgB,IAAI,aAAa,CAAC,MAAM,EAAE;AAC1C;AACA,QAAQ,IAAI,EAAE;AACd,KAAK,CAAC;AACN;AAWA,SAAS,mBAAmB,CAAC,CAAC,EAAE;AAChC,IAAI,OAAO,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACzC;AACA,SAAS,eAAe,CAAC,CAAC,EAAE;AAC5B,IAAI,OAAO,IAAI,YAAY,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;AAC9C;;IChiEY;AAAZ,CAAA,UAAY,UAAU,EAAA;AACpB,IAAA,UAAA,CAAA,UAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAa;AACb,IAAA,UAAA,CAAA,UAAA,CAAA,UAAA,CAAA,GAAA,CAAA,CAAA,GAAA,UAAiB;AACjB,IAAA,UAAA,CAAA,UAAA,CAAA,WAAA,CAAA,GAAA,CAAA,CAAA,GAAA,WAAkB;AAClB,IAAA,UAAA,CAAA,UAAA,CAAA,SAAA,CAAA,GAAA,CAAA,CAAA,GAAA,SAAgB;AAChB,IAAA,UAAA,CAAA,UAAA,CAAA,aAAA,CAAA,GAAA,EAAA,CAAA,GAAA,aAAoB;AACpB,IAAA,UAAA,CAAA,UAAA,CAAA,YAAA,CAAA,GAAA,EAAA,CAAA,GAAA,YAAmB;AACnB,IAAA,UAAA,CAAA,UAAA,CAAA,KAAA,CAAA,GAAA,EAAA,CAAA,GAAA,KAAsE;AACxE,CAAC,EARW,UAAU,KAAV,UAAU,GAQrB,EAAA,CAAA,CAAA;AAED;;AAEG;AACH,eAAe,eAAe,CAAC,KAAiB,EAAA;IAC9C,OAAO,MAAM,CAAC,uCAAuC,EAAE,EAAE,KAAK,EAAE,CAAC;AACnE;AAEA;;AAEG;AACH,eAAe,YAAY,CACzB,KAAkB,EAClB,KAAiB,EAAA;IAEjB,OAAO,MAAM,CAAC,mCAAmC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACtE;AAEA;;AAEG;AACH,eAAe,mBAAmB,CAAC,KAAiB,EAAA;IAClD,OAAO,YAAY,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;AAChD;;;;","x_google_ignoreList":[0,1,2,3,4]} -------------------------------------------------------------------------------- /dist-js/index.mjs: -------------------------------------------------------------------------------- 1 | import { invoke } from '@tauri-apps/api/tauri'; 2 | import { getCurrent } from '@tauri-apps/api/window'; 3 | 4 | var StateFlags; 5 | (function (StateFlags) { 6 | StateFlags[StateFlags["SIZE"] = 1] = "SIZE"; 7 | StateFlags[StateFlags["POSITION"] = 2] = "POSITION"; 8 | StateFlags[StateFlags["MAXIMIZED"] = 4] = "MAXIMIZED"; 9 | StateFlags[StateFlags["VISIBLE"] = 8] = "VISIBLE"; 10 | StateFlags[StateFlags["DECORATIONS"] = 16] = "DECORATIONS"; 11 | StateFlags[StateFlags["FULLSCREEN"] = 32] = "FULLSCREEN"; 12 | StateFlags[StateFlags["ALL"] = 63] = "ALL"; 13 | })(StateFlags || (StateFlags = {})); 14 | /** 15 | * Save the state of all open windows to disk. 16 | */ 17 | async function saveWindowState(flags) { 18 | return invoke("plugin:window-state|save_window_state", { flags }); 19 | } 20 | /** 21 | * Restore the state for the specified window from disk. 22 | */ 23 | async function restoreState(label, flags) { 24 | return invoke("plugin:window-state|restore_state", { label, flags }); 25 | } 26 | /** 27 | * Restore the state for the current window from disk. 28 | */ 29 | async function restoreStateCurrent(flags) { 30 | return restoreState(getCurrent().label, flags); 31 | } 32 | 33 | export { StateFlags, restoreState, restoreStateCurrent, saveWindowState }; 34 | //# sourceMappingURL=index.mjs.map 35 | -------------------------------------------------------------------------------- /dist-js/index.mjs.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.mjs","sources":["../guest-js/index.ts"],"sourcesContent":[null],"names":[],"mappings":";;;IAGY;AAAZ,CAAA,UAAY,UAAU,EAAA;AACpB,IAAA,UAAA,CAAA,UAAA,CAAA,MAAA,CAAA,GAAA,CAAA,CAAA,GAAA,MAAa;AACb,IAAA,UAAA,CAAA,UAAA,CAAA,UAAA,CAAA,GAAA,CAAA,CAAA,GAAA,UAAiB;AACjB,IAAA,UAAA,CAAA,UAAA,CAAA,WAAA,CAAA,GAAA,CAAA,CAAA,GAAA,WAAkB;AAClB,IAAA,UAAA,CAAA,UAAA,CAAA,SAAA,CAAA,GAAA,CAAA,CAAA,GAAA,SAAgB;AAChB,IAAA,UAAA,CAAA,UAAA,CAAA,aAAA,CAAA,GAAA,EAAA,CAAA,GAAA,aAAoB;AACpB,IAAA,UAAA,CAAA,UAAA,CAAA,YAAA,CAAA,GAAA,EAAA,CAAA,GAAA,YAAmB;AACnB,IAAA,UAAA,CAAA,UAAA,CAAA,KAAA,CAAA,GAAA,EAAA,CAAA,GAAA,KAAsE;AACxE,CAAC,EARW,UAAU,KAAV,UAAU,GAQrB,EAAA,CAAA,CAAA;AAED;;AAEG;AACH,eAAe,eAAe,CAAC,KAAiB,EAAA;IAC9C,OAAO,MAAM,CAAC,uCAAuC,EAAE,EAAE,KAAK,EAAE,CAAC;AACnE;AAEA;;AAEG;AACH,eAAe,YAAY,CACzB,KAAkB,EAClB,KAAiB,EAAA;IAEjB,OAAO,MAAM,CAAC,mCAAmC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACtE;AAEA;;AAEG;AACH,eAAe,mBAAmB,CAAC,KAAiB,EAAA;IAClD,OAAO,YAAY,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;AAChD;;;;"} -------------------------------------------------------------------------------- /guest-js/index.ts: -------------------------------------------------------------------------------- 1 | import { invoke } from "@tauri-apps/api/tauri"; 2 | import { WindowLabel, getCurrent } from "@tauri-apps/api/window"; 3 | 4 | export enum StateFlags { 5 | SIZE = 1 << 0, 6 | POSITION = 1 << 1, 7 | MAXIMIZED = 1 << 2, 8 | VISIBLE = 1 << 3, 9 | DECORATIONS = 1 << 4, 10 | FULLSCREEN = 1 << 5, 11 | ALL = SIZE | POSITION | MAXIMIZED | VISIBLE | DECORATIONS | FULLSCREEN, 12 | } 13 | 14 | /** 15 | * Save the state of all open windows to disk. 16 | */ 17 | async function saveWindowState(flags: StateFlags): Promise { 18 | return invoke("plugin:window-state|save_window_state", { flags }); 19 | } 20 | 21 | /** 22 | * Restore the state for the specified window from disk. 23 | */ 24 | async function restoreState( 25 | label: WindowLabel, 26 | flags: StateFlags, 27 | ): Promise { 28 | return invoke("plugin:window-state|restore_state", { label, flags }); 29 | } 30 | 31 | /** 32 | * Restore the state for the current window from disk. 33 | */ 34 | async function restoreStateCurrent(flags: StateFlags): Promise { 35 | return restoreState(getCurrent().label, flags); 36 | } 37 | 38 | export { restoreState, restoreStateCurrent, saveWindowState }; 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tauri-plugin-window-state-api", 3 | "version": "0.0.0", 4 | "description": "Save window positions and sizes and restore them when the app is reopened.", 5 | "license": "MIT or APACHE-2.0", 6 | "authors": [ 7 | "Tauri Programme within The Commons Conservancy" 8 | ], 9 | "type": "module", 10 | "browser": "dist-js/index.min.js", 11 | "module": "dist-js/index.mjs", 12 | "types": "dist-js/index.d.ts", 13 | "exports": { 14 | "import": "./dist-js/index.mjs", 15 | "types": "./dist-js/index.d.ts", 16 | "browser": "./dist-js/index.min.js" 17 | }, 18 | "scripts": { 19 | "build": "rollup -c" 20 | }, 21 | "files": [ 22 | "dist-js", 23 | "!dist-js/**/*.map", 24 | "README.md", 25 | "LICENSE" 26 | ], 27 | "devDependencies": { 28 | "tslib": "2.8.1" 29 | }, 30 | "dependencies": { 31 | "@tauri-apps/api": "1.6.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /rollup.config.mjs: -------------------------------------------------------------------------------- 1 | import { readFileSync } from "fs"; 2 | 3 | import { createConfig } from "../../shared/rollup.config.mjs"; 4 | 5 | export default createConfig({ 6 | input: "guest-js/index.ts", 7 | pkg: JSON.parse( 8 | readFileSync(new URL("./package.json", import.meta.url), "utf8"), 9 | ), 10 | external: [/^@tauri-apps\/api/], 11 | }); 12 | -------------------------------------------------------------------------------- /src/cmd.rs: -------------------------------------------------------------------------------- 1 | use crate::{AppHandleExt, StateFlags, WindowExt}; 2 | use tauri::{command, AppHandle, Manager, Runtime}; 3 | 4 | #[command] 5 | pub async fn save_window_state( 6 | app: AppHandle, 7 | flags: u32, 8 | ) -> std::result::Result<(), String> { 9 | let flags = StateFlags::from_bits(flags) 10 | .ok_or_else(|| format!("Invalid state flags bits: {}", flags))?; 11 | app.save_window_state(flags).map_err(|e| e.to_string())?; 12 | Ok(()) 13 | } 14 | 15 | #[command] 16 | pub async fn restore_state( 17 | app: AppHandle, 18 | label: String, 19 | flags: u32, 20 | ) -> std::result::Result<(), String> { 21 | let flags = StateFlags::from_bits(flags) 22 | .ok_or_else(|| format!("Invalid state flags bits: {}", flags))?; 23 | app.get_window(&label) 24 | .ok_or_else(|| format!("Couldn't find window with label: {}", label))? 25 | .restore_state(flags) 26 | .map_err(|e| e.to_string())?; 27 | Ok(()) 28 | } 29 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Tauri Programme within The Commons Conservancy 2 | // SPDX-License-Identifier: Apache-2.0 3 | // SPDX-License-Identifier: MIT 4 | 5 | use bitflags::bitflags; 6 | use serde::{Deserialize, Serialize}; 7 | use tauri::{ 8 | plugin::{Builder as PluginBuilder, TauriPlugin}, 9 | LogicalSize, Manager, Monitor, PhysicalPosition, PhysicalSize, RunEvent, Runtime, Window, 10 | WindowEvent, 11 | }; 12 | 13 | use std::{ 14 | collections::{HashMap, HashSet}, 15 | fs::{create_dir_all, File}, 16 | io::Write, 17 | sync::{Arc, Mutex}, 18 | }; 19 | 20 | mod cmd; 21 | 22 | pub const STATE_FILENAME: &str = ".window-state"; 23 | 24 | #[derive(Debug, thiserror::Error)] 25 | pub enum Error { 26 | #[error(transparent)] 27 | Io(#[from] std::io::Error), 28 | #[error(transparent)] 29 | Tauri(#[from] tauri::Error), 30 | #[error(transparent)] 31 | TauriApi(#[from] tauri::api::Error), 32 | #[error(transparent)] 33 | Bincode(#[from] Box), 34 | } 35 | 36 | pub type Result = std::result::Result; 37 | 38 | bitflags! { 39 | #[derive(Clone, Copy, Debug)] 40 | pub struct StateFlags: u32 { 41 | const SIZE = 1 << 0; 42 | const POSITION = 1 << 1; 43 | const MAXIMIZED = 1 << 2; 44 | const VISIBLE = 1 << 3; 45 | const DECORATIONS = 1 << 4; 46 | const FULLSCREEN = 1 << 5; 47 | } 48 | } 49 | 50 | impl Default for StateFlags { 51 | fn default() -> Self { 52 | Self::all() 53 | } 54 | } 55 | 56 | #[derive(Debug, Deserialize, Serialize, PartialEq)] 57 | struct WindowState { 58 | width: f64, 59 | height: f64, 60 | x: i32, 61 | y: i32, 62 | // prev_x and prev_y are used to store position 63 | // before maximization happened, because maximization 64 | // will set x and y to the top-left corner of the monitor 65 | prev_x: i32, 66 | prev_y: i32, 67 | maximized: bool, 68 | visible: bool, 69 | decorated: bool, 70 | fullscreen: bool, 71 | } 72 | 73 | impl Default for WindowState { 74 | fn default() -> Self { 75 | Self { 76 | width: Default::default(), 77 | height: Default::default(), 78 | x: Default::default(), 79 | y: Default::default(), 80 | prev_x: Default::default(), 81 | prev_y: Default::default(), 82 | maximized: Default::default(), 83 | visible: true, 84 | decorated: true, 85 | fullscreen: Default::default(), 86 | } 87 | } 88 | } 89 | 90 | struct WindowStateCache(Arc>>); 91 | pub trait AppHandleExt { 92 | /// Saves all open windows state to disk 93 | fn save_window_state(&self, flags: StateFlags) -> Result<()>; 94 | } 95 | 96 | impl AppHandleExt for tauri::AppHandle { 97 | fn save_window_state(&self, flags: StateFlags) -> Result<()> { 98 | if let Some(app_dir) = self.path_resolver().app_config_dir() { 99 | let state_path = app_dir.join(STATE_FILENAME); 100 | let cache = self.state::(); 101 | let mut state = cache.0.lock().unwrap(); 102 | for (label, s) in state.iter_mut() { 103 | if let Some(window) = self.get_window(label) { 104 | window.update_state(s, flags)?; 105 | } 106 | } 107 | 108 | create_dir_all(&app_dir) 109 | .map_err(Error::Io) 110 | .and_then(|_| File::create(state_path).map_err(Into::into)) 111 | .and_then(|mut f| { 112 | f.write_all(&bincode::serialize(&*state).map_err(Error::Bincode)?) 113 | .map_err(Into::into) 114 | }) 115 | } else { 116 | Ok(()) 117 | } 118 | } 119 | } 120 | 121 | pub trait WindowExt { 122 | /// Restores this window state from disk 123 | fn restore_state(&self, flags: StateFlags) -> tauri::Result<()>; 124 | } 125 | 126 | impl WindowExt for Window { 127 | fn restore_state(&self, flags: StateFlags) -> tauri::Result<()> { 128 | let cache = self.state::(); 129 | let mut c = cache.0.lock().unwrap(); 130 | 131 | let mut should_show = true; 132 | 133 | if let Some(state) = c.get(self.label()) { 134 | // avoid restoring the default zeroed state 135 | if *state == WindowState::default() { 136 | return Ok(()); 137 | } 138 | 139 | if flags.contains(StateFlags::DECORATIONS) { 140 | self.set_decorations(state.decorated)?; 141 | } 142 | 143 | if flags.contains(StateFlags::SIZE) { 144 | self.set_size(LogicalSize { 145 | width: state.width, 146 | height: state.height, 147 | })?; 148 | } 149 | 150 | if flags.contains(StateFlags::POSITION) { 151 | let position = (state.x, state.y).into(); 152 | let size = (state.width, state.height).into(); 153 | // restore position to saved value if saved monitor exists 154 | // otherwise, let the OS decide where to place the window 155 | for m in self.available_monitors()? { 156 | if m.intersects(position, size) { 157 | self.set_position(PhysicalPosition { 158 | x: if state.maximized { 159 | state.prev_x 160 | } else { 161 | state.x 162 | }, 163 | y: if state.maximized { 164 | state.prev_y 165 | } else { 166 | state.y 167 | }, 168 | })?; 169 | } 170 | } 171 | } 172 | 173 | if flags.contains(StateFlags::MAXIMIZED) && state.maximized { 174 | self.maximize()?; 175 | } 176 | 177 | if flags.contains(StateFlags::FULLSCREEN) { 178 | self.set_fullscreen(state.fullscreen)?; 179 | } 180 | 181 | should_show = state.visible; 182 | } else { 183 | let mut metadata = WindowState::default(); 184 | 185 | if flags.contains(StateFlags::SIZE) { 186 | let scale_factor = self 187 | .current_monitor()? 188 | .map(|m| m.scale_factor()) 189 | .unwrap_or(1.); 190 | let size = self.inner_size()?.to_logical(scale_factor); 191 | metadata.width = size.width; 192 | metadata.height = size.height; 193 | } 194 | 195 | if flags.contains(StateFlags::POSITION) { 196 | let pos = self.outer_position()?; 197 | metadata.x = pos.x; 198 | metadata.y = pos.y; 199 | } 200 | 201 | if flags.contains(StateFlags::MAXIMIZED) { 202 | metadata.maximized = self.is_maximized()?; 203 | } 204 | 205 | if flags.contains(StateFlags::VISIBLE) { 206 | metadata.visible = self.is_visible()?; 207 | } 208 | 209 | if flags.contains(StateFlags::DECORATIONS) { 210 | metadata.decorated = self.is_decorated()?; 211 | } 212 | 213 | if flags.contains(StateFlags::FULLSCREEN) { 214 | metadata.fullscreen = self.is_fullscreen()?; 215 | } 216 | 217 | c.insert(self.label().into(), metadata); 218 | } 219 | 220 | if flags.contains(StateFlags::VISIBLE) && should_show { 221 | self.show()?; 222 | self.set_focus()?; 223 | } 224 | 225 | Ok(()) 226 | } 227 | } 228 | 229 | trait WindowExtInternal { 230 | fn update_state(&self, state: &mut WindowState, flags: StateFlags) -> tauri::Result<()>; 231 | } 232 | 233 | impl WindowExtInternal for Window { 234 | fn update_state(&self, state: &mut WindowState, flags: StateFlags) -> tauri::Result<()> { 235 | let is_maximized = match flags.intersects(StateFlags::MAXIMIZED | StateFlags::SIZE) { 236 | true => self.is_maximized()?, 237 | false => false, 238 | }; 239 | 240 | if flags.contains(StateFlags::MAXIMIZED) { 241 | state.maximized = is_maximized; 242 | } 243 | 244 | if flags.contains(StateFlags::FULLSCREEN) { 245 | state.fullscreen = self.is_fullscreen()?; 246 | } 247 | 248 | if flags.contains(StateFlags::DECORATIONS) { 249 | state.decorated = self.is_decorated()?; 250 | } 251 | 252 | if flags.contains(StateFlags::VISIBLE) { 253 | state.visible = self.is_visible()?; 254 | } 255 | 256 | if flags.contains(StateFlags::SIZE) { 257 | let scale_factor = self 258 | .current_monitor()? 259 | .map(|m| m.scale_factor()) 260 | .unwrap_or(1.); 261 | let size = self.inner_size()?.to_logical(scale_factor); 262 | 263 | // It doesn't make sense to save a window with 0 height or width 264 | if size.width > 0. && size.height > 0. && !is_maximized { 265 | state.width = size.width; 266 | state.height = size.height; 267 | } 268 | } 269 | 270 | if flags.contains(StateFlags::POSITION) && !is_maximized { 271 | let position = self.outer_position()?; 272 | state.x = position.x; 273 | state.y = position.y; 274 | } 275 | 276 | Ok(()) 277 | } 278 | } 279 | 280 | #[derive(Default)] 281 | pub struct Builder { 282 | denylist: HashSet, 283 | skip_initial_state: HashSet, 284 | state_flags: StateFlags, 285 | } 286 | 287 | impl Builder { 288 | pub fn new() -> Self { 289 | Self::default() 290 | } 291 | 292 | /// Sets the state flags to control what state gets restored and saved. 293 | pub fn with_state_flags(mut self, flags: StateFlags) -> Self { 294 | self.state_flags = flags; 295 | self 296 | } 297 | 298 | /// Sets a list of windows that shouldn't be tracked and managed by this plugin 299 | /// for example splash screen windows. 300 | pub fn with_denylist(mut self, denylist: &[&str]) -> Self { 301 | self.denylist = denylist.iter().map(|l| l.to_string()).collect(); 302 | self 303 | } 304 | 305 | /// Adds the given window label to a list of windows to skip initial state restore. 306 | pub fn skip_initial_state(mut self, label: &str) -> Self { 307 | self.skip_initial_state.insert(label.into()); 308 | self 309 | } 310 | 311 | pub fn build(self) -> TauriPlugin { 312 | let flags = self.state_flags; 313 | PluginBuilder::new("window-state") 314 | .invoke_handler(tauri::generate_handler![ 315 | cmd::save_window_state, 316 | cmd::restore_state 317 | ]) 318 | .setup(|app| { 319 | let cache: Arc>> = if let Some(app_dir) = 320 | app.path_resolver().app_config_dir() 321 | { 322 | let state_path = app_dir.join(STATE_FILENAME); 323 | if state_path.exists() { 324 | Arc::new(Mutex::new( 325 | tauri::api::file::read_binary(state_path) 326 | .map_err(Error::TauriApi) 327 | .and_then(|state| bincode::deserialize(&state).map_err(Into::into)) 328 | .unwrap_or_default(), 329 | )) 330 | } else { 331 | Default::default() 332 | } 333 | } else { 334 | Default::default() 335 | }; 336 | app.manage(WindowStateCache(cache)); 337 | Ok(()) 338 | }) 339 | .on_webview_ready(move |window| { 340 | if self.denylist.contains(window.label()) { 341 | return; 342 | } 343 | 344 | if !self.skip_initial_state.contains(window.label()) { 345 | let _ = window.restore_state(self.state_flags); 346 | } 347 | 348 | let cache = window.state::(); 349 | let cache = cache.0.clone(); 350 | let label = window.label().to_string(); 351 | let window_clone = window.clone(); 352 | let flags = self.state_flags; 353 | 354 | // insert a default state if this window should be tracked and 355 | // the disk cache doesn't have a state for it 356 | { 357 | cache 358 | .lock() 359 | .unwrap() 360 | .entry(label.clone()) 361 | .or_insert_with(WindowState::default); 362 | } 363 | 364 | window.on_window_event(move |e| match e { 365 | WindowEvent::CloseRequested { .. } => { 366 | let mut c = cache.lock().unwrap(); 367 | if let Some(state) = c.get_mut(&label) { 368 | let _ = window_clone.update_state(state, flags); 369 | } 370 | } 371 | 372 | WindowEvent::Moved(position) if flags.contains(StateFlags::POSITION) => { 373 | let mut c = cache.lock().unwrap(); 374 | if let Some(state) = c.get_mut(&label) { 375 | state.prev_x = state.x; 376 | state.prev_y = state.y; 377 | 378 | state.x = position.x; 379 | state.y = position.y; 380 | } 381 | } 382 | _ => {} 383 | }); 384 | }) 385 | .on_event(move |app, event| { 386 | if let RunEvent::Exit = event { 387 | let _ = app.save_window_state(flags); 388 | } 389 | }) 390 | .build() 391 | } 392 | } 393 | 394 | trait MonitorExt { 395 | fn intersects(&self, position: PhysicalPosition, size: LogicalSize) -> bool; 396 | } 397 | 398 | impl MonitorExt for Monitor { 399 | fn intersects(&self, position: PhysicalPosition, size: LogicalSize) -> bool { 400 | let size = size.to_physical::(self.scale_factor()); 401 | 402 | let PhysicalPosition { x, y } = *self.position(); 403 | let PhysicalSize { width, height } = *self.size(); 404 | 405 | let left = x; 406 | let right = x + width as i32; 407 | let top = y; 408 | let bottom = y + height as i32; 409 | 410 | [ 411 | (position.x, position.y), 412 | (position.x + size.width as i32, position.y), 413 | (position.x, position.y + size.height as i32), 414 | ( 415 | position.x + size.width as i32, 416 | position.y + size.height as i32, 417 | ), 418 | ] 419 | .into_iter() 420 | .any(|(x, y)| x >= left && x < right && y >= top && y < bottom) 421 | } 422 | } 423 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["guest-js/*.ts"] 4 | } 5 | --------------------------------------------------------------------------------